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

# Embed deployment & CSP

> The embed is Pulse-hosted — the Content-Security-Policy, frame-ancestors, and CNAME details that govern how it's framed inside your page, and what to configure if you host Tier B on your own subdomain.

The embed is Pulse-operated — you never build or host its code yourself, even
when it's served from your own subdomain (Tier B, via CNAME). This page
covers what its hosting and security model means for your integration: the
headers it serves, the framing rules that control who may embed it, and what
to set up if you put it behind your own domain.

## Where the embed is served

The embed is served from a versioned path, `https://embed.pulse.shiga.io/v1/`
by default. **The path is versioned, not the assets**: breaking bridge/protocol
changes go to a new version (`/v2/`) — the version you're integrated against
keeps working for you indefinitely, with no upgrade required on your side.

## Content-Security-Policy the embed serves

```http theme={null}
Content-Security-Policy:
  default-src 'self';
  script-src 'self';
  style-src 'self' 'unsafe-inline';
  img-src 'self' data: https:;            # data: for QR; https: for partner logos (Tier B)
  connect-src 'self' https://api.pulse.shiga.io https://sandbox.api.pulse.shiga.io;
  frame-ancestors *;                       # see note below
Referrer-Policy: no-referrer
X-Content-Type-Options: nosniff
```

* **`frame-ancestors`** controls which pages are allowed to embed the iframe.
  It's `*` today — any partner page may embed it. The hardened end-state is a
  per-partner allowlist: the embed host reads your registered origin(s) from
  your partner config and emits `frame-ancestors <your origins>` instead. Once
  that ships, make sure the origin(s) you embed from are registered.
* **`connect-src`** lists every API host the embed calls: `api.pulse.shiga.io`
  in production, `sandbox.api.pulse.shiga.io` for sandbox integrations (see
  [Sandbox](/testing/sandbox)).
* The session token arrives in the URL **fragment** — it is never sent to the
  server, never appears in access logs, and `Referrer-Policy: no-referrer`
  keeps it out of outbound referrers. You don't need to do anything extra to
  protect it beyond not logging the full URL yourself.

## Already handled for you

* The iframe is mounted with
  `sandbox="allow-scripts allow-same-origin allow-forms allow-popups"` — no
  top-navigation, no downloads. You don't set this yourself; the SDK applies
  it when you call `mount()`.
* The postMessage bridge between your page and the iframe is origin-checked
  in both directions.
* `mount()` rejects `sk_` keys outright, and fires `embed_load_timeout` if the
  embed never becomes ready — both fail loudly rather than silently degrading.

## Hosting Tier B on your own subdomain

If you serve the [hosted page](/render/hosted-page) from your own subdomain
(for example `pay.yourapp.com`) instead of redirecting to the Pulse-hosted
URL: CNAME your subdomain to the embed host. A TLS certificate is provisioned
per partner domain, and you get the same build, served with `layout=page` —
see [Hosted page (Tier B)](/render/hosted-page) for the query parameters and
[Embedded iframe (Tier A)](/render/embedded-iframe) if you're mounting the
component directly instead.
