~/adr/001-csp-nonce-finalize-chain
Per-request CSP nonces via build-time finalize chain
accepted $ decided 14 Sept 2025
$ diff decision consequence
Decision
Generate a fresh random nonce at build time and propagate it through a three-script
chain — generate-csp emits the policy with a placeholder, inject-nonce stamps
the nonce into every inline <script> tag, and finalize-csp writes the final
headers into the prebuilt config.json so the deployed headers carry the real
nonce (see scripts/finalize-csp.mjs, plus the csp-nonce-outage post-mortem).
Consequences
- + No
unsafe-inlineinscript-src;strict-dynamiccarries trust transitively. - + Deterministic and auditable:
csp-checkfails the build on a committed placeholder nonce. - − Every deploy rotates the nonce, so cached HTML and headers must ship together — stale-edge HTML breaks inline scripts until revalidation.