What is the Strict-Transport-Security header?
The Strict-Transport-Security response header, defined in RFC 6797 (HTTP Strict Transport Security, HSTS), declares that a host must only be contacted over HTTPS. A conforming user agent that receives it over a secure connection notes the host as a Known HSTS Host for max-age seconds; during that time it rewrites http URLs for the host to https before sending anything, and it treats any certificate error as fatal, with no click-through.
The directive max-age is required. includeSubDomains extends the policy to every subdomain. max-age=0 tells the user agent to forget the policy. A user agent MUST ignore the header when it arrives over plain HTTP, and if a response carries more than one, it processes only the first.
API Usage & Best Practices
- Know who enforces it: HSTS is enforced by the client, and in practice the clients that enforce it are browsers. It protects an API that browsers call directly, such as one used by a single-page app through
fetch, because the browser will refuse to send a request, cookie or token to that host in cleartext. Server-to-server clients and most general-purpose HTTP libraries do not implement it; curl applies it only if you opt in with--hsts. - Send it anyway: It costs one header on HTTPS responses and closes the downgrade window for every browser that does talk to your API. Send it from every HTTPS response on the hostname, not just the home page, since RFC 6797 makes it a SHOULD on every secure response.
- Do not rely on it for machine clients: For SDKs and integrations, enforce HTTPS yourself: ship
httpsbase URLs, do not fall back tohttp, and on API-only hostnames prefer refusing plaintext over redirecting it. A redirect arrives after the credential has already crossed the network in cleartext, and a301may legitimately turn aPOSTinto aGET. - Roll out
includeSubDomainscarefully: Setting it on your apex domain coversapi.example.comtoo, which is good, but it also covers every internal or legacy subdomain still serving plain HTTP, which will break in browsers for the fullmax-age. Start with a shortmax-age, confirm nothing breaks, then raise it. - Treat preload as permanent:
preloadis not part of RFC 6797. It signals consent to the browser preload list run at hstspreload.org, which requiresmax-ageof at least31536000,includeSubDomainsandpreload, and warns that inclusion cannot easily be undone. Only submit a domain whose every subdomain will serve HTTPS for the long term.
Examples
HTTP/1.1 200 OKContent-Type: application/jsonStrict-Transport-Security: max-age=31536000; includeSubDomainsClearing the policy before retiring HTTPS on a host:
HTTP/1.1 200 OKStrict-Transport-Security: max-age=0