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 runtime origin https://agent.karta.sh; if you set a custom data-base-url, use that origin instead.
What each is for:
  • script-src https://cdn.karta.sh - the async loader (karta.js) and the code it lazily imports are served from the CDN.
  • connect-src https://agent.karta.sh - from your page the loader fetches the embed token mint (/v1/embed/session-tokens) and runtime config (/v1/embed/config) from the runtime origin. Use your data-base-url origin here if you override it.
  • frame-src https://agent.karta.sh - the widget UI runs in a cross-origin iframe served from the runtime origin. The streaming session traffic runs inside that iframe against its own origin, so it needs nothing more from your page’s CSP.
The widget UI is isolated in a cross-origin iframe, so its styles and scripts are scoped to the iframe’s own document and never touch your page - you do not need style-src 'unsafe-inline' for the widget. It also uses no eval or new Function, so no script-src 'unsafe-eval' is needed.

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. Karta 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.

Hosted agent pages

The public /{org}/{agent} and /{org}/{agent}/embed pages are served from the agent origin. They are top-level or iframe documents, so they do not depend on JavaScript from your page. When a hosted page runs without an explicit ?key=pk_live_xxx, it gets runtime config from /v1/embed/first-party-config and mints a browser-safe session token through /v1/embed/first-party-token on the same origin. Those endpoints are for Karta-hosted pages. For your own page, use a publishable embed key with /v1/embed/session-tokens, or mint a session token from your backend.

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, agent-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 agent, 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 Karta and on to the model provider that backs the agent (your own, under BYOK, or Karta’s). See Trust & compliance for operator-access guidance.
  • Soft identity is advisory. A soft userId is metadata, never an auth credential, and any page can set it. Use verified identity to bind a trusted subject, and a signed context bag when the agent needs facts about the user it can rely on.
  • 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 an escape-first renderer, 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 agent and sent to Karta and a model provider to generate replies;
  • what you log or retain on your side. The widget keeps no chat transcript in the page; conversation continuity comes from server-side session state, so a reload can resume the session;
  • how a user can reach a human, if you wire the escalate hook.
The built-in pre-chat consent string is one place to surface this.

Session tokens

The short-lived, agent-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.