⚡ Chromium Post-Quantum HTTPS Authentication Roadmap

The HRPQ downgrade gap
lives between the origin and the cookie jar.

HRPQ lets one origin require post-quantum TLS. Cookies don't stop at the origin, they're scoped to the whole registrable domain. hrpq-gap-scan finds the sibling subdomains, missing headers, and enterprise TLS proxies that turn that mismatch into a real downgrade path, before an incident finds it for you.

Three ways the model breaks

Cookie scoping ignores HRPQ

A domain-scoped cookie set by a PQ-protected origin is still readable by, and overwritable by, any PQ-insecure sibling on the same registrable domain. Protecting one origin doesn't protect that origin's session state.

includeSubDomains is all-or-nothing

Set it, and any subdomain that isn't PQ hybrid-capable hard-fails once HRPQ is enforced, no silent classical fallback. Leave it off, and the cookie-injection gap above stays open.

Enterprise TLS proxies are invisible

A proxy that terminates and re-originates TLS is its own migration target. Clients roaming between a proxied and unproxied network see connections fail and recover with no obvious explanation.

What it reports

FindingSeverityMeaning
hrpq-missing-includesubdomains HIGH HRPQ set without includeSubDomains; siblings can still inject cookies into this origin's session state.
includesubdomains-breaks-subdomain HIGH includeSubDomains set, but a subdomain isn't PQ-capable and will hard-fail once HRPQ is enforced.
cookie-injection-exposure HIGH A domain-scoped cookie from a PQ-capable host is exposed to a non-PQ-capable sibling.
proxy-downgrade-vector HIGH A host negotiates PQ hybrid directly but not through an enterprise proxy path (via diff).
no-pq-hybrid MEDIUM Host negotiated a classical group; a downgrade pivot point until upgraded.
unreachable LOW Host couldn't be probed; verify manually.

Usage

$ hrpq-gap-scan scan example.com --subdomains app.example.com legacy.example.com

hrpq-gap-scan report for example.com
============================================================
  example.com: X25519MLKEM768 [PQ hybrid]  max-age=31536000; includeSubDomains
  app.example.com: X25519MLKEM768 [PQ hybrid]  no HRPQ header
  legacy.example.com: X25519 [classical]  no HRPQ header

Findings (3):
  [HIGH] legacy.example.com: example.com sets includeSubDomains, but
         legacy.example.com does not negotiate a PQ hybrid group. Browsers
         enforcing HRPQ have no silent classical fallback here.
  [HIGH] example.com: Cookie 'session' is domain-scoped (Domain=.example.com)
         and set by a PQ hybrid-capable host, but legacy.example.com on the
         same registrable domain is not PQ hybrid-capable.
  [MEDIUM] legacy.example.com: Negotiated group was 'X25519', a classical
         group. This host is a viable downgrade pivot until upgraded.
$ hrpq-gap-scan scan example.com --subdomains-file subdomains.txt --json

{
  "apex": "example.com",
  "hosts": { "...": "..." },
  "findings": [
    {
      "severity": "high",
      "kind": "cookie-injection-exposure",
      "host": "example.com",
      "detail": "Cookie 'session' is domain-scoped (Domain=.example.com) ..."
    }
  ]
}
$ hrpq-gap-scan scan example.com --json > direct.json      # outside the proxy
$ hrpq-gap-scan scan example.com --json > via_proxy.json   # inside the proxied network
$ hrpq-gap-scan diff direct.json via_proxy.json

Proxy vantage-point differences (1):
  [HIGH] app.example.com: app.example.com negotiates a PQ hybrid group
         directly but the proxied path resolves to 'X25519'. The
         TLS-inspecting proxy on this network path is the actual downgrade
         vector, not the origin server.

pip install -e . from a clone of the repo. Requires OpenSSL 3.2+ on PATH. Full walkthrough and sample output in examples/.