# Security policy reports > https://docs.errora.org/en/products/security-reports Browsers can report policy violations back to a URL. Point that URL at Errora and violations become issues, grouped by directive and blocked host. Supported report types: **CSP**, **Expect-CT**, **Expect-Staple**, **HPKP**, including the batched **Reporting API** format. ## Setup The endpoint is per project and authenticated by the DSN public key: ```text https:///api//security/?sentry_key= ``` Add it to your policy header: ```text Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline'; connect-src 'self' https://; report-uri https:///api//security/?sentry_key= ``` Modern browsers prefer the Reporting API: ```text Reporting-Endpoints: csp-endpoint="https:///api//security/?sentry_key=" Content-Security-Policy: default-src 'self'; report-to csp-endpoint ``` Send both headers during a migration — support is uneven across browsers. ### Nginx ```nginx add_header Content-Security-Policy "default-src 'self'; report-uri https://errora.example.com/api/$PROJECT_ID/security/?sentry_key=$KEY" always; ``` ### Django ```python CSP_REPORT_URI = "https://errora.example.com/api//security/?sentry_key=" ``` ### Laravel Set the header in middleware, or with `spatie/laravel-csp`'s `reportUri` option. ## Rolling out a policy safely Start in report-only mode so nothing breaks while you learn what your pages actually load: ```text Content-Security-Policy-Report-Only: default-src 'self'; report-uri https://…/security/?sentry_key=… ``` Watch the issues for a week, fix the legitimate ones, then switch the header to the enforcing form. ## What you get Violations are grouped as issues by **directive + blocked host**, so `script-src` violations from one CDN are one issue, not ten thousand. Each event carries the document URI, the violated directive, the blocked URI, the effective policy and the browser. **Extension noise is filtered** — `chrome-extension://`, `moz-extension://` and friends — because your users' extensions are not your bug. ## Verify ```bash curl -X POST "https:///api//security/?sentry_key=" \ -H 'Content-Type: application/csp-report' \ -d '{"csp-report":{"document-uri":"https://example.com/","violated-directive":"script-src", "blocked-uri":"https://evil.example.net/x.js","effective-directive":"script-src"}}' ``` Then look in **Issues**. ## Troubleshooting | Symptom | Cause / fix | | --- | --- | | No reports at all | `report-uri` is inside the wrong header, or the browser only supports `report-to` | | `401` in the browser console | `sentry_key` missing or wrong in the query string | | Flood of reports | Usually one bad directive; fix the policy rather than filtering — that is what report-only mode is for | | Reports from extensions | Already filtered; if you still see them, they came through a page-injected script, not the extension protocol |