How I built 1208.sh, a Keybase-style identity page with Bitcoin as the notary
If you were online around 2016, you probably remember Keybase. You linked your Twitter, your GitHub and your website to one cryptographic key, and anyone could check that all those accounts belonged to the same person. Keybase made the idea popular, and other projects kept it alive: Keyoxide does it with plain OpenPGP, and Adam Newbold built proven.lol around the same concept.
This one started at work. I wanted something like proven.lol for my company: a page where clients could confirm that a domain, a profile or a PDF really came from us. While sketching it, I kept thinking about my own scattered online life. More than twenty domains, Mastodon, Bluesky, GitHub, Flickr, Lobsters, Hacker News. So I forked the idea for myself, and it became 1208.sh.
It was a lot of fun to build. Part of the fun was the look. I didn't want another dashboard, so the page is designed like a certificate, with a guilloché rosette, blue verification seals and a pen-style signature. The other part was the plumbing, and most of the plumbing is about time: who signed what, and when.
How it works #
One key. Everything hangs on a single OpenPGP key. The key lists my accounts and domains inside itself, in the same notation format Keyoxide reads. Each of those places points back to the key: a TXT record on every domain, a line in a profile bio, a public gist. A claim only counts when both directions agree.
A chain of signed records. Each time I publish, a small program writes a JSON record with the list of claims, the official addresses of the site and a summary of every signed document. I sign it with the key, and it carries the hash of the previous record. The records form a chain, so changing an old one breaks every record after it.
Bitcoin as the clock. A signature proves who, but not when. Anyone can sign something today and say it was last year. So every record goes to OpenTimestamps, a free public service that bundles many hashes into a single Bitcoin transaction. Once that transaction is in a block, there is a proof that this exact file existed before the block was mined. Nobody can backdate it, me included. My first record landed in block 971,542.
Documents. The same machinery signs files: a PDF, an MP3, a contract. The program puts the file's SHA-256 fingerprint into a Merkle tree, and the root of that tree goes into the signed record. Public files can be downloaded from the site. Private ones never leave my computer, and only the fingerprint is published. If someone hands you a file and says it came from me, you drop it on the page and your browser tells you whether I signed it, and when.
The tools. Go for the site generator and the command line. openpgp.js and a few hundred lines of plain JavaScript for the checks in the browser. Static files served by nginx from a small Linux server. Every hour a routine collects the finished Bitcoin proofs and rebuilds the site; once a day it re-checks every account. Every night a copy of the code, the records and the public files goes to GitHub, and I only get an email when something serious breaks. For signing I wrote a tiny Windows app: right-click a file, send it to the signer, choose public or private, type the key's passphrase. It also writes signed statements and registers projects with the exact commit they were at.
Why you can trust it without trusting me #
The page is built so you don't have to believe the page. Press the check button and your browser, not my server, redoes every step:
- it downloads the public key and verifies the signature of the latest record;
- it visits each account and domain to see that the proof is still there;
- it follows the OpenTimestamps proof up to the Bitcoin block and compares that block with two independent explorers, mempool.space and blockstream.info;
- it confirms that the address you are on is listed inside the signed record, so a copy of the site on another domain can't pass as the real one.
If anything fails, the seal turns red and the page tells you what broke. The only thing you need from outside is the key fingerprint, and that is printed on every one of my profiles. A forger would have to take over all of them at the same time.
It has limits, and I'd rather say them. It proves that one person controls the key and all those accounts, and that each record existed at a certain moment. It doesn't prove what is written on my ID card. And if my key were ever stolen, I would have to revoke it, as with any key-based identity.
Come and poke at it #
The site lives at 1208.sh and at prova.pablomurad.com; both switch to Portuguese for visitors from Brazil. Press the button, watch the seals turn blue, go to the Documents page and drop a file to see what happens. If you use Keyoxide, you'll find the same claims there, because it is the same key. There is also an Atom feed if you want to follow new signed records.
And if you build something like it for yourself, send it my way. I'd like to see it.