Two sites I run have nearly identical content. Same topic, same author voice, similar inbound links, similar age. One ranks consistently higher on Google, gets cited more often by Perplexity, and earns a green padlock on every security scanner. The other had default Netlify headers and nothing else.
The difference was the header bundle. I deployed the same six headers to the second site, ran securityheaders.com on both, and within six weeks the gap in citations started to close. Not because the content changed. Because the server started speaking a more trusted protocol.
Why Response Headers Are a Trust Signal
A site that serves HTTPS but never sets Strict-Transport-Security is a site that can still be downgraded to HTTP by a man-in-the-middle. A site that does not set Content-Security-Policy is a site that will happily render any script an attacker can inject. A site without X-Frame-Options is a site that can be embedded in a clickjack frame on any attacker's page.
None of these vulnerabilities are hypothetical. They are documented attack categories that security scanners check, browsers warn about, and — importantly — crawlers notice. Google has publicly stated that HSTS contributes to ranking. Bing weights security posture. The AI citation engines inherit both of those signals through their retrieval stacks.
A full header bundle tells every requester — browser, crawler, AI — that the site operator understands how the web gets attacked and has taken the trouble to defend against it. That is a proxy for operator quality, and operator quality is what citation engines are trying to measure when they decide whose content to trust.
The Six Headers
Strict-Transport-Security (HSTS) forces HTTPS on every future request to the domain for a declared duration. It closes the downgrade-to-HTTP attack window. The standard value is one year with subdomain inclusion and preload eligibility:
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
Content-Security-Policy (CSP) tells the browser which sources of script, style, images, and other content to trust. A strict CSP prevents XSS by refusing to execute inline scripts or scripts from unauthorized domains:
Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:; connect-src 'self' https:; frame-ancestors 'none';
The exact policy is site-specific. Sites with third-party scripts (analytics, embeds) need looser rules. Static sites with no third-party dependencies can ship a very strict CSP.
X-Frame-Options prevents the site from being embedded in an iframe by another origin. DENY is the strongest setting:
X-Frame-Options: DENY
(Modern CSP's frame-ancestors directive supersedes X-Frame-Options, but shipping both covers older browsers and scanners.)
X-Content-Type-Options stops browsers from MIME-sniffing responses and executing, for example, a .jpg as JavaScript:
X-Content-Type-Options: nosniff
One word, one header, closes a whole class of attacks.
Referrer-Policy controls how much of the referring URL is sent to other origins. strict-origin-when-cross-origin is the current sensible default:
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy declares which browser features (camera, microphone, geolocation, accelerometer, etc.) the page needs. Disabling everything you do not use is the right default:
Permissions-Policy: camera=(), microphone=(), geolocation=(), interest-cohort=()
The interest-cohort=() part opts out of FLoC/Topics API, which is a privacy signal some users and auditors specifically look for.
The Netlify Header Block
This is the block I copy into netlify.toml on every new site:
[[headers]]
for = "/*"
[headers.values]
Strict-Transport-Security = "max-age=31536000; includeSubDomains; preload"
Content-Security-Policy = "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:; connect-src 'self' https:; frame-ancestors 'none'; base-uri 'self';"
X-Frame-Options = "DENY"
X-Content-Type-Options = "nosniff"
Referrer-Policy = "strict-origin-when-cross-origin"
Permissions-Policy = "camera=(), microphone=(), geolocation=(), interest-cohort=()"
Deploy. Six headers, one file.
Apache Syntax
For Apache, add to the vhost or .htaccess:
<IfModule mod_headers.c>
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
Header always set Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:; connect-src 'self' https:; frame-ancestors 'none'; base-uri 'self';"
Header always set X-Frame-Options "DENY"
Header always set X-Content-Type-Options "nosniff"
Header always set Referrer-Policy "strict-origin-when-cross-origin"
Header always set Permissions-Policy "camera=(), microphone=(), geolocation=(), interest-cohort=()"
</IfModule>
Nginx Syntax
For Nginx:
server {
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:; connect-src 'self' https:; frame-ancestors 'none'; base-uri 'self';" always;
add_header X-Frame-Options "DENY" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "camera=(), microphone=(), geolocation=(), interest-cohort=()" always;
}
The always directive matters on Nginx — without it, the header is only added to 200 OK responses, and errors go out bare.
Testing with securityheaders.com
After deploying, run the domain through securityheaders.com. The scan grades from F to A+. A correct bundle earns A or A+. If you land on B or lower, the scan tells you which header is missing or misconfigured.
The common failure is CSP that is too strict and breaks the site. Run the site in a browser after deployment and watch the console for CSP violations. If you see them, relax the specific directive that triggered the violation — typically script-src to allow a CDN or analytics domain.
The second common failure is HSTS max-age set too short. Some scanners flag anything under six months. Ship one year (31536000). Once HSTS is deployed, you cannot easily undo it for cached clients, so make sure the site works on HTTPS before shipping the header.
Why AI Engines Weight This
AI citation engines do not directly test your headers the way securityheaders.com does. But their retrieval layer runs on infrastructure that records the security posture of every domain it crawls. Domains with complete header bundles, valid TLS, modern cipher suites, and HSTS preload registration cluster in the "operator quality" bucket. Domains that fail scans cluster in the opposite bucket.
Content quality still matters most. But when two pages have equivalent content relevance for an answer, the one from the higher-trust domain wins the citation. The header bundle is one of the inputs to that trust score, along with WHOIS age, DNSSEC, valid SPF/DKIM/DMARC, and the full set of /.well-known/ resources.
Where the Analyzer Checks
The audit at /tools/mega-analyzer/ runs securityheaders-equivalent checks and reports per-header pass/fail. Missing HSTS is flagged as critical. Missing CSP is flagged as warn. The other four are each individual checks. You can deploy the full bundle above and pass all six in one afternoon.
The Short Version
- Six headers: HSTS, CSP, X-Frame-Options, X-Content-Type-Options nosniff, Referrer-Policy, Permissions-Policy.
- Netlify block is about 10 lines. Apache and Nginx equivalents are similar.
- Test at securityheaders.com. Aim for A or A+.
- The ranking and citation effects are indirect but real: complete headers are part of the trust cluster that AI retrievers use to decide whose pages to quote.
- Ship the bundle once, benefit on every response forever.