From 01197dd7614cf28d92f937aa59dd1ef33339ee7f Mon Sep 17 00:00:00 2001 From: reachableceo Date: Sat, 5 Sep 2026 17:08:16 -0500 Subject: [PATCH] [#385] SSH CA live on fleet step-ca: user cert issuance + e2e ssh auth PROVEN ED25519 user/host CA keys generated; enableSSHCA on JWK provisioner; 24h root principal cert issued and used to ssh into sectestbed 5104 (passwordless, no static key). Host onboarding = 1 file + reload. Rollout role queued in KNELIAC. Public CA key committed (private keys never leave tsys-ca). https://projects.knownelement.com/issues/385 --- .crush/active-ticket | 2 +- docs/runbook-ssh-ca.md | 45 ++++++++++++++++++++++++++++++++++++++++ ssh-ca/fleet_user_ca.pub | 1 + 3 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 docs/runbook-ssh-ca.md create mode 100644 ssh-ca/fleet_user_ca.pub diff --git a/.crush/active-ticket b/.crush/active-ticket index f8c1dbb..a5941da 100644 --- a/.crush/active-ticket +++ b/.crush/active-ticket @@ -1 +1 @@ -#800 +#385 diff --git a/docs/runbook-ssh-ca.md b/docs/runbook-ssh-ca.md new file mode 100644 index 0000000..b765d61 --- /dev/null +++ b/docs/runbook-ssh-ca.md @@ -0,0 +1,45 @@ +# SSH certificate CA runbook — step-ca on tsys-ca + +> Ticket [#385](https://projects.knownelement.com/issues/385) · parent +> [#697](https://projects.knownelement.com/issues/697)/[#800](https://projects.knownelement.com/issues/800) +> Lane index https://community.turnsys.com/t/297 + +## Live state (2026-09-05) + +- SSH CA enabled on the prod step-ca (same endpoint as ACME: + https://100.102.96.24:8443). Separate ED25519 signing keys: + `ssh_host_ca_key` + `ssh_user_ca_key` (in /opt/stepca-prod/data/secrets, + never leave the host). Public CA: `ssh-ca/fleet_user_ca.pub` in this repo + + artifact mirror. +- Provisioner: JWK `admin` with `claims.enableSSHCA=true`. +- **VERIFIED e2e**: user cert (principal root, 24h) issued and used to SSH + into sectestbed 5104 — passwordless, no static key. PLAYBOOK RECORD in + journal of #385. + +## Host onboarding (one file + one reload) + + install -m 644 fleet_user_ca.pub /etc/ssh/fleet_user_ca.pub + echo "TrustedUserCAKeys /etc/ssh/fleet_user_ca.pub" > /etc/ssh/sshd_config.d/99-fleet-ca.conf + systemctl reload sshd + +Rollout to the fleet = KNELIAC role (queued; sectestbed wave first, then +prod hosts under GLPI CR). + +## Client flow (operators + automation) + + step ssh certificate root-cert ./id_root --principal root \ + --provisioner admin --provisioner-password-file \ + --ca-url https://100.102.96.24:8443 --root fleet-root.crt \ + --not-after 24h + ssh -i ./id_root -o CertificateFile=./id_root-cert.pub root@ + +Better UX once keyed hosts trust the CA: `step ssh login` (agent-managed, +`step ssh` known-hosts propagation via `--ssh` host templates — queued). + +## Hardening TODO (before prod wave) + +- host certificates (`--host`) + sshd HostCertificate so CLIENTS also + verify servers (kills TOFU). +- JWK admin provisioner → per-operator provisioners; automation gets a + dedicated provisioner with restricted principals + short TTLs. +- Enable `--acme-strict-fqdn`-style hygiene: review principals allowed. diff --git a/ssh-ca/fleet_user_ca.pub b/ssh-ca/fleet_user_ca.pub new file mode 100644 index 0000000..7c52bfe --- /dev/null +++ b/ssh-ca/fleet_user_ca.pub @@ -0,0 +1 @@ +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHtlhPfNlm/6bJqPRQv7jsrt1sMUTKgAAwUh0yZCESNU KNEL Fleet SSH User CA