Skip to content

Privacy

Cognidesk privacy settings are session-start controls. Pass them when you create a Conversation, and the runtime stores the settings in the Conversation context so later messages, voice segments, Channel Events, replay, telemetry, snapshots, and Studio adapter reads use the same policy.

The SDK intentionally ships with no default PII mask rules. Applications decide which values are sensitive in their domain and provide explicit masks or privacy hooks.

Session privacy settings

const conversation = await runtime.createConversation({
  agentId: "support",
  channel: "chat",
  context: {
    customerId: customer.id,
  },
  privacy: {
    traceContent: "none",
    customerRelationVisibility: "id",
    masks: [
      {
        name: "email",
        pattern: "[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,}",
        flags: "gi",
        replacement: "[email]",
      },
      {
        name: "phone",
        pattern: "(^|[^A-Z0-9])(\\+?\\d[\\d ().-]{6,}\\d)(?=$|[^A-Z0-9])",
        flags: "gi",
        replacement: "$1[phone]",
      },
    ],
  },
});
Setting Values Effect
enabled true, false Turns SDK-managed masking off when set to false. Custom hooks still run.
traceContent full, redacted, none Controls content in stored events, replay, snapshots, and telemetry.
customerRelationVisibility id, none Controls whether Studio/adapter surfaces may expose a generic customer relation id.
masks app-defined rules Applies explicit regex replacements before content is stored or exported.

Trace content levels

traceContent: "full" keeps content unchanged unless masks or hooks are configured.

traceContent: "redacted" keeps the same event shape but applies your explicit masks and privacy hooks to strings.

traceContent: "none" removes message and content-heavy payloads from traces and telemetry while preserving structural workflow events. You can still see which Journey and state ran, which tool/action completed, and lifecycle events, but raw user and assistant message text is not stored in trace surfaces.

Customer relation

Cognidesk derives the generic customer relation from existing Conversation context. Use either context.customerId or context.customer.id; do not pass a second customer field just for Studio.

await runtime.createConversation({
  agentId: "support",
  context: {
    customerId: "customer_123",
  },
  privacy: {
    traceContent: "redacted",
    customerRelationVisibility: "id",
  },
});

Studio adapter surfaces expose only { id } when a customer id exists and the session privacy allows it. If traceContent is none, the relation is hidden unless customerRelationVisibility: "id" is set explicitly.

Transport and UI

HTTP clients can pass the same object to POST /api/conversations, POST /api/voice/conversations, and Channel Event createConversation payloads:

{
  "agentId": "support",
  "context": { "customerId": "customer_123" },
  "privacy": {
    "traceContent": "none",
    "customerRelationVisibility": "none",
    "masks": [
      { "name": "email", "pattern": "[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,}", "flags": "gi", "replacement": "[email]" }
    ]
  }
}

React UIs can pass privacy to ChatWidget, useChat, or useVoice when the widget or hook may create a new Conversation.

Consent is application state, not a separate redaction layer. A frontend should collect the user's choice, persist it if appropriate, and then either pass a RuntimePrivacySettings object to the session-start call or omit privacy. Core still performs all masking, event redaction, replay redaction, snapshot redaction, telemetry redaction, and privacy-hook execution.

type DemoConsent = "consent" | "no";

const consent = localStorage.getItem("myapp.privacyConsent.v1") as DemoConsent | null;

const privacy = consent === "no"
  ? {
      traceContent: "none",
      customerRelationVisibility: "none",
      masks: [
        {
          name: "email",
          pattern: "[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,}",
          flags: "gi",
          replacement: "[email]",
        },
      ],
    } as const
  : undefined;

await client.createConversation({
  agentId: "support",
  context: {},
  ...(privacy ? { privacy } : {}),
});

Use the UI to choose policy. Do not re-implement message, event, telemetry, or replay redaction in the UI. That would create duplicate behavior that can drift from the SDK runtime.

Hooks

Use RuntimeOptions.privacy for organization-wide hooks and optional baseline settings. Hooks are useful for non-regex decisions, provider-specific payloads, or application policies that need customer or tenant context.

const runtime = createRuntime({
  storage,
  agent,
  models,
  privacy: {
    async redactConversationContext({ context }) {
      return keepSupportSafeCustomerFields(context);
    },
    async redactTelemetryAttributes({ attributes }) {
      return scrubTelemetry(attributes);
    },
  },
});

Keep deterministic masks for syntax-shaped values such as IDs, email addresses, phone numbers, account numbers, or booking references. Use hooks when the decision depends on meaning, policy, tenant configuration, or external customer metadata.