Skip to content

docs: explain the CSP nonce model across client-router soft navigations#1055

Merged
vivek7405 merged 2 commits into
mainfrom
docs/csp-nonce-client-router
Jul 22, 2026
Merged

docs: explain the CSP nonce model across client-router soft navigations#1055
vivek7405 merged 2 commits into
mainfrom
docs/csp-nonce-client-router

Conversation

@vivek7405

Copy link
Copy Markdown
Collaborator

Closes #1054

Documents the one genuinely subtle, security-relevant part of the CSP story that the docs skipped: how the nonce behaves across a client-router soft navigation.

What's added

  • docs/app/docs/security/page.ts: a "CSP and the client router" subsection under the existing CSP section, covering (a) enforcement is the HTTP Content-Security-Policy header, not a <meta http-equiv> tag (so frame-ancestors / report-uri work), and the <meta name="csp-nonce"> is only a client-side carrier; (b) on a soft nav the original page-load nonce stays authoritative and the router re-stamps every dynamically-inserted script/preload with it via getCspNonce() (fix: view-transition soft-nav meta leak and stuck Suspense skeleton #1049/fix: preserve csp-nonce on mergeHead, warn on dropped streamed resolve #1052); (c) no user config needed, and CSP pages are cache-excluded so a nonce is never replayed stale.
  • .agents/skills/webjs/references/built-ins.md: a matching paragraph in the CSP section.

Grew out of an analysis of whether the meta csp-nonce approach needed changes. It does not, the code was already correct, only the docs were silent.

Definition of done

Add a 'CSP and the client router' subsection to the security docs page and a
paragraph to the built-ins reference: enforcement is the HTTP header (not a
meta http-equiv tag), the meta name=csp-nonce is a client-side carrier, and on
a soft navigation the original page-load nonce stays authoritative and is
re-stamped onto every dynamically-inserted script/preload (#1049/#1052). Gives
users setting up strict CSP the why behind the model.
@vivek7405 vivek7405 self-assigned this Jul 22, 2026
Review: 'the ORIGINAL nonce stays authoritative for the whole session'
overstated. It holds for the life of the current document. A hard reload or
full page load creates a new document with the response's own fresh nonce.
Reword and add the harmless-full-load case so soft-nav vs hard-reload is
clear (the built-ins reference already stated this conservatively).

@vivek7405 vivek7405 left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Checked the prose against the code, all the mechanism claims hold. One overstatement: it said the original nonce stays authoritative for the whole session, which reads as if it survives a reload. It only holds for the life of the current document. Fixed, and added the harmless full-load case so the soft-nav vs hard-reload line is explicit.

Comment thread docs/app/docs/security/page.ts

@vivek7405 vivek7405 left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-read the soft-nav paragraph after the rewording. The document-scoped claim is accurate, the full-load case is spelled out, and it is consistent with the built-ins reference. Good to go.

@vivek7405
vivek7405 marked this pull request as ready for review July 22, 2026 19:50
@vivek7405
vivek7405 merged commit fdb0a95 into main Jul 22, 2026
10 checks passed
@vivek7405
vivek7405 deleted the docs/csp-nonce-client-router branch July 22, 2026 20:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Document the CSP nonce model across client-router soft navigations

1 participant