Security model
One principle everywhere: the dashboard grants, the chat endpoint enforces, and the client can only narrow a grant, never widen it. Nothing the browser sends is trusted for policy.
The boundary
- Agent instructions live only in the dashboard. The endpoint rejects a browser-sent system prompt outright.
- Attachments are agent policy: the endpoint refuses files when the agent disallows them, and the widget hides the attach button after its capability handshake.
- The client's
attachmentsoption and limits can narrow the grant for UX. The endpoint enforces its own caps regardless. - Tool and widget
execute/renderrun in your page with agent-chosen input: validate with a Standard Schema, or treat the input as untrusted.
Tokens
- Your server mints short-lived chat auth tokens (60–600 s) from the API key. The browser never sees the key.
- Tokens stay in memory and use the
Authorizationheader, without cookies. Send them only to the deployment that issued the API key. - Self-hosted deployments must set
apiUrlexplicitly. The default points at the hosted cloud.
Sandbox artifacts
- Signed tickets authorize artifact downloads and bind them to the published bytes. No separate Bearer header is required.
- The serving route re-reads, re-sniffs (magic bytes, never extensions), re-caps, and re-hashes the bytes at download time. Any change since publishing is refused.
- Only sniffed raster images render inline. SVG can only ever be served as
text/plain, and every response carriesnosniffplus a frame-and-script-free CSP. - Tickets expire in minutes alongside the sandbox's idle expiry. An expired download says to ask the agent again.
What the SDK does not protect against
- Chat Markdown escapes raw HTML. Host widgets remain your responsibility, including how they handle agent-chosen props.
- The sandbox is isolated per conversation but holds no secrets by design. Never instruct an agent to write credentials into it.