Security headers for Astro sites

The headers every Astro site should send, how to set them on a static host, and the Content-Security-Policy trap to watch for.

Security headers tell the browser how to treat your site. They cost nothing, they apply to every page, and many sites still don’t send them.

The headers to set

Header What it does
Strict-Transport-Security Tells browsers to always use HTTPS
Content-Security-Policy Limits where scripts, styles and other resources can load from
X-Content-Type-Options Stops browsers guessing file types
X-Frame-Options Stops other sites putting yours in a frame
Referrer-Policy Controls how much of your URL is shared with other sites
Permissions-Policy Turns off browser features you don’t use

Setting them on a static host

Cloudflare and Netlify both read a _headers file. In an Astro project, put it in public/ so it’s copied into the build:

/*
  Strict-Transport-Security: max-age=31536000; includeSubDomains
  X-Content-Type-Options: nosniff
  X-Frame-Options: DENY
  Referrer-Policy: strict-origin-when-cross-origin
  Permissions-Policy: camera=(), microphone=(), geolocation=()

Vercel sets headers in vercel.json. On a site with a server, you can set them in Astro middleware.

The Content-Security-Policy trap

A strict policy blocks inline scripts, and Astro can inline small scripts into your HTML to save a request. The page still loads and returns a 200, so a broken button is easy to miss. We hit exactly this on our own sign-in page.

One fix is to stop Vite inlining anything:

// astro.config.mjs
export default defineConfig({
  vite: { build: { assetsInlineLimit: 0 } },
});

Then search the build for leftover inline scripts, and check the browser console on any page with a form. Roll out a new policy carefully, because a policy that’s too strict can break pages without any obvious error. Content-Security-Policy-Report-Only lets you test one first.

Check the result

Look at the response headers on your live site, not your config, because a CDN can add or strip them. Em Region grades the headers on every site in your fleet.

Bring your whole fleet into view

We are onboarding a small group of hosts and agencies first.