Security model
The design goal, stated bluntly: you should not have to trust this service. Here is what that means, and where its limits are.
What the service cannot do
Every published keyset is signed on your machine by your
identity key, which never touches our servers. Consumers โ the
AuthorizedKeysCommand helper on your servers, the
sshkeys verify command โ check that signature against locally
pinned keys. Therefore, even a fully compromised sshkeys service (or a
malicious operator, or a hijacked network path) cannot:
- add a key to your keyset,
- modify or re-sign any keyset,
- roll your keyset back to an older sequence number (consumers track sequence and refuse rollbacks),
- serve stale data forever โ keysets carry a bounded
valid_until(default 7 days), after which consumers refuse them.
Signatures are standard OpenSSH SSHSIG. You can verify any keyset with
ssh-keygen -Y verify and no software of ours.
What tampering would look like
Every keyset change is appended to a global hash chain; the service signs a checkpoint of the log head after every append. The checkpoint history is public and mirrorable. Consequences:
- A rewritten or forked log produces conflicting signed checkpoints โ cryptographic evidence against the service.
- Serving different keysets to different people ("split view") is detectable by comparing the log head across channels.
- Every change to your keyset triggers an email and webhook to you. An update you didn't make is your compromise alarm.
- Revocations are permanent history. A key that was revoked stays visibly revoked in every subsequent keyset.
What you do still trust us with (stated honestly)
The service can refuse service (availability), can serve stale-but-unexpired keysets within their validity window, and the profile decorations โ identity badges, possession and attestation checkmarks โ are service attestations, not user-signed data. The transparency log in its current version makes dishonest operation detectable and evidenced, not impossible. The full analysis, including residual risks, lives in the threat-model document in the source repository.
Your side of the bargain
- Your identity key is the root of your trust. Keep it offline or hardware-backed; rotation requires cross-signing with the old key.
- Servers should pin identity keys (
trust.pinned_file) and usefail_policy=cachedorclosedโ neveropenin production. - Watch your own handle:
sshkeys watch you --oncein cron, or rely on the change emails.
Reporting a vulnerability
Email [email protected]. You'll get an acknowledgement within 72 hours. We ask for up to 90 days of coordinated disclosure and give public credit unless you prefer otherwise. Most valuable to us: signature-verification bypasses, transparency-log integrity issues, proof-of-possession or rotation bypasses, and anything that makes the sshd helper admit an unauthorized key.