Skip to main content
This page covers the security and privacy model for the embeddable chat widget: what your page’s Content-Security-Policy needs, how access is gated, the abuse controls, and where chat data goes.

Content-Security-Policy

If your site sends a CSP, allow the widget the following. These assume the default data-plane origin https://agent.karta.sh; if you set a custom data-base-url, use that origin for connect-src instead.
script-src  https://cdn.karta.sh;
connect-src https://agent.karta.sh;
style-src   'unsafe-inline';
What each is for:
  • script-src https://cdn.karta.sh - the async loader (karta.js) and the UI/core chunk it lazily imports are both served from the CDN.
  • connect-src https://agent.karta.sh - the widget fetches the embed token mint (/v1/embed/session-tokens), runtime config (/v1/embed/config), and the streaming session API (/{org}/{project}/v1/…) from the data plane. Use your data-base-url origin here if you override it.
  • style-src 'unsafe-inline' - the widget renders inside a Shadow DOM and injects its stylesheet as an inline <style> element in the shadow root. It does not (and cannot) carry your page’s CSP nonce, so an inline style-src allowance is required for the widget’s CSS.
The widget does not use eval or new Function, so no script-src 'unsafe-eval' is needed. The Shadow DOM keeps the widget’s styles off the rest of your page regardless of the inline style-src allowance.
If you set a URL avatar (data-theme-agent-avatar pointing at an image), also allow that image host in img-src. Emoji/text avatars need nothing.

Origin allowlist

The publishable pk_live_… embed key is meant to ship in your page’s HTML - it is not a secret. Its blast radius is fenced by the allowed-origins allowlist, not by hiding the key.
  • The browser sends its real Origin header on the token mint. The data plane reads that header (never a body-supplied value, which a hostile page could spoof) and refuses the mint if the origin is not on the key’s allowlist.
  • The match is exact on scheme + host + port. There are no wildcards - list each origin you embed on.
  • Rotating or disabling the key on the Embed tab cuts off token minting immediately.

The safety model

The widget never holds a long-lived credential, and anonymous traffic is bounded:
  • Short-lived session tokens. The embed key is exchanged for a short-lived, project-scoped session token per session. The browser only ever holds that expiring token, never an API key.
  • Anonymous spend cap. Each key has a hard ceiling on what anonymous (non-verified) traffic can cost per period, set on the Embed tab. On hit, minting stops.
  • Rate limits. The token-mint edge is rate-limited per IP, as a backstop against a key being hammered from one source.

Graceful limits

When a usage, spend, or rate limit is hit, the widget does not show a raw error. It shows a calm “check back later” state, locks the composer so the user cannot keep hammering a capped assistant, and emits a first-class limit_reached event (with an optional retryAfterSeconds) so your page can respond - for example, surfacing a contact form. A hard cap has no client-side recovery within the page’s lifetime; the limit clears server-side on its period boundary.

Privacy & data path

Be accurate with your users about where their chat goes:
  • Chat content reaches Karta and the model provider. Messages the end user types are sent to the Karta data plane and on to the model provider that backs the agent (your own, under BYOK, or Karta’s). Running an agent necessarily means its operator processes the content it handles - see Trust & compliance.
  • Soft identity is advisory. A soft userId or attributes you attach are metadata, never an auth credential, and any page can set them. Do not put secrets in attributes. Use verified identity to bind a trusted subject.
  • The optional pre-chat consent string. The widget can show a pre-chat disclosure before the first message - with an optional Accept gate - to tell users the chat is AI-assisted and link your privacy policy. The disclosure text is sanitized through the same escape-first renderer as assistant output, so it is safe to author but cannot contain executable markup.

What you should disclose

As the site embedding the widget, you are the data controller for your users’ chats. Disclose, per your jurisdiction, that:
  • conversations are processed by an AI assistant and sent to Karta and a model provider to generate replies;
  • what you log or retain on your side (the widget persists a lightweight transcript in the user’s browser localStorage for reload continuity, keyed per identity, and clears it on an explicit shutdown/reset);
  • how a user can reach a human, if you wire the escalate hook.
The pre-chat consent string is the built-in place to surface this.

Session tokens

The short-lived, project-scoped credential the embed key is exchanged for.

Identity

Anonymous, soft, and verified (HMAC) end-user identity.

Trust & compliance

The platform’s broader security posture and operator access.

BYOK

Keep your model-provider credentials under your own control.