# HTTP Concealed (RFC 9729): authentication that hides a resource even exists
Table of Contents
Most website login systems share a rarely discussed flaw: they’re visible. Even without knowing the password, it’s often easy to tell that something behind a given address is meant to be protected. In February 2025 the IETF, the body that maintains Internet’s technical standards, published RFC 9729 and defined a new HTTP authentication scheme built to avoid exactly that. It’s called “Concealed”.
The problem: locked doors you can still spot
When a browser asks for a page and the server requires access, it usually says so openly. The classic case is a response with status code 401 Unauthorized and a WWW-Authenticate header, through which the server announces: “you need to authenticate here”. That’s useful and correct behaviour on the vast majority of sites, but it has a side effect: anyone who tries that address learns there’s a protected resource behind it.
The RFC uses a precise term for this: traditional authentication schemes are probeable. An unauthenticated client can send requests at random and watch the responses to work out where the server keeps something under lock and key. On a public site that’s no problem. It becomes one when the goal is for certain services to stay invisible to anyone who doesn’t already know they exist: a private panel, a management endpoint, a resource meant for a small group.
The tricky part is that, for an attacker, knowing something exists is already half the work. An automated scanner sweeping through thousands of addresses feeds on exactly these differences in responses, the same kind of background traffic described in the piece on brute force attacks. If the server treats a locked door differently from a door that isn’t there, that difference is a clue.
What the “Concealed” scheme is
RFC 9729 defines a new cryptographic authentication scheme for HTTP with one extra property: it’s non-probeable. In practice, an outside observer can’t tell a server that requires this kind of authentication apart from one that does nothing of the sort.
The mechanism is built on asymmetric cryptography. The term is worth unpacking: every authorised user holds a pair of keys, one private (kept secret) and one public (shared with the server in advance). The server keeps a list mapping each key ID to its public key. Anyone wanting to authenticate proves they hold the private key by signing an agreed-upon piece of data; the server verifies that signature with the public key it has on file. No password ever travels across the wire.
One practical point to keep in mind: the keys have to be distributed beforehand, by some other channel. The scheme assumes the server already knows which keys to accept. It isn’t meant for signing up to just any site, but for letting in people who were added to the list ahead of time.
How it hides the resource’s existence
The trick lies in how the data to be signed is generated. In classic cryptographic schemes, to stop an old signature from being reused, the server sends the client a one-time value (a nonce) to fold into the signature. But that very message from the server is the giveaway: by announcing the nonce, the server is saying “there’s authentication here”.
RFC 9729 removes that step. The fresh data to be signed doesn’t come from the server: the client derives it from the ongoing TLS connection, the same encryption that protects traffic on https sites, the same foundation the extra privacy of Encrypted Client Hello rests on. TLS offers a function, the keying material exporter, that lets client and server independently derive a secret value tied to that specific connection. Using a dedicated label - EXPORTER-HTTP-Concealed-Authentication - the client obtains this value, signs it with its private key, and sends it. The server, for its part, can recompute the same value and verify it.
The result is that the client speaks first, with no invitation needed. And here’s the part that matters for privacy: a server that wants to stay truly invisible must respond identically whether the resource doesn’t exist or exists but authentication failed. In practice it returns 404 Not Found in both cases. Anyone without the right key can’t tell “there’s nothing here” from “there’s something that isn’t for you”.
How it works, concretely
The authentication travels in the Authorization header (or Proxy-Authorization towards a proxy), using the Concealed scheme and a handful of parameters. Without diving into the cryptographic detail, the five fields the specification defines are:
k- the ID of the key the client wants to use;a- the public key the server uses to verify the signature;s- the signature scheme in use, drawn from the standard TLS registry;p- the proof (the signature itself) attesting possession of the private key;v- a verification value tied to the TLS exporter output.
One technical requirement applies: it needs TLS version 1.3, or 1.2 with the extended master secret extension. The reason is that the signature must stay anchored to that single connection. The scheme works with HTTP/2, HTTP/3 and the QUIC transport.
What it’s actually for
The main use case is keeping off the radar those services that shouldn’t be stumbled upon. An administration endpoint, a management interface, an internal API: with the Concealed scheme, anyone without a valid key has no way to tell that the address even does anything. It’s a form of defence in depth: it doesn’t replace the other protections, but it shrinks the surface an automated scanner can map.
There’s a tracking benefit too. The specification notes that the keys tie a user to a single origin (a single site), but are built so they can’t be used to correlate requests across different sites. In other words, the same person doesn’t become recognisable while moving from one domain to another.
What to watch out for
Like any tool, it has limits stated openly in the RFC.
The signature is bound to the connection, not to the individual request. That opens a reuse risk: if the header carrying the proof were to leak - say, because of code running in the same browser session - it could be exploited on other requests over the same connection. That’s why the RFC is blunt on one point: the keys used here must not be reused in other protocols.
Then there’s freshness. The signed value depends on the age of the TLS connection; a server wanting a more recent proof can force a new connection to be opened. And there’s the matter of timing side channels: if the server took different amounts of time to respond in the two cases - resource absent versus authentication failed - that millisecond difference could give away what was meant to stay hidden. Achieving genuinely indistinguishable responses takes care on this front too.
Where it stands
RFC 9729 isn’t a draft: it’s a published document, on the IETF standards track at the Proposed Standard level. That’s the first stable rung on the path: a mature, publicly reviewed specification, not yet the final “Internet Standard” level, the same stage reached recently by the HTTP header that flags deprecated APIs. Before reaching this point it was named draft-ietf-httpbis-unprompted-auth and was developed in the IETF’s httpbis working group.
The authors are David Schinazi (Google), David M. Oliver (Guardian Project) and Jonathan Hoyland (Cloudflare). In concrete terms, support on the browser and server side is still early and needs checking case by case: the specification is solid, and how far it spreads across real tools is what the coming years will decide. It remains an interesting idea, because it shifts the goal of authentication from “block access” to “don’t even let on there’s a door”.
