← Harden & defendssh certificates replace authorized_keys sprawl

ssh certificates replace authorized_keys sprawl

$ssh-keygen -s ca_key -I andres -n andres -V +8h user_key.pub

the authorized_keys mess you already have

go check your servers right now. actually do it. how many public keys are sitting in ~/.ssh/authorized_keys across every box you manage. now ask yourself who those keys belong to, whether that contractor from eight months ago still has access, and whether anyone would even notice if one of those keys got copied somewhere it shouldn't be. that's the problem. authorized_keys files are permanent by default, they live forever unless someone remembers to clean them up, and nobody remembers.

the fix is a certificate authority, not more keys

ssh has supported its own certificate system for years and almost nobody uses it, which is a shame because it solves exactly this problem. instead of every server trusting a pile of individual public keys, every server trusts one thing: a CA public key. when someone needs access, you sign their key with the CA, the signature has an expiration baked in, and the server checks the signature instead of hunting through a list of keys.

this flips the model. access isn't "is this key on the list" anymore, it's "was this key vouched for by the CA, and is that vouch still valid." revoking access for a person doesn't mean editing files on forty servers, it means you stop signing new certs for them and their old ones expire on schedule anyway.

breaking down the signing command

ssh-keygen -s ca_key -I andres -n andres -V +8h user_key.pub

here's what each piece is actually doing:

-s ca_key tells ssh-keygen which CA private key to sign with. this file is the crown jewels, it's what every server trusts, so it should live somewhere protected, ideally not on your laptop.

-I andres sets a key identifier. this is just a label that shows up in logs, so when you're digging through auth logs later you can actually see whose cert did what instead of guessing from a hash.

-n andres sets the principal, which is the username this cert is allowed to log in as. servers can be configured to only accept certs with a matching principal, so this is where you actually restrict who the cert works for.

-V +8h is the part that matters most. it sets the validity window, in this case eight hours from signing. after that, the certificate is dead weight. no revocation list needed, no ticket to file, it just stops working.

user_key.pub is the public key getting signed, belonging to whoever is requesting access.

on the server side, you just need one line added:

echo 'TrustedUserCAKeys /etc/ssh/ca.pub' >> /etc/ssh/sshd_config

that tells sshd "trust anything signed by this CA," and now that server never needs to have its authorized_keys file touched again for normal access.

what this actually protects you from

the real win here is blast radius. with scattered keys, a laptop compromise means someone has a valid key that works until you manually find and remove it everywhere it was added, and "everywhere" is the scary part because you probably don't have a full inventory. with short lived certs, a stolen laptop only grants access for the remaining hours on the cert, and if you stop signing new ones the moment you notice, the exposure window closes itself.

it also kills the "former employee still has SSH access" problem, which shows up in incident postmortems constantly. offboarding becomes "remove them from the signing process," not "audit every server for their key."

how to actually protect your systems

start small. pick one non critical box, generate a CA keypair, add the TrustedUserCAKeys line, and sign yourself a cert with a short validity window to test the login. once that works, roll it out server by server, and as you do, go delete the old entries in authorized_keys, don't leave them as a silent backdoor next to your shiny new cert system. protect the CA private key like it's a root password, because functionally it is one, keep it offline or behind hardware backed storage if you can. and set your validity windows short on purpose, force yourself to re sign often, that friction is the point.

the takeaway

authorized_keys sprawl isn't a hypothetical risk, it's just accumulated debt that quietly grows every time someone gets access and nobody circles back to remove it. ssh certificates turn access into something with a built in expiration date instead of something you have to remember to clean up. one CA, one trust decision per server, and every login time boxed by default. that's not a fancy feature, that's just how access control should have worked from the start.

watch the reel ↗
the weekly drop

one command a week that makes you harder to hack.

a single tool, explained in plain english, every week. straight to your inbox.

no spam. one email a week. unsubscribe anytime.