Content Security Policy, hosts and first-party relay
This page is for the engineer who owns your site’s Content Security Policy (CSP) or network allow-list. It lists which hosts the browser collector talks to, which CSP directives it needs, what happens when a directive is missing, and how to put the collector on a subdomain of your own site with a relay hostname.
Key points
- Allow both Noxtica hostsAllow collect.noxtica.com and ingest.noxtica.com in connect-src. A telemetry call that fails is retried once on the collector host.
- wasm-unsafe-eval, not unsafe-evalscript-src needs 'wasm-unsafe-eval' for the engines. Noxtica does not need 'unsafe-eval'. Without it collection continues with reduced evidence.
- Blob workers need worker-srcThe engines start workers from blob: URLs, so worker-src must include blob: next to your own entries.
- Relay needs plan, DNS and a noticeA relay hostname needs a plan that includes it, a CNAME and a TXT record, and a confirmed privacy-notice update. A tenant can hold 3 live hostnames in the current release.
What it is
Availability: Evaluation access. Availability depends on your plan, role and the modules enabled for your organisation. Relay hostnames also depend on your plan and on relay provisioning being enabled for your deployment.
The collector uses these hosts:
| Host | What goes there |
|---|---|
collect.noxtica.com (your collector host) | The core and extensions scripts, the engine loaders and WebAssembly files, POST /client/token, /client/submit, /client/visit and the interaction tracker. |
ingest.noxtica.com | High-volume telemetry: RUM, RUM error detail, console logs, the client buffer, and the replay policy and upload calls. The loader derives it from the default collector host. |
challenges.cloudflare.com | The Cloudflare Turnstile script, loaded when the server asks the browser for a challenge. |
Both Noxtica hosts must be allowed in connect-src. A telemetry call that fails or answers a server error is retried once on the collector host, and the lane then stays on the collector for the rest of the page. A client error (4xx) never moves hosts.
A relay hostname replaces collect.noxtica.com with a subdomain of your own site, for example noxtica.example.com. You add a DNS record, Noxtica issues the certificate, and the page then loads the collector from your subdomain. Some privacy tools block third-party hosts; a hostname under your own domain is not third-party. Noxtica does not promise that any blocker lets the collector through.
Prerequisites
- Control of the CSP header or meta tag of the pages that carry the tag.
- To use a relay hostname:
- Workspace admin access to Backoffice → Integrations & API → Relay Hostnames, and a step-up MFA confirmation for each change.
- A plan that includes relay hostnames. Without one, the Backoffice refuses to create the hostname (
plan_feature_required). Relay hostnames are billed per active hostname; see Pricing. - Relay provisioning enabled for your deployment. Otherwise the page says “Relay provisioning is not yet enabled for this deployment”.
- DNS control of the subdomain you want to use.
- An updated privacy policy and cookie notice. The Backoffice makes you confirm it before it creates the hostname.
- The domain’s Site Key and its domain id.
Steps
1. Add the Noxtica sources to your policy
Merge the sources into your own directives. Do not paste a policy over yours: you would drop your own 'self' entries.
| Directive | Add | Why |
|---|---|---|
script-src | https://collect.noxtica.com and 'wasm-unsafe-eval' | Loads the scripts, and lets the KHAN and Obsidian engines compile WebAssembly. 'wasm-unsafe-eval' does not allow eval(). |
worker-src | blob:, next to your own entries | The engines start workers from blob: URLs. A worker script must be same-origin, so it cannot come from the collector host. |
connect-src | https://collect.noxtica.com and https://ingest.noxtica.com | Token and submit calls go to the collector host. Telemetry goes to the ingest host. |
| Turnstile directives | https://challenges.cloudflare.com | When your domain uses server-requested challenges, the core loads Turnstile. Allow the host in the directives that Cloudflare’s Turnstile documentation names. |
Content-Security-Policy:
script-src 'self' https://collect.noxtica.com 'wasm-unsafe-eval';
worker-src 'self' blob:;
connect-src 'self' https://collect.noxtica.com https://ingest.noxtica.com;
Backoffice → Integrations & API → Script & Consent → CSP & storage prints the same lines for your hosts. The reasons behind 'unsafe-eval', chrome-extension: reports, hashes and nonces, and the report-only probe are in Content Security Policy.
Noxtica does not need 'unsafe-eval'. Add 'wasm-unsafe-eval' instead.
If you keep telemetry on the collector with data-ingest-url set to the collector origin, connect-src needs the collector host alone. If you set data-ingest-url to another host, allow that host instead of ingest.noxtica.com.
2. Know what degrades without 'wasm-unsafe-eval'
Before it loads any WebAssembly module, the loader checks whether the policy allows WebAssembly. When it does not, the KHAN engine and the GPU attestation engine stop with the message WebAssembly blocked by Content Security Policy. Add 'wasm-unsafe-eval' to the script-src CSP directive. Collection carries on with reduced evidence. Native collection and the submit still run. The fix is the directive, not a code change.
Read the engine status in the console. These are diagnostic helpers that support may ask you about:
window.NoxticaCollector.getKhanVmStatus();
window.NoxticaCollector.getGpuVmStatus();
An enforced violation for the extensions script also shows up in loadExtensions() as reason: 'csp_blocked', with code set to script-src-elem or script-src. A connect-src that blocks the follow-up diagnostic request reads as network.
3. Check the policy in report-only mode
Send the policy you want as Content-Security-Policy-Report-Only for a day, read the reports, then enforce it. A stricter report-only header next to a permissive enforcing one shows what the permissive policy hides.
Content-Security-Policy-Report-Only: script-src 'self' https://collect.noxtica.com 'wasm-unsafe-eval'; worker-src 'self' blob:; connect-src 'self' https://collect.noxtica.com https://ingest.noxtica.com; report-uri /csp-report
4. Create a relay hostname (optional)
- Open Backoffice → Integrations & API → Relay Hostnames. The DNS setup box shows the CNAME target. It reads “Pending operator configuration” until the target is set for your deployment.
- Enter the Domain (the id of the domain the hostname belongs to) and the Relay hostname, for example
noxtica.example.com. - Tick Acknowledge privacy-notice obligation: “I confirm I have updated my privacy policy and cookie-consent notice to disclose this relay endpoint, as required by GDPR Art.13/14 and the ePrivacy Directive.”
- Select Add hostname and confirm the MFA prompt. The toast says “Relay hostname created. Add the DNS records, then verify.”
The hostname must be a public DNS name: letters, digits, hyphens and dots, at least two labels, each label up to 63 characters and the whole name up to 253 characters. A name under noxtica.com and a private or reserved name are refused. A tenant can hold a limited number of live hostnames: 3 in the current release. A revoked hostname frees its slot.
5. Add the DNS records and verify
- At your DNS provider, add a CNAME record from your hostname to the CNAME target.
- Add the TXT record that the Backoffice shows under the hostname (“Add this TXT record to verify ownership:”), as
name = value. - Select Verify on the hostname row. The status badge moves through Pending DNS, DNS verified and Issuing certificate to Active. Verification failed means the records did not check out; correct them and select Verify again.
Backoffice → Domains → open the domain → Relay tab shows the same status read-only.
6. Point the page at the relay hostname
When the badge reads Active, serve the collector from your hostname:
<script
src="https://noxtica.example.com/collector/noxtica-collector-core.js"
data-site-key="pk_prod_your_site_key_here"
data-api-url="https://noxtica.example.com"
data-auto-init
data-auto-check-once
async
></script>
- Keep the file name
noxtica-collector-core.js. The loader binds a tag by that name. data-api-urlmakes the token, submit and visit calls go to your hostname. Withdata-ingest-urlleft atauto, a host other than the default collector keeps its telemetry on itself, so one host serves everything.- The extensions script is loaded from the folder of the core script, so it comes from your hostname too. The engine files named in the session token follow the host that issued the token.
- Update
script-srcandconnect-srcto your hostname. The Noxtica hosts are no longer needed for this domain unless you setdata-ingest-urlto one of them. - The Backoffice snippets are generated for the default hosts. Replace the host in the generated tag yourself.
- Keep the Site Key of the domain that the hostname belongs to. The page origin must still match the domain; the relay hostname is the collector host, not your page origin.
- Switch a staging page before production, and run the checks in the next section.
7. Revoke a relay hostname
Select Revoke on the hostname row and confirm: “Revoke this relay hostname? Telemetry served on it will stop and the certificate will be removed.” Switch your tags back to collect.noxtica.com before you revoke. Revoke the hostname in the Backoffice, then remove the DNS records.
Add the sources to your policy
Merge script-src, worker-src and connect-src entries for the collector and ingest hosts into your own policy.
Know what degrades
Without 'wasm-unsafe-eval' the engines stop with a WebAssembly-blocked message. Native collection and the submit still run.
Probe in report-only mode
Send the target policy as Content-Security-Policy-Report-Only for a day, read the reports, then enforce.
Create the relay hostname
In Integrations & API → Relay Hostnames enter the domain and hostname, tick the privacy-notice acknowledgement and confirm MFA.
Add DNS records and verify
Add the CNAME and TXT records, select Verify, and wait for the badge to read Active.
Point the page at the relay
Use the hostname in the script src and data-api-url, and update script-src and connect-src. Test on staging first.
Revoke when done
Switch tags back to collect.noxtica.com, revoke the hostname in Backoffice, then remove the DNS records.
Verify it works
- In DevTools → Network, filter by the collector host. The core script,
POST /client/token, and after consent the extensions script andPOST /client/submitcome from that host. Telemetry calls go to the ingest host, or to your relay hostname. - The console shows no CSP violation that names a Noxtica host.
- After consent,
window.noxticaClient.getExtensionsState()is'attached', andwindow.NoxticaCollector.getKhanVmStatus()reports no CSP error. - For a relay hostname,
window.noxticaClient.apiUrlandwindow.noxticaClient.ingestUrlare your hostname. - In Backoffice → Domains → the domain → Relay, the hostname shows Active.
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
| Console violation for the core or extensions script | script-src lacks the collector host or your relay hostname | Add the host. loadExtensions() answers csp_blocked with script-src-elem or script-src. |
WebAssembly blocked by Content Security Policy | script-src lacks 'wasm-unsafe-eval' | Add it. Collection continues with reduced evidence until you do. |
| Engine workers fail to start | worker-src lacks blob:, or it replaced your own entries | Add blob: next to 'self'. |
| Telemetry calls are blocked, token and submit work | connect-src lists the collector host but not the ingest host | Allow both hosts, or set data-ingest-url to the collector origin. |
loadExtensions() answers network while a CSP is in force | connect-src blocks the diagnostic request that classifies the failure | Allow the collector host in connect-src. |
| A Turnstile widget never appears | challenges.cloudflare.com is not allowed | Allow it as Cloudflare documents. |
Relay: creating the hostname fails with plan_feature_required | Your plan has no relay hostnames | Change the plan or contact your account team. |
| Relay: “Relay provisioning is not yet enabled for this deployment” | Provisioning is not set up for your deployment | Contact your account team. |
| Relay: Add hostname is disabled | The hostname or domain is empty, the acknowledgement is not ticked, provisioning is unavailable, or the limit is reached | Complete the fields and the acknowledgement, or revoke an unused hostname. |
| Relay: stays on Pending DNS | The CNAME or TXT record is missing or wrong | Compare the records with the Backoffice values and select Verify. |
| Relay: Verification failed | The records did not verify | Correct the records and select Verify again. |
Token call answers 403 with Origin mismatch | The page origin is not the one registered for the Site Key. A relay hostname does not change this. | Use the Site Key of the page origin. |
Related
- Install and Browser Runtime: the CSP section, stable and pinned tags, and the recorder head.
- Script attributes and client options:
data-api-urlanddata-ingest-url. - Cookies, storage and consent categories for your site: update your notices before you enable a relay.
- Domains, site keys and the install card: domain ids and the Relay tab.
- Browser SDK troubleshooting: symptoms across the SDK.
- Subprocessors: who Noxtica uses to deliver the service.