> This page is for version 🇬🇧 UK.
> For other versions, use one of these documentation indexes:
> - 🇦🇺 AU (default): https://docs.humanapproved.com/au/llms.txt
> - 🇬🇧 UK: https://docs.humanapproved.com/uk/llms.txt
> - 🇺🇸 US: https://docs.humanapproved.com/us/llms.txt

> This is HumanApproved's documentation, as Markdown for AI agents. /llms.txt lists every page; /llms-full.txt has them all. If you're helping someone integrate HumanApproved, start with /guides/ai-coding-agents.

# Content Security Policy

> The script-src, connect-src and img-src entries a checkout's Content Security Policy needs for the HumanApproved embed.

The embed is built for strict policies: no `eval`, no inline script or style, and no `'unsafe-inline'`. Its pause panel's styles live in a closed shadow root. Add these sources to the policy you already have.

| Directive     | Add                            | Why                                                                         |
| ------------- | ------------------------------ | --------------------------------------------------------------------------- |
| `script-src`  | `https://cdn.beopen.com`       | The embed script.                                                           |
| `connect-src` | `https://uk.humanapproved.com` | The checks, the quote and the status polling.                               |
| `img-src`     | `https://uk.humanapproved.com` | The pause panel's logo, when your product has one on its **Branding** page. |

For example, a policy that only allows your own origin otherwise:

```http
Content-Security-Policy: default-src 'self'; script-src 'self' https://cdn.beopen.com; connect-src 'self' https://uk.humanapproved.com; img-src 'self' https://uk.humanapproved.com
```

* **`connect-src`** must allow your region's address, the host your key calls. Nothing else needs to be added: the embed's early connection and its settings request use the same host.
* **`img-src`**: if it doesn't allow the logo, the browser blocks the image and the panel leaves the logo out.
* **Your own file** with the `protect` call is on your site: load it the way your policy already allows your own scripts, for example from your origin or with your nonce. Don't put the call in an inline `<script>`: a strict policy blocks it and the step isn't protected, and there's no error.
* **The `page` font** for the panel uses fonts your page has already loaded, so it needs no directive.

## Subresource Integrity

Load a pinned version with its `integrity` hash and `crossorigin="anonymous"`:

```html
<script src="https://cdn.beopen.com/approvals-embed/1.5.0/embed.js"
        integrity="sha384-…" crossorigin="anonymous" async></script>
```

Copy the tag from the portal's **Embed** page, which has the hash filled in. The browser refuses a file that doesn't match the hash, so your pages only run the release you tested. A published release never changes, and there's no "latest" address: to upgrade, change the version and the hash together. A hash that doesn't match makes the browser refuse the script, which turns protection off.

The embed also works with Trusted Types: it uses no `innerHTML`.

## When the policy blocks the embed

If the policy blocks a request, the step proceeds unchecked. Look in the browser console for:

* **A refused script** from `cdn.beopen.com`: add it to `script-src`.
* **A refused connection** to your region's address: add it to `connect-src`. The embed's warning says the check got no response.
* **A refused image**: add your region's address to `img-src`.

See [Test and go live](/uk/guides/test-and-go-live#troubleshooting) for more.