MiniUtil field guide

Security Headers: A Safe Deployment Order

Roll out CORS, CSP, Permissions-Policy, caching, SRI, and security.txt in an order that limits breakage and contradictory settings.

Short answer: Inventory behavior first, deploy observability and low-risk controls next, then enforce policies one surface at a time with rollback criteria.

1. Inventory origins, resources, and sensitive responses

List the origins that call each API, the third-party resources every page loads, and which responses contain private data. Header generation is the last step; the inventory determines the policy.

2. Fix caching and publish a reporting contact

Set private or no-store behavior on personalized responses before tuning public asset caching. Publish security.txt early because it does not alter page execution and gives researchers a clear reporting path.

3. Narrow CORS per endpoint

CORS is a browser read-permission policy, not authentication. Allow only origins and methods required by the endpoint, return Vary: Origin when responses differ by origin, and never pair credentialed requests with a wildcard origin.

4. Observe CSP before enforcing it

Begin with Content-Security-Policy-Report-Only, collect violations without including sensitive page data, and remove unnecessary sources. Enforce the smallest proven policy, then tighten it incrementally.

5. Restrict features and verify external assets

Use Permissions-Policy to disable unused powerful features. Add Subresource Integrity only to immutable cross-origin assets with a dependable versioning strategy; otherwise a legitimate upstream change can break the page.

What each header actually controls

ControlPrimary jobCommon mistake
CORSWhich origins may read a response in browsersTreating it as login or request blocking
CSPWhich resources and execution paths a page may useEnforcing a guessed policy without reports
Permissions-PolicyWhich browser features a document or iframe may useAssuming it replaces user permission prompts
Cache-ControlWhere and how long a response may be storedCaching personalized responses publicly
SRIWhether a fetched asset matches expected bytesHashing an asset that changes at the same URL