authn-revokd
OpenSSH has no way to distribute a KRL, and nothing in a KRL says it is
stale. sshd reads a file that stopped updating months ago as the current
list. authn-revokd closes both gaps for the lists
authn-bridge publishes: it
fetches each list, keeps it only if it verifies, writes it where sshd or a TLS
server reads it, and, when a list lapses, writes one that revokes the CA
itself. Pure Go, CGO_ENABLED=0, one binary. These pages describe v0.6.4.
$ go install github.com/go-authn/revocation/cmd/authn-revokd@v0.6.4
$ authn-revokd -version
authn-revokd v0.6.4
$ authn-revokd -help
Usage of authn-revokd:
-config string
the configuration file (default "/etc/authn-revokd/revokd.hcl")
-once
sync once and exit: 1 when a list is not current, or could not be fetched
-version
print the version and exit-help exits 0; before v0.6.2 it exited 2.
Before v0.6.0 the command was revokd, and read /etc/revokd.hcl by default.
Nothing reads that file any more; when it is there and the new default is not,
the error names both paths.
What it does, in one run
Against a test authn-bridge on loopback, with a KRL source and a CRL source:
$ authn-revokd -config revokd.hcl -once
bridge-ssh: version 0, issued 2026-10-11T09:50:24Z, expires 2026-10-11T10:50:24Z
bridge-x509: version 1791712224691, issued 2026-10-11T09:50:24Z, expires 2026-10-11T10:50:24Z
output sshd: wrote /tmp/authn/revokd/out/sshd.krl
output tls: wrote /tmp/authn/revokd/out/bridge.crl
$ ssh-keygen -Q -l -f out/sshd.krl
# KRL version 0
# Generated at 20261011T115024
# Comment: authn-revokd sshdA second run with nothing new prints nothing and exits 0: an output is rewritten only when its content changes.
Why the transport does not matter
Every list authenticates itself: a KRL by a detached SSHSIG signature by the CA’s own key, a CRL by its CA’s signature. Every list says when it stops being current. So a list may come over HTTPS, plain HTTP inside a cluster, a mirror, or a file. The transport decides how fast a change arrives, never whether a forged or stale list is taken.
| KRL | CRL | |
|---|---|---|
| authentic | SSHSIG by the SSH CA key, namespace krl@go-authn.github.io | signed by its CA |
| current | expires@go-authn.github.io, which sshd ignores | nextUpdate |
| never backwards | krl_version, then generation date | CRL Number, then thisUpdate |
| fail closed | authn-revokd writes a KRL that revokes the CA key | OpenSSL refuses an expired CRL by itself |
Where to go next
| Installing it | the daemon, or -once on a timer; wiring sshd and nginx |
| The configuration | sources, outputs, the mirror, and what is refused |
| How a list is verified | signature, dates, and never older than the list held, across restarts |
| When a list lapses | the KRL that revokes the CA itself |
What it does not do
A revocation reaches a server no faster than authn-revokd polls (refresh),
plus the issuer’s delay in issuing again. While the issuer is down, its
certificates are refused from the list’s expiry on. Whoever holds a CA’s key can
sign any list, as they can sign any certificate.
Licence
BSD-3-Clause.
Created on by tannevaled
Modified on by tannevaled