sshkeys

SSH keys people can actually verify.

Publish your public keys at a memorable URL — signed by you, logged forever, servable straight to your servers. The service can't forge your keys, and can prove it.

Publish your keys Self-host it
$ curl sshkeys.io/paul.keys
ssh-ed25519 AAAAC3NzaC1lZDI1... paul/work-laptop

$ sshkeys verify paul
✓ keyset signature valid: identity SHA256:mUzT4i… (matches pinned key)
✓ keyset sequence 42, valid until 2026-07-25
✓ recorded in transparency log (entry 121, 7 total changes)
✓ log checkpoint signed by service (seq 121)
✓ github identity verified: paulm
✓ devopsteam.io verified via DNS
✓ private-key possession verified
✓ hardware-backed key attested

work-laptop      ED25519      active     SHA256:Yp3lz…
old-yubikey      ED25519-SK   revoked 2026-06-12 (device-retired)

Why not just github.com/you.keys?

GitHub's endpoint serves your uploaded keys, and that's all it does. Everything that makes keys trustworthy is missing:

github.com/you.keyssshkeys
Serve public keys at a URL
Proof-of-possession (challenge signed with the private key)
Keysets signed end-to-end by your key
Revocation with permanent public history— (silent deletion)
Append-only transparency log + signed checkpoints
Key expiry
FIDO2 hardware attestation
DNS / domain verification
sshd integration with local signature verification
Self-hostable

How it works

  1. Create your identity key — locally.
    sshkeys login && sshkeys init
    An ordinary SSH key that signs your published key list. It never leaves your machine — the service physically cannot sign on your behalf.
  2. Publish a key — with proof you hold it.
    sshkeys publish ~/.ssh/id_ed25519.pub --label work-laptop
    The CLI signs a server challenge with the new key (via ssh-agent, so hardware keys work), your identity key signs the updated keyset, and the change lands in the transparency log.
  3. Use it anywhere.
    curl sshkeys.io/you.keys        # plain OpenSSH lines
    sshkeys sync you server1        # verified install over ssh
    sshkeys verify you              # the full trust panel
    Signatures are standard OpenSSH SSHSIG — verifiable with ssh-keygen -Y verify, without our software.

For your servers

The AuthorizedKeysCommand helper resolves login keys from sshkeys with the paranoia your sshd deserves: it verifies keyset signatures locally against pinned identity keys, serves from cache first (a warm cache never touches the network on the login path), refuses sequence rollbacks, and has explicit fail policies. A fully compromised sshkeys service cannot admit anyone to your machines.

AuthorizedKeysCommand /usr/local/bin/sshkeys-akc %u
AuthorizedKeysCommandUser sshkeys

Prefer no daemon in the login path? Render static authorized_keys from the same verified keysets with sshkeys sync, Ansible, or Terraform — patterns in the docs.

Revocation is history, never deletion

Every keyset change is recorded in an append-only hash chain with service-signed checkpoints. A revoked key stays visibly revoked, forever. Every change triggers an email and webhook to you — if your keyset changes and it wasn't you, that's your alarm. Anyone can mirror the checkpoint history: a rewritten log produces signed evidence against us.

Self-host in one command

The hosted service runs the same open code you can run yourself: one Go binary, one SQLite file. Your keys, your trust root, your infrastructure.

docker run -p 8080:8080 -v sshkeys-data:/data \
  -e SSHKEYS_BASE_URL=https://keys.example.com sshkeys
Publish your keys Read the security model