Security Headers on Cloudflare — Transform Rules Configuration

Updated April 2026

Quick Answer Set security headers on Cloudflare via Transform Rules: Dashboard → Rules → Transform Rules → Modify Response Header → Create Rule. Add Strict-Transport-Security, X-Frame-Options, X-Content-Type-Options, Referrer-Policy, and Permissions-Policy as static headers. They apply at the edge to every request, regardless of origin server configuration.

Cloudflare lets you set security headers at the edge via Transform Rules — no origin server changes needed. Every request gets the headers before it reaches your users.

Scan your Cloudflare site → HeadersFixer

The two approaches

You can set security headers either from your origin server (Nginx, your app) or at the Cloudflare edge via Transform Rules. Edge rules win because they apply even if your origin forgets to send them — and they survive origin changes.

Setting headers via Transform Rules (recommended)

  1. Cloudflare Dashboard → your domain
  2. Rules → Transform Rules → Modify Response Header
  3. Create Rule → name it "Security Headers"
  4. When: All incoming requests (or use a custom filter)
  5. Then: Set static — add each header below
Header nameValue
Strict-Transport-Securitymax-age=31536000; includeSubDomains
X-Frame-OptionsSAMEORIGIN
X-Content-Type-Optionsnosniff
Referrer-Policystrict-origin-when-cross-origin
Permissions-Policycamera=(), microphone=(), geolocation=(), interest-cohort=()
Cross-Origin-Opener-Policysame-origin

Adding CSP via Transform Rules

CSP values can be long — Cloudflare Transform Rules support up to 4096 characters per header value:

Header name: Content-Security-Policy
Value: default-src 'self'; script-src 'self' https://www.googletagmanager.com; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self'; connect-src 'self'; frame-ancestors 'none'; object-src 'none'; base-uri 'self';

Wrangler (Workers config)

If you use Cloudflare Workers, set headers in your Worker script:

export default { async fetch(request, env) { const response = await fetch(request) const newResponse = new Response(response.body, response) newResponse.headers.set('X-Frame-Options', 'SAMEORIGIN') newResponse.headers.set('X-Content-Type-Options', 'nosniff') newResponse.headers.set('Referrer-Policy', 'strict-origin-when-cross-origin') newResponse.headers.set( 'Strict-Transport-Security', 'max-age=31536000; includeSubDomains' ) newResponse.headers.set( 'Permissions-Policy', 'camera=(), microphone=(), geolocation=()' ) return newResponse }
}

HSTS on Cloudflare

Cloudflare has a dedicated HSTS toggle: Dashboard → SSL/TLS → Edge Certificates → HSTS. Use this instead of a Transform Rule for HSTS — it is easier to manage and handles the preload submission correctly.

Do not enable HSTS includeSubDomains until all subdomains support HTTPS. If any subdomain is HTTP-only, users will be locked out after HSTS is cached.

Why headers sometimes disappear behind Cloudflare

If your origin sets headers but they vanish in production, Cloudflare may be stripping them. Check:

Compare origin vs Cloudflare headers → Header Diff