voboda's blog

HDK Sessions

The standard session model: user logs in, server stores state, server decides what you're allowed to do.

Structurally incompatible with privacy.

I've been working on something better, called HDK Sessions.

Cookies were the original sin. Once you have a persistent identifier for each browser, building a profile behind it costs nothing. We hoarded data, built profiles, and found ourselves in the surveillance economy. (Lou Montulli built cookies in 1994 so MCI could offload e-commerce state to the browser. But the very first deployment was Netscape's own site tracking returning visitors. Montulli protested when ad networks co-opted the technology. His own employer ignored him, then sold to a media company built on eyeballs. Funny how that worked out.)

So HDK Sessions asks: can we get what we need from server-state but without storing any personal data on the server at all? Authentication, access control, personalisation?

Turns out, yes.

HDK Sessions uses modern cryptography to let users carry their own session state, which is encrypted, tamper-proof, and forgotten by the server the moment each request is done.

But the real win isn't the crypto. It's what you stop storing.

Don't store what the user did:

{ visited: ["/lesson-1", "/lesson-2"] }

Store what they're entitled to:

{ entitlements: ["lesson-3-open"] }

You already know where your access gates are and how you'll assess them. You just do those assessments as they occur rather than historically.

It's actually easier. Even in complex cases, you're composing entitlements rather than doing complex ACLs or database queries prone to edge-case leaks. The instinct to hoard user data is the problem, not the protection. Letting go of what you don't need turns out to simplify everything downstream.

How it works

Your browser generates its own random ID. On each request, it sends that ID, a request counter, and an encrypted blob of your session state.

The server holds one root key. From that key, your ID, and the counter, it derives a unique encryption key for that specific request (using Heirarchical Deterministic Keys), decrypts the blob, processes your request, re-encrypts, and sends the new blob back.

Then forgets. EAch visit is processed once, transiently, to derive the state, then discarded.

Nothing stays on the server. You don't need a database.

The blob travels back and forth in HTTP headers, not a static cookie. You can open DevTools and verify this. No cookies.

And this isn't just cookies with a different header. The architecture centres around proving entitlements and rights that evolve, not collecting personal data.

The big insight I had was that to invert keypairs from the usual sense; the server has the private keys for the encrypted blobs. This allows you to protect the payload from visibility and tampering, making the system behave with the same security properties was ask of cookies and server-side data. But the custody of the data stays with the user. They can delete their own personal data without even asking permission.

HDK Sessions are also just a better technical choice. Beyond privacy, HDK Sessions gives you things the cookie model doesn't:

Where you might still want a database

There are cases where HDK Sessions don't replace server-side storage.

The point isn't that databases are bad. It's that if you're keeping a server database just for session state, you're making your life hard and making privacy hard.

HDK Sessions are for the large class of applications that adopted server-side profiles not because they needed them, but because cookies made them the default.


I've built a SvelteKit library if you want to try it, and you can see it in action at One Line For Your Mind (source). The full design rationale covers the trade-offs honestly — including what this doesn't guarantee.

I'd love to hear your thoughts.