Back in March I wrote about moving my PGP key off a keyserver and onto my own domain. WKD is great. It’s also only as good as your domain, your server, and your nginx config at 2am.

So I built the other half. keys.thurin.id is a keyserver with no database. Every key it serves is read straight off Ethereum, at the moment you ask for it.

Try it:

gpg --keyserver hkps://keys.thurin.id --search-keys benwoodall.eth

That’s my key. Found by my ENS name, served by a keyserver that doesn’t store it.

How it works

Thurin.id lets you put your PGP key on your Ethereum address: a signed claim in a contract that has no owner, no admin, and no upgrade button. The key lives on-chain. So does a signature from that key saying “I control this address.”

When gpg asks keys.thurin.id for a key, the server looks up the claim on Ethereum, checks that the signature holds and the claim is still active, and hands back the key. Nothing is kept between requests except a two-minute cache.

It speaks plain HKP, the same protocol keyservers have spoken for decades, so gpg doesn’t know anything is different. You can look a key up by:

  • fingerprint or key ID
  • ENS name
  • Ethereum address

Not by email. That’s on purpose. Emails stay off the chain unless you choose to publish one, and I’d rather a search for your address come up empty than turn the keyserver into a spam list.

Nothing to flood

In 2019 someone flooded a couple of well-known keys on the old SKS network with tens of thousands of junk signatures, and gpg choked trying to import them. The network never really recovered. Anyone could add anything to anyone’s key, and nobody could take it off.

Here nobody can. The server has no upload. The only way to change a key is a transaction from the address that owns the claim. Nobody else can add a thing to your key, so there’s nothing for a stranger to pile onto.

And when an owner revokes their claim, the keyserver stops serving that key. Refresh your keyring and it’s gone.

Don’t trust me either

This is the part I care about most. keys.thurin.id is a convenience, not an authority. The same thing runs anywhere:

npx @thurinlabs/thurin keyserver --rpc http://127.0.0.1:8545

Point it at your own Ethereum node and you get the same answers without asking me anything. My server keeps no access logs, never records IPs, and doesn’t write down what you searched for. But you shouldn’t have to take my word for that, and with your own copy you don’t.

A few honest limits:

  • A keyserver only knows what the node tells it. Mine asks a public node by default. For anything that matters, run your own.
  • An ENS name can be pointed somewhere else. If you know the fingerprint, use the fingerprint.
  • Putting a key on Ethereum costs gas. At quiet times that’s cents, and your first claim can be sponsored.
  • Any keyserver, mine included, could hold back a revocation. Your own copy can’t.

Why bother

PGP keyservers were supposed to be the phone book for encryption. They ended up being someone else’s database, until they got flooded or shut down or started dropping names.

A keyserver whose database is a public chain doesn’t have that problem. There’s no box to seize, no table to corrupt, and no company deciding what to keep. If keys.thurin.id disappears tomorrow, every key is still there, and anyone can stand up a new one in a minute.

Old trust, new ground.

Want your key on it? Claim it at thurin.id/attest, or check how any of this works in the docs. Questions and pushback: benwoodall.eth, or my Thurin.id page.