Unit 4: Users and groups · Lesson 7 of 7 · 20 min

SSH certificates instead of key sprawl

Sign short-lived certificates with a CA so access expires on its own and nobody edits authorized_keys again.

mission

You are
You are piloting SSH certificates for web01.
Situation
dana's authorized_keys still trusts a key from a 2019 CI job. With certificates, the server trusts one CA and every login key expires.
Goal
Count the keys trusted today, then issue an eight-hour certificate and read it.
Hand in
A certificate for learner, valid for one working day.
01

Inventory today's trusted keys

learner@root-lab
for f in /home/*/.ssh/authorized_keys; do echo "$f $(grep -c . $f)"; done 2>/dev/null
/home/dana/.ssh/authorized_keys 2
ssh-keygen -l -f /home/dana/.ssh/authorized_keys | awk '{print $NF, $(NF-1)}'
(ED25519) dana@laptop
(ED25519) deploy@ci-2019

you should see Two keys for dana, one of them from a CI job in 2019. Nobody could tell you if it is still needed.

02

Create a CA and a user key

In real life the CA key lives in a vault or HSM, not in a home folder.

learner@root-lab
mkdir -p ~/ssh-ca && cd ~/ssh-ca
ssh-keygen -q -t ed25519 -N '' -C 'web01 user CA' -f user_ca
ssh-keygen -q -t ed25519 -N '' -C 'learner laptop' -f learner_key
ls
learner_key
learner_key.pub
user_ca
user_ca.pub

you should see Two key pairs.

03

Sign a one-day certificate

-n sets who the certificate may log in as. -V sets the validity window.

learner@root-lab
ssh-keygen -s user_ca -I learner-2026-10-22 -n learner -V 20261022:20261023 learner_key.pub 2>&1 | sed 's/ for .*//'
Signed user key learner_key-cert.pub: id "learner-2026-10-22" serial 0
ssh-keygen -L -f learner_key-cert.pub | grep -E 'Key ID|Valid|Principals' -A1 | grep -v '^--'
        Key ID: "learner-2026-10-22"
        Serial: 0
        Valid: from 2026-10-22T00:00:00 to 2026-10-23T00:00:00
        Principals:
                learner

you should see Valid for one day and only as learner.

04

Tell sshd to trust the CA

On the server this is one line in sshd_config, plus copying user_ca.pub to the path it names. After that, authorized_keys files can go.

you should see TrustedUserCAKeys /etc/ssh/user_ca.pub

Two ways to grant access

authorized_keys
~dana/.ssh/authorized_keys
ssh-ed25519 ... dana@laptop
ssh-ed25519 ... deploy@ci-2019

Keys never expire and pile up per user

Certificates
TrustedUserCAKeys /etc/ssh/user_ca.pub
cert: learner, valid 2026-10-22 only

One CA to trust, every login expires

What a defender takes away

  1. 1Inventory authorized_keys on every server.
  2. 2Certificates expire, keys do not.
  3. 3Protect the CA key like the keys to every server, because it is.

Questions

0 of 3 solved

Answer each one from what you find on your lab machine.