> ## Documentation Index
> Fetch the complete documentation index at: https://docs.puntego.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Content Security Policy

> Run Puntego under a strict CSP with a copy-paste policy, per-directive origins, and nonce propagation.

Puntego runs cleanly under a strict Content Security Policy. The boot script and
runtime are nonce-aware: you pass your per-request nonce once, and Puntego reuses
it for every script and style element it injects. No `'unsafe-inline'` and no
`'unsafe-eval'` are required for the guide to load, chat, point, and run
Verified Actions.

This page gives you a baseline policy that covers the core experience, then the
exact additions to make when you enable Verified Actions or voice. Treat the
samples as a starting point and confirm them against your own application's
directives — most sites already serve a CSP, and the values below are meant to
be merged into it rather than to replace it.

## Minimal baseline policy

This is the smallest policy that loads the guide, lets it chat, and lets it point
and highlight on your page. Replace `{NONCE}` with your per-request nonce value
(the same one you put on the boot script). A real header is a single line; it is
wrapped here for readability.

```http theme={null}
Content-Security-Policy:
  default-src 'self';
  script-src 'self' 'nonce-{NONCE}' https://puntego.com;
  connect-src 'self' https://worker.puntego.com;
  style-src  'self' 'nonce-{NONCE}';
  img-src    'self' data:;
```

### What each origin is for

| Directive     | Value                               | Why it is needed                                                                                                                                  |
| ------------- | ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| `script-src`  | `'self'`                            | Your own application scripts.                                                                                                                     |
| `script-src`  | `'nonce-{NONCE}'`                   | Authorizes the Puntego runtime and any follow-on chunks it injects (they carry your nonce).                                                       |
| `script-src`  | `https://puntego.com`               | Serves `boot.js` and the runtime bundle.                                                                                                          |
| `script-src`  | `https://challenges.cloudflare.com` | Turnstile, used by Verified Actions. Add only when Verified Actions are enabled.                                                                  |
| `connect-src` | `'self'`                            | Your own application requests.                                                                                                                    |
| `connect-src` | `https://worker.puntego.com`        | The Puntego worker — boot, chat, consent, and trace calls. This must match your `data-gp-api`; without a reachable worker the guide cannot start. |
| `connect-src` | `https://api.openai.com`            | OpenAI Realtime, used by voice. Add only when voice is enabled.                                                                                   |
| `connect-src` | `wss://api.elevenlabs.io`           | ElevenLabs realtime speech, used by voice. Add only when voice is enabled.                                                                        |
| `style-src`   | `'self'`                            | Your own application styles.                                                                                                                      |
| `style-src`   | `'nonce-{NONCE}'`                   | The runtime injects a single stylesheet for the guide's shadow root and stamps your nonce onto it.                                                |
| `frame-src`   | `https://challenges.cloudflare.com` | Turnstile renders its challenge in a frame. Add only when Verified Actions are enabled.                                                           |
| `img-src`     | `'self' data:`                      | Guide icons and inline image data used by the launcher and panel.                                                                                 |

> **Test before you ship.** The injected stylesheet carries your nonce, so a
> nonce-based `style-src` admits it without `'unsafe-inline'`. We do not promise
> a nonce-only `style-src` is sufficient for every setup — your other app
> directives and any third-party styles still apply — so verify the policy in a
> staging environment and watch the browser console for CSP violations before
> rolling it to production.

## Add Verified Actions (Turnstile)

[Verified Actions](/verified-actions) protect writes with a Cloudflare Turnstile
challenge. Turnstile loads a script and renders its challenge in a frame, so add
its origin to two directives:

```http theme={null}
script-src ... https://challenges.cloudflare.com;
frame-src      https://challenges.cloudflare.com;
```

## Add voice

Voice is optional per workspace. When it is enabled, the runtime opens realtime
connections to the speech providers, so extend `connect-src`:

```http theme={null}
connect-src ... https://api.openai.com wss://api.elevenlabs.io;
```

A strict-CSP site must also grant microphone access through a Permissions-Policy
header, or the browser blocks capture before Puntego ever asks:

```http theme={null}
Permissions-Policy: microphone=(self)
```

If voice provider credentials are not configured for your workspace, Puntego
falls back to an internal mock voice and these origins are not contacted — but it
is safe to leave them in place.

## Complete policy (all features)

With Verified Actions and voice both enabled, the merged policy looks like this:

```http theme={null}
Content-Security-Policy:
  default-src 'self';
  script-src 'self' 'nonce-{NONCE}' https://puntego.com https://challenges.cloudflare.com;
  connect-src 'self' https://worker.puntego.com https://api.openai.com wss://api.elevenlabs.io;
  style-src  'self' 'nonce-{NONCE}';
  img-src    'self' data:;
  frame-src  https://challenges.cloudflare.com;
Permissions-Policy: microphone=(self)
```

## Install snippet

Use the standard snippet when you do not serve a nonce-based CSP. Keep
`crossorigin="anonymous"` in both forms.

### Standard

```html theme={null}
<script
  async
  src="https://puntego.com/boot.js"
  data-app-id="gp_your_app_id"
  data-gp-api="https://worker.puntego.com"
  crossorigin="anonymous"
></script>
```

### Strict CSP (with nonce)

Pass the same nonce value to both `nonce` and `data-nonce`:

```html theme={null}
<script
  async
  src="https://puntego.com/boot.js"
  data-app-id="gp_your_app_id"
  data-gp-api="https://worker.puntego.com"
  crossorigin="anonymous"
  nonce="YOUR_CSP_NONCE"
  data-nonce="YOUR_CSP_NONCE"
></script>
```

Copy the canonical snippet from **Dashboard → Install** so your app ID stays
aligned with the deployed worker and embed assets.

## How nonce propagation works

You only set the nonce once. The boot script reads it from either `nonce` or
`data-nonce`, then the runtime reuses that value for everything it adds to the
page:

* The boot script reads your nonce from `nonce` or `data-nonce`.
* The runtime stamps the same nonce on every follow-on script it loads (the
  runtime chunk and, when voice is active, the voice chunk).
* The runtime stamps the same nonce on the single stylesheet it injects for the
  guide's shadow root.

Because Puntego propagates the nonce instead of inlining unguarded scripts or
styles, your `script-src` and `style-src` can stay nonce-based with no
`'unsafe-inline'`.

## Next steps

* [Install Puntego](/install) — the full script tag, configuration attributes,
  and domain allowlist.
* [Framework guides](/frameworks) — read a per-request nonce from `next/headers`
  and pass it through the `@puntego/react` provider, plus single-page-app routing
  and a no-code Google Tag Manager template.
* [Verified Actions](/verified-actions) — what the Turnstile origins protect and
  how approved actions are configured.
* [Security](/security) — how Puntego isolates the guide, redacts PII, and keeps
  telemetry clean.
