Sentry’s browser SDK needs connect-src for the ingest host in your DSN, which Sentry’s loader docs write as *.sentry.io, and Session Replay adds worker-src 'self' blob: for its compression worker. Loading the SDK from Sentry’s CDN or Loader Script adds script-src https://browser.sentry-cdn.com https://js.sentry-cdn.com. To collect your policy’s violations in Sentry as well, point report-uri and report-to at the project’s Security Header endpoint, under Project Settings > Security Headers.
The policy, in Report-Only
Reporting-Endpoints: csp-endpoint="https://o123456.ingest.sentry.io/api/7890123/security/?sentry_key=0123456789abcdef"
Content-Security-Policy-Report-Only: default-src 'self'; script-src 'self' https://browser.sentry-cdn.com https://js.sentry-cdn.com; connect-src 'self' https://*.sentry.io; worker-src 'self' blob:; child-src 'self' blob:; object-src 'none'; base-uri 'self'; frame-ancestors 'self'; report-uri https://o123456.ingest.sentry.io/api/7890123/security/?sentry_key=0123456789abcdef; report-to csp-endpoint
The IDs and key are placeholders: copy yours from the project. Report-Only blocks nothing; the browser reports each violation, and Sentry collects them. The builder shows no meta tag, because a meta tag can’t carry a report-only policy, and finds one low point: report-uri is deprecated in favor of report-to, and Sentry recommends both. Chrome, Firefox 149 and later and Safari 16.4 and later read report-to, by MDN’s compatibility data, and under CSP Level 3 they ignore report-uri when both are present; older browsers still need it. Sentry’s example also sends the older Report-To header, with the same URL.
Where the SDK sends events
- The DSN’s host. Events go to the ingest host in your DSN,
o<org-id>.ingest.sentry.io, at/api/<project-id>/envelope/. The builder reads Sentry’s bare*.sentry.ioas any subdomain over https, or over http too on an http page;https://*.sentry.iopins it to HTTPS. You can narrow it to the exact host in your DSN. - A tunnel. With
tunnel: "/tunnel"inSentry.init, the SDK posts to your own origin, and your server forwards to Sentry.connect-src 'self'covers it, and ad blockers don’t treat it as a third-party request. - Sentry’s guide also asks for its host in
connect-srcordefault-srcwhen you collect reports, so the policy above covers both jobs.
Session Replay
Replay compresses in a Web Worker made from a blob: URL, so worker-src 'self' blob:; Safari 15.4 and older also need child-src 'self' blob:. worker-src falls back to child-src, then script-src, then default-src, so if you set none of them, default-src decides and needs the blob: instead. If blob: workers are out, Sentry lets you host its compression worker yourself, under 'self'.
Rolling out
Report-Only first, then enforce. You can send both headers at once: enforce the policy you trust and report the stricter next one. Add sentry_environment or sentry_release to the report URL’s query string to tag reports.
In nginx
add_header Reporting-Endpoints 'csp-endpoint="https://o123456.ingest.sentry.io/api/7890123/security/?sentry_key=0123456789abcdef"' always;
add_header Content-Security-Policy-Report-Only "default-src 'self'; script-src 'self' https://browser.sentry-cdn.com https://js.sentry-cdn.com; connect-src 'self' https://*.sentry.io; worker-src 'self' blob:; child-src 'self' blob:; object-src 'none'; base-uri 'self'; frame-ancestors 'self'; report-uri https://o123456.ingest.sentry.io/api/7890123/security/?sentry_key=0123456789abcdef; report-to csp-endpoint" always;