--- title: Security headers description: The header set and Content Security Policy applied to every response. type: reference --- # Security headers kreogen uses [Nosecone](https://docs.arcjet.com/nosecone/quick-start) to set security-related response headers. It runs in middleware, so every response carries them — including redirects. ```ts // apps/app/proxy.ts import { noseconeOptions, securityMiddleware } from '@kreogen/security/proxy'; const securityHeaders = securityMiddleware(noseconeOptions); ``` Defaults cover `Strict-Transport-Security`, `X-Content-Type-Options`, `X-Frame-Options`, `Referrer-Policy`, `Cross-Origin-*` and friends. See the [Nosecone reference](https://docs.arcjet.com/nosecone/reference) for the full list. ## Content Security Policy Unlike the upstream template this is derived from, CSP is **enabled**. A policy that ships disabled is a policy nobody ever turns on. It is defined in `packages/security/proxy.ts`, grouped by the integration that needs each origin — so removing an integration means deleting its group rather than picking entries out of one long list: ```ts const POSTHOG = [ 'https://us.i.posthog.com', 'https://us-assets.i.posthog.com', ] as const; const STRIPE = ['https://js.stripe.com', 'https://api.stripe.com'] as const; ``` The `as const` is required. Nosecone types sources as a template-literal union, so a plain `string[]` will not typecheck. The policy is report-only in development, so a missing directive shows up as a console warning while you work, and enforced everywhere else. ## Adding an origin When you add an integration that talks to a new host, add it to the relevant directive. Miss this and the request is blocked in production while working fine in development — the most annoying possible failure mode. The directives most often needing extension: | Directive | For | | ------------ | ------------------------------------- | | `connectSrc` | APIs, websockets, analytics ingestion | | `scriptSrc` | Third-party scripts | | `imgSrc` | Remote images, avatars, CDNs | | `frameSrc` | Embedded checkout, video, iframes | ## Notes on the defaults `'unsafe-inline'` is present in `scriptSrc` because Next inlines its bootstrap and hydration payload. The stricter alternative — per-request nonces with `'strict-dynamic'` — requires threading a nonce from middleware through every script tag, and is worth doing for applications handling sensitive data. `frameAncestors` is `'none'` and `objectSrc` is `'none'`. Loosen the first only if the app is deliberately embeddable. `upgradeInsecureRequests` is on outside development. ## Verifying Check what is actually being sent: ```sh curl -sI https://app.example.com | grep -i "content-security-policy\|strict-transport" ``` [securityheaders.com](https://securityheaders.com) grades a deployed origin. --- For a semantic overview of all documentation, see [/sitemap.md](/sitemap.md) For an index of all available documentation, see [/llms.txt](/llms.txt)