PKI Manager v3.0.0
Major release adding a complete SSH Certificate Manager — issue, manage, and revoke OpenSSH host and user certificates from a KMS-backed dual CA, fully integrated into the existing React UI, tRPC, REST/OpenAPI, and Cosmian KMS. Every layer is validated byte-for-byte against real OpenSSH (ssh-keygen + a live sshd).
SSH certificates turn trust management from O(N×M) into O(N+M) — adding expiry, principal-based RBAC, least-privilege restrictions, and a human-attributable audit trail.
🔑 Dual SSH CA (KMS-backed, non-exportable)
- Separate User CA + Host CA, ECDSA nistp256, generated non-exportable in the Cosmian KMS (
Sensitive=true); signing via KMIPSignso the CA private key never leaves the KMS. - Pure-TypeScript OpenSSH certificate encoder (PROTOCOL.certkeys) and KRL encoder — byte-identical to
ssh-keygen. Nosshpk/ssh2dependency. - Import an existing CA, plus CA rotation with dual-trust overlap (both keys published until old certs expire).
🖥️ Host & user certificates
- Host certificates eliminate TOFU (
known_hostschurn); user certificates eliminate per-hostauthorized_keys. - Principal-based RBAC catalog → renders
AuthorizedPrincipalsFilemappings. - Least privilege baked into the cert: extension whitelist (
permit-pty, …) and critical options (force-command, validatedsource-addressCIDRs), via a friendly capability editor. - Short TTLs as the primary revocation mechanism (+1w users, +52w hosts); host-only clock-skew backdate.
- Bulk renew/revoke; host & user offboarding in one action.
🚫 Revocation & KRL distribution
- Native OpenSSH KRL build (validated by
ssh-keygen -Q) signed by the CA key. - Public bare KRL served for
RevokedKeyswithETag/If-None-Match/304/lazy-regen (honest trust model — sshd does not verify KRL signatures; integrity = TLS +0444perms). - Per-host ECIES-encrypted KRL distribution (KMIP
Encrypt/Decrypt) so the revocation set stays private — with a host-side systemd puller (services/krl-distributor/).
🔌 APIs & automation
ssh.*tRPC namespace + REST under/api/v1/ssh(Zod → OpenAPI, in the same Swagger), with fail-closed authz when OIDC is disabled.- Public trust-material downloads (
TrustedUserCAKeys,@cert-authority, sshd drop-ins). - Fleet-token automation API (
/api/v1/external/ssh/*) — SHA-256-hashed tokens scoped to a CA pair, idempotent signing — driven by a new Ansiblessh_host_certrole.
🖼️ Operator console
- Grouped SSH section: CAs, Hosts, Users, Principals, Revocation/KRL — with config-snippet generators, a live
ssh-keygen -Lpreview, and dashboard tiles.
✅ Validation
- End-to-end harness against a real
sshd(PoC UC3–UC9): no-TOFU host login, user-cert auth, principal RBAC, PTY denial, force-command, expiry, KRL revocation. 500+ backend tests green.
📋 Process
- 41-task milestone with 4 decision records (signing approach, data model, KRL distribution, baseline) and an API contract doc.
Merged on top of v2.0.0 (Kubernetes cert-manager external issuer + CRL signing). No changes to existing X.509 behavior.