Docs / SDK / Build / Content security policy
View as MarkdownContent security policy
The Content-Security-Policy directives a page needs to run an embedded Mindset agent, with a ready policy to copy.
After this page your site's content security policy (CSP) lets the Mindset agent load and run, and still blocks everything else you mean it to block.
If your site sends no Content-Security-Policy header or meta tag, you can skip this page.
What the agent needs
Everything the SDK fetches comes from one place: your Mindset host, the address on the agent's Embed tab. The examples use https://eu.mindset.ai. Replace it with yours.
| Directive | Allow | Why |
|---|---|---|
script-src | Your Mindset host | The page loads /sdk/mindset-agent.js (or imports /sdk/mindset-agent-uiless.js) from it. The element also loads /sdk/mindset-agent-charts.js from the same host the first time it draws a chart |
connect-src | Your Mindset host | Every turn, tool call and session renewal is a fetch to it. Replies stream over that fetch, so there is no WebSocket and no wss: to allow |
font-src | Your Mindset host | The element loads the Inter typeface from /fonts/ on the host. Blocked, it falls back to the system font |
img-src | The hosts your agent's images come from | An agent can show images from anywhere its content points (markdown images in replies, image widgets). Allow the hosts your agents use, or https: |
style-src | Nothing, in current browsers | See styles below |
Your own backend, where getSession fetches the session, needs to be in connect-src too. 'self' covers it when it's on the same origin as the page.
The SDK uses no eval and no new Function, so you don't need 'unsafe-eval'.
A ready policy
Content-Security-Policy:
script-src 'self' https://eu.mindset.ai;
connect-src 'self' https://eu.mindset.ai;
font-src https://eu.mindset.ai;
img-src 'self' data: https:;Send it as one header line. The line breaks are for reading. Narrow img-src to the image hosts your agents use. Keep any other directives your site already has, such as default-src, alongside these.
A nonce-based policy
If your policy allows scripts by nonce instead of by host, put the nonce on the Mindset script tag:
<script nonce="RANDOM-PER-RESPONSE" src="https://eu.mindset.ai/sdk/mindset-agent.js"></script>Content-Security-Policy:
script-src 'nonce-RANDOM-PER-RESPONSE' 'strict-dynamic';
connect-src 'self' https://eu.mindset.ai;
font-src https://eu.mindset.ai;
img-src 'self' data: https:;The element copies that nonce onto the chart script it adds later, so charts load too.
The nonce is picked up only when the bundle loads from a classic <script src=".../mindset-agent.js"> tag, including one you add from code. Loaded any other way, the chart script carries no nonce. Then allow your Mindset host in script-src, or keep 'strict-dynamic' so scripts your trusted scripts add are allowed.
Styles
The element puts its stylesheet in its own shadow root as a constructed stylesheet. Current browsers don't apply style-src to constructed stylesheets, so the element needs no 'unsafe-inline' and no style entry for the Mindset host.
Two things do add a <style> element, and a strict style-src blocks them:
- Older Safari (before 16.4) can't construct stylesheets, so the element falls back to a
<style>element in its shadow root. - Dialogs, popovers and menus inside the chat add a small
<style>element to your page's<head>while they are open, to stop the page behind them scrolling.
Blocking these is cosmetic: the browser reports a CSP violation and that styling is lost. In current browsers that means the page behind an open dialog can still scroll. On older Safari the chat loses its stylesheet. If you need it to look right on older Safari, add style-src 'self' 'unsafe-inline'. Otherwise leave style-src strict.
What Mindset sends back
You don't configure any of this, but it explains why the policy above is enough.
/sdk/*and/fonts/*are served withAccess-Control-Allow-Origin: *andCross-Origin-Resource-Policy: cross-origin, so a page on any origin can load them.- The routes the agent runs on answer cross-origin requests from any origin, without cookies. The session credential travels in an
Authorizationheader, never a cookie. - The session create call has no CORS headers at all, so a browser can't make it. It belongs on your server. See Create a session for your users.
What can go wrong
| What you see | Cause and fix |
|---|---|
| The console reports a blocked script from your Mindset host, and no panel appears | script-src doesn't allow the host, or the script tag lacks the nonce your policy requires |
The panel appears but every message fails with turn-failed | connect-src doesn't allow the host. The console shows the blocked fetch |
| Charts say they couldn't be drawn | The chart script was blocked. Allow the host in script-src, or put your nonce on the main script tag |
| Text is in a system font | font-src doesn't allow the host |
CSP violation reports mention style-src while a dialog is open | The scroll lock's <style> element. It's cosmetic. See styles |
| Images in replies are broken | img-src doesn't allow the host the image comes from |
Related
- Put an agent on your page for the basic setup.
- Errors and resilience for every error the SDK raises.