dbsc.alpagot.net · port 443 · a cookie that has to keep proving itself

A session cookie
that re-signs to survive.

A live Device Bound Session Credentials server, not a mockup. Click Start session and, if your browser supports DBSC, it generates a private key it will never let leave the device and starts proving possession of it every few minutes just to keep its cookie alive.

YOUR SESSION, VERIFIED AT THE EDGE

No DBSC session yet — click Start session below and watch this card. A supporting browser registers and starts refreshing automatically.

your JA4t13d1011h2_61a7ad8aa9b6_3fcd1a44f3e3
your JA3 (MD5)6AAFF3B7B596E76E13FA3735E24CEACE
your IP216.73.216.209
TLS protocolTLSv1.3

Every value here comes from a request this server actually received — the registration and refresh proofs are verified with crypto.subtle.verify(), not simulated.

WHAT THIS IS

A key the browser can't hand over

Click Start session above. A supporting browser silently generates an ECDSA keypair, keeps the private half somewhere it can't export it from, and hands this server the public half. From then on, the browser has to re-sign a fresh server-issued challenge every few minutes to keep its session cookie alive — the card above is live, and the history log fills in as it happens.

THE PROBLEM IT FIXES

Stolen cookies are how most accounts actually get taken over

Phishing kits and infostealer malware (Lumma, RedLine and the like are built almost entirely around this) don't bother stealing passwords anymore — they exfiltrate the browser's cookie jar. On a normal site that's enough: a session cookie is a bearer token, good for as long as it's valid, and that's typically hours to weeks. Steal one and you own the session, in full, until it happens to expire on its own.

DBSC doesn't stop the cookie from being stolen. It stops the theft from lasting: the cookie can only be renewed by signing a challenge with a private key a secure enclave or TPM never exposes, so a copied cookie has a shelf life instead of a free run. This demo sets that shelf life to 180 seconds so you can watch it run out instead of taking it on faith — a real deployment would use something much longer, minutes to hours, not a demo-friendly few minutes.

THE GAP IT DOESN'T CLOSE

Proof of possession, not proof of every request

DBSC proves key possession at refresh time, not on every request in between. A cookie copied mid-lifetime is still valid until it expires — the private key was never needed to use it, only to renew it. That's why this demo also records the TLS fingerprint (JA4) of the connection that registered each session and compares it against every refresh. A mismatch doesn't prove theft on its own — plenty of devices share a JA4 — but it's a cheap, edge-computed signal worth feeding into bot or session-risk scoring rather than trusting the cookie alone.

TRY IT

Steal your own cookie

Start a session above, then do exactly what an infostealer does: open devtools → Application → Cookies → this site, and copy the value of dbsc_session. Nothing on this page hands it to you — it's HttpOnly, same as it would be on a real login — you have to go get it the way malware would.

Paste it into this, right now, alongside the dbsc_sid value the JSON returned when you started the session, and it works — it's still the current cookie:

curl -s https://dbsc.alpagot.net/protected --cookie "dbsc_sid=<from Start session>; dbsc_session=<paste from devtools>"

One practical gotcha: Chrome revalidates on its own schedule, and in practice that's noticeably faster than the 180s figure below — often under a minute, running quietly in the background whether or not the tab is doing anything. If you take even a short pause between copying the cookie from devtools and running the command, don't be surprised if it's already stale: you're not testing "before rotation" any more, you're testing "after" without meaning to. Copy and run it in the same breath, right after a fresh registered or refreshed line appears in the log above, to reliably catch it while it's still valid.

Now wait — up to 180 seconds, until the history log above shows another refreshed entry — and run the exact same command again, unchanged. It fails: the browser already rotated to a new cookie value behind the scenes, and the copy you're holding doesn't get to renew itself. That's the entire benefit, in one loop.

Run it from a terminal rather than a second browser tab and you get a tell for free: curl's TLS stack has a different JA4 than your browser's, so even the successful call before rotation comes back flagged as a JA4 mismatch — see the gap it doesn't close, above.

UNDER THE HOOD

Compute, but not for the reason you'd guess

Unlike its VCL siblings, this one needed real compute — but not because VCL can't verify a signature. digest.ecdsa_verify() has a jwt digest format built for exactly this, and a P-256 key's fixed ASN.1 prefix makes turning a JWK's raw x/y into the PEM it wants a mechanical BLOB operation, not a JSON parser. The real blocker is state: registration and every refresh need to write — a newly bound key, a just-issued challenge — and have the very next request read that write back within seconds, quite possibly from a different POP. Edge dictionaries and config stores are populated through the control-plane API, not from inside vcl_recv, and even routed around that, updates take on the order of tens of seconds to reach every POP — too slow for a challenge POP A issued to verify on POP B moments later. A KV Store's real-time, globally-consistent read-after-write is the part with no VCL equivalent, and it's Compute-only.

Three honest caveats. Browser support is still rolling out — Chrome on Windows shipped it, macOS is expected later, Firefox's position is undecided — so if the card above never goes green, that's very possibly your browser, not this server. This is a demo for one tab, not a production identity system: no cross-device transfer, no enterprise policy, session termination is the bare minimum (Clear-Site-Data on logout). And this was built in September 2026 against the current draft — header names, the credential-attribute rules, and the refresh cadence are all things the spec could still change before it ships as a Recommendation.

0origin servers
ES256the only algorithm this demo accepts
180scookie lifetime before a refresh is required
everyFastly POP can verify one
WHO BUILT THIS

Richard Alpagot

Senior Cloud Engineer at Fastly.