# HSTS, CSP, and the Security Header Bundle: The Trust Signal You Send With Every Response

Six response headers, one deploy, measurable ranking and AI-citation improvements. Here&#39;s the bundle I ship on every site and the Netlify config to do it.

Author: J.A. Watte
Published: April 18, 2026
Source: https://jwatte.com/blog/blog-security-headers-trust-bundle/

---

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 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:

```toml
[[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`:

```apache
<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:

```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.


---

Canonical HTML: https://jwatte.com/blog/blog-security-headers-trust-bundle/
RSS: https://jwatte.com/feed.xml
JSON Feed: https://jwatte.com/feed.json
Hero image: https://jwatte.com/images/blog-security-headers-trust-bundle.webp
