securityHeaders
Response headers for an app built with these components: strict CSP, HSTS, no framing, no sniffing.
// proxy.ts (Next.js) or any edge/middleware
const nonce = crypto.randomUUID();
for (const [name, value] of Object.entries(securityHeaders({ nonce }))) response.headers.set(name, value);Installation
Once per app, set up Aedis UI. The CLI verifies the signed release before writing anything and pins every dependency:
npx @aedis/cli@0.1.0 initImport the theme once in your global CSS, after Tailwind:
app/globals.css
@import "tailwindcss";@import "./styles/aedis-theme.css";Then add the component:
npx @aedis/cli@0.1.0 add security-headers# pnpm dlx @aedis/cli@0.1.0 add security-headers · yarn dlx @aedis/cli@0.1.0 add security-headers · bunx @aedis/cli@0.1.0 add security-headersProps
| Prop | Type | Default | Description |
|---|---|---|---|
| nonce | string | — | Per-request nonce; the framework must put it on its scripts. |
| hashes | string[] | — | Static sites: sha256-/sha384-/sha512- hashes of the inline scripts, computed at build time. Use instead of nonce; the policy is then 'self' plus the hashes. |
| connectSrc | string[] | [] | Extra origins for fetch and SSE. |
| imgSrc | string[] | [] | Extra origins for images. |
| frameAncestors | string[] | [] | Who may frame the page; nobody by default. |
Security
- script-src is nonce + strict-dynamic, or 'self' + build-time hashes on a static site: no inline script, no eval, no script from a CDN.
- A missing, doubled or malformed nonce or hash throws instead of producing a weaker policy.
- frame-ancestors 'none' and X-Frame-Options DENY stop clickjacking; form-action 'self' stops form hijacking.
- Cache-Control: no-store keeps pages with personal data out of shared caches.