SSH Certificates: The Login Upgrade I Wish I Used Before My Homelab Got Messy
Stop copying SSH public keys to every VPS and homelab box. SSH certificates give you short-lived access, cleaner revocation, and one sane trust model for your servers.
I used to manage SSH access the lazy way: generate a key on my laptop, paste the public key into authorized_keys, repeat forever.
It worked fine when I had two servers. Then the homelab became five machines, a couple of VPS boxes, one emergency jump host, and an old mini PC I kept forgetting existed. Suddenly I had keys everywhere, old laptops with stale access, and no clean answer to the question: βwhat happens if I need to revoke this quickly?β
That is where SSH certificates clicked for me.
Not TLS certificates. Not browser certificates. SSH has its own certificate system built into OpenSSH, and it is ridiculously useful for self-hosters once you get over the slightly scary first setup.
The short version
SSH certificates let your servers trust a certificate authority instead of trusting every individual public key.
You create one signing key β your SSH CA. Each server trusts that CA. When you want to log in, you sign your normal SSH public key with the CA and give it a short lifetime, like eight hours.
Your server sees:
- this key was signed by my trusted CA
- it is valid right now
- it is allowed to log in as this user
- it has not expired yet
Then it lets you in.
Honestly, this is cleaner than stuffing authorized_keys with keys from every laptop, desktop, phone, backup machine, and βtemporaryβ workstation that somehow lives for three years.
Why bother?
If you only have one Raspberry Pi under your desk, SSH certificates are probably overkill. Keep your SSH key, disable password login, and go outside. You win.
But if you run multiple servers, SSH certificates solve a few annoying problems:
- No more copying user keys to every host
- Short-lived access by default
- Cleaner offboarding when a device is lost
- One trust anchor instead of twenty random keys
- Better auditability with certificate IDs
The big one for me was expiration.
With normal SSH keys, access lasts until you remember to remove it. And I do not trust future-me to remember anything. SSH certificates let me issue access that dies automatically.
That is the whole security vibe I want in a homelab: safe defaults for when I get distracted by something shiny.
πNordVPN
Secure your server with a reliable VPN.
Affiliate link β we may earn a commission at no extra cost to you.
What we are building
We will set up a simple SSH certificate authority, configure one server to trust it, sign a user key, and log in using the certificate.
This is the minimal useful version. No HashiCorp Vault. No Smallstep. No SSO portal. Those are great later, but I like understanding the boring OpenSSH version first.
You need:
- one local machine you trust
- one Linux server with OpenSSH
- sudo access on that server
- about 30 minutes where you are not also debugging DNS
Fair warning: guard the CA private key carefully. If someone gets it, they can sign SSH access unless you have additional controls. I keep mine offline in an encrypted folder and only use it when issuing certs.
Step 1: Create your SSH CA key
On your admin machine, create a dedicated folder:
mkdir -p ~/ssh-ca
cd ~/ssh-ca
Now generate the CA key:
ssh-keygen -t ed25519 -f ssh_user_ca -C "homelab ssh user ca"
Use a strong passphrase. Yes, it is slightly annoying. That annoyance is the point.
You now have:
ssh_user_ca # private signing key - protect this
ssh_user_ca.pub # public CA key - safe to copy to servers
Do not put ssh_user_ca on your VPS. Do not put it in a Git repo. Do not leave it in your downloads folder like a raccoon with root access.
Step 2: Tell a server to trust your CA
Copy the public CA key to your server:
scp ~/ssh-ca/ssh_user_ca.pub [email protected]:/etc/ssh/user_ca_keys.pem
On the server, lock down the permissions:
sudo chown root:root /etc/ssh/user_ca_keys.pem
sudo chmod 644 /etc/ssh/user_ca_keys.pem
Now edit /etc/ssh/sshd_config and add:
TrustedUserCAKeys /etc/ssh/user_ca_keys.pem
Before restarting SSH, test the config:
sudo sshd -t
If that returns nothing, you are good.
Restart SSH:
sudo systemctl reload ssh
Keep your current SSH session open while testing. I have locked myself out enough times to treat this as a religious rule.
Step 3: Sign your user key
Back on your admin machine, sign your normal SSH public key.
If your regular key is ~/.ssh/id_ed25519.pub, run:
ssh-keygen -s ~/ssh-ca/ssh_user_ca \
-I "sam-laptop-2026-06-15" \
-n sam \
-V +8h \
~/.ssh/id_ed25519.pub
What those flags mean:
-spicks the CA private key-Isets a certificate identity for logs-n samallows login as the Linux usersam-V +8hmakes the certificate expire in eight hours
OpenSSH creates a certificate beside your key:
~/.ssh/id_ed25519-cert.pub
Your private key did not change. The cert is just a signed permission slip attached to it.
Step 4: Log in with the certificate
Try logging in:
ssh [email protected]
OpenSSH usually auto-detects id_ed25519-cert.pub when it sits beside id_ed25519.
If you want to be explicit:
ssh -i ~/.ssh/id_ed25519 \
-o CertificateFile=~/.ssh/id_ed25519-cert.pub \
[email protected]
To inspect the certificate:
ssh-keygen -L -f ~/.ssh/id_ed25519-cert.pub
You should see the key ID, valid principals, signing CA, and validity window.
This command is weirdly satisfying. It turns SSH access from βI hope I remember what key this isβ into an actual object you can inspect.
Step 5: Remove old authorized keys carefully
Once certificate login works, you can start cleaning up ~/.ssh/authorized_keys on the server.
Do this slowly. Leave one emergency key in place until you have tested from a second terminal and maybe a second network.
My usual order is:
- Enable CA trust
- Sign my key for a short window
- Test login
- Test sudo
- Open a second session
- Remove stale keys
- Keep one break-glass key somewhere boring and documented
The break-glass key is not elegant, but neither is driving home because you made your own server too secure from a coffee shop.
A better config for daily use
You can make your local SSH config less ugly:
Host homelab-vps
HostName server.example.com
User sam
IdentityFile ~/.ssh/id_ed25519
CertificateFile ~/.ssh/id_ed25519-cert.pub
Then:
ssh homelab-vps
When the cert expires, login fails. You sign a new one and move on.
For my own servers, I like short windows:
+8hfor normal admin work+1hfor risky maintenance+7donly for travel, and only if I really need it
Short-lived credentials feel annoying for about a day. Then you realize expired credentials are silent little bodyguards.
What about revocation?
Expiration handles most of the mess. If certs only live eight hours, you often do not need emergency revocation.
But you can revoke certificates with a Key Revocation List. Create a KRL:
ssh-keygen -k -f revoked.krl ~/.ssh/id_ed25519-cert.pub
Copy it to the server:
scp revoked.krl [email protected]:/etc/ssh/revoked.krl
Then add this to /etc/ssh/sshd_config:
RevokedKeys /etc/ssh/revoked.krl
Reload SSH again after testing config:
sudo sshd -t
sudo systemctl reload ssh
For a small homelab, I mostly rely on short lifetimes. For teams or shared infrastructure, KRLs matter more.
Where a VPN still fits
SSH certificates improve authentication. They do not hide SSH from the internet, protect you from sketchy Wi-Fi, or replace network-level access control.
My preferred setup is layered:
- SSH exposed only where needed
- firewall rules as tight as possible
- SSH certificates for short-lived login
- VPN for admin work from untrusted networks
- monitoring for failed login noise
If your SSH port is reachable from a hotel network, a VPN is still worth using. Certificates are not magic armor; they are one very good lock.
πNordVPN
Secure your server with a reliable VPN.
Affiliate link β we may earn a commission at no extra cost to you.
The mistakes I made
My first mistake was signing certificates for too long. I started with 30 days because I did not want the hassle.
That completely missed the point.
If a cert lasts a month, it behaves a lot like a normal SSH key with extra steps. The real win is issuing access for the task in front of you, then letting it die.
My second mistake was keeping the CA key too available. Convenient, yes. Smart, no. Now it lives in an encrypted location and I only mount it when signing.
My third mistake was not setting clear certificate IDs. Use useful names like sam-laptop-2026-06-maintenance, not test. Your logs will be much nicer when something weird happens.
Should you use this?
Use SSH certificates if you have more than a couple of servers, multiple admin devices, or the creeping feeling that your authorized_keys files have become archaeology.
Skip it if your setup is tiny and you are still learning SSH basics. There is no shame in simple.
But if you already self-host serious stuff β password managers, email, monitoring, Git, backups β this is one of those upgrades that makes the whole setup feel more grown up. Not enterprise cosplay. Just cleaner, safer access.
Start with one non-critical server. Sign a cert for eight hours. Log in. Let it expire. Once that feels normal, roll it out to the rest of your fleet.
Future-you will appreciate not having to grep through six servers wondering which forgotten laptop still has the keys to the kingdom.
Stay in the loop π¬
Get self-hosting tutorials, tool reviews, and infrastructure tips delivered to your inbox. No spam, unsubscribe anytime.
Join 0 self-hosters. Free forever.