Trust Model
- The hub root CA establishes the root of trust
- Each satellite intermediate CA is signed by the corresponding hub root
- Satellite-local components can then issue and rotate agent certificates without breaking the trust chain back to the hub
Certificate Lifetime
The current runbook issues CA certificates for 10 years:- agent certificates can be rotated by
cert-manager - the CA lifetime is intentionally long until there is a better mechanism for distributing satellite CA certificates
Generate the Hub Root CA
Create the root CA and upload it to the hub vault:Generate a Satellite Intermediate CA
Read the hub CA from 1Password, generate the site CA, and upload it to the satellite vault:tls.crt/tls.key into the cert-manager Issuer Secret; the item’s ca.crt is kept as a record of the signing chain and is not read by anything on the satellite.
Rotate the Hub Root CA
Use this when the root key may have been exposed or on a planned rotation. The API trusts every root in theca.crt field of the hub pki-ca item (a PEM bundle), so the rotation is rolling: trust both roots, move issuance to the new one, reissue every client, then drop the old root. Removing the old root is the only revocation the API offers, so the sequence matters more than the speed.
- Gate: bundle-aware API everywhere. Every API replica in the environment must run a build that loads the trust file as a bundle. An older build loads only the first certificate, so the bundle order below is not optional.
- Mint the new root offline.
fleetctl infra certs root-ca --cn "Fleet Manager Root CA" --days 3650 --output-dir ./new-rootproducesca.crt/ca.key. The root key is used only by thesignstep below and then lives in 1Password; it never lands on an Issuer. - Trust both, hub first.
fleetctl deployment-standup onepassword pki-ca-root trust <env> --new-root ./new-root/ca.crtappends the new root to the hubpki-cafieldca.crt, existing roots first, and skips anything already present. Pass--also-trust <pem>for a partner root that must be trusted alongside (for example UNI’s own client-certificate root).tls.crt/tls.keyare untouched. Force-sync the hubpki-ca-trustExternalSecret (the trust bundle syncs into its own Secret; the Issuer’spki-caSecret carries only the signing pair) and confirm on every API replica that/etc/fleet-manager/certs/ca.crtholds every root, that thefleet_manager_api_trusted_ca_rootsgauge matches, and that the API log showstrusted CA bundle loaded: N root(s)with no bundle warnings. The API re-reads the file on change, no restart. - Switch issuance.
pki-ca-root sign <env> --new-root ./new-root/ca.crt --new-root-key ./new-root/ca.keymints a hub intermediate signed by the new root and replaces hubtls.crt/tls.key; it refuses until the new root is inca.crt. Thenpki-ca <satellite> <env> --rotateonce per satellite re-mints that satellite’s intermediate from the hub item and replaces itspki-cafields in place. External issuers that hold a copy of the CA (for example UNI’sreservations/fm-client-ca) receive their own CA material at this point. - Reissue every client. cert-manager does not reissue a leaf when its Issuer’s Secret changes. Force renewal of every Certificate in
deployment/charts/hub/templates/*/certificate.yaml,deployment/charts/satellite/templates/*/certificate.yamland any out-of-cluster client, then prove each new leaf cryptographically against the new root, not by issuer name (a re-minted CA can keep the same subject):openssl verify -CAfile new-root.pem leaf.pemfor hub leaves,openssl verify -CAfile new-root.pem -untrusted intermediate.pem leaf.pemfor satellite leaves, and the same command withold-root.pemmust fail. Then authenticate once against the API with each client class (a hub agent, a satellite agent, CHAD, an out-of-cluster client) and confirm a token is issued. Re-copy hand-distributed leaves into 1Password and reload their consumers. - Prove, then revoke. Only when every leaf on the inventory verifies against the new root and fails against the old one, and every client class has authenticated with its new chain, run
pki-ca-root revoke <env> --keep-fingerprint <sha256>once per root that must remain (thetruststep logs every fingerprint; a prefix works only while it matches exactly one root, and the roots share a subject so fingerprints are the only handle). The command checks the signature, not the subject, and refuses to drop the root that signed the current hubtls.crt. Wait one access-token lifetime before declaring the rotation complete: a client still holding a token issued under the old root fails only when it next authenticates.
ca.crt, and a new-root leaf issued in step 5 will fail against that build, so roll back leaves before rolling back the API. After step 6, re-adding the old root re-trusts a compromised key; the fix for a missed client is to reissue it, not to restore the root.
Operational Notes
ENVshould match the environment name used for the target hub and satellite vaultsNAMEshould match the satellite deployment identifier, such asglo1orsta1- PKI setup is a prerequisite for bringing a new satellite online in the published deployment flow