CCAT CA — Provisioner set and reference tables#
This page is reference: lookup tables for the CCAT step-ca
provisioner set, the SSH access tiers, the Ansible role tags exposed
by ca_trust and hsm_host, and the lifetime flags accepted by
step ca provisioner update. For the why behind these numbers, see
CCAT Certificate Authority — Architecture and Design. For the operational procedures (adding,
rotating, removing), see CA provisioner management.
The CCAT provisioner set#
Provisioners are the entry points through which clients request certs
from step-ca. Each provisioner has a type (OIDC, JWK, ACME, SSHPOP, …),
an authentication mechanism, and a set of claims that govern what
kinds of certs it can issue and with what lifetimes. They live in
ca.json inside the step-ca-data volume.
CCAT runs six provisioners. They are installed by the script
step-ca/provisioners-add.sh.
Name |
Type |
Purpose |
Default lifetime |
Max lifetime |
|---|---|---|---|---|
|
OIDC |
Interactive SSH user certs via Dex + GitHub (team-gated) |
16 h |
16 h |
|
JWK |
Production x509 / TLS certs |
90 d (2160 h) |
90 d |
|
JWK |
Staging x509 / TLS certs |
30 d (720 h) |
30 d |
|
JWK |
SSH certs for automated services (Jenkins, ccat_transfer/bbcp, CI) |
24 h |
24 h |
|
ACME |
Auto-TLS for internal services via ACME protocol |
90 d |
90 d |
|
SSHPOP |
SSH host cert auto-renewal (host re-proves by signing with old cert) |
7 d (168 h) |
7 d |
For the rationale behind each lifetime, see CCAT Certificate Authority — Architecture and Design § “Why these lifetimes” and § “What SSHPOP is and why it’s clever”.
SSH access tiers#
Tier |
Primary auth |
Backup auth |
Linux account |
Sudo |
|---|---|---|---|---|
1 — Admin |
|
Nitrokey FIDO2 key in static |
Personal user, |
Yes |
2 — Staff |
|
(none — off by design) |
Personal user |
No, unless opted in case-by-case |
3 — Break-glass |
(none — not reachable via SSH) |
iLO console + password |
|
Yes |
The narrative for what each tier means and how the tiers compose is in CCAT Certificate Authority — Architecture and Design § “SSH access tiers — narrative”.
Ansible role: ca_trust — distribute public trust material#
Applied to: all managed hosts (input_ccat, input_staging,
ccat, eventually travel_hosts).
Responsibilities:
Copy
root_ca.crtinto the RHEL (/etc/pki/ca-trust/source/anchors/) or Debian (/usr/local/share/ca-certificates/) trust store and runupdate-ca-trust/update-ca-certificates.Copy
ssh_user_ca.pubto/etc/ssh/trusted_user_ca_keysand setTrustedUserCAKeysinsshd_config.Register
ssh_host_ca.pubin/etc/ssh/ssh_known_hostswith a@cert-authority *.data.ccat.uni-koeln.deline.Render
/etc/ssh/auth_principals/<user>for every user ingroup_vars/all/users.ymlwith agithub:field, and setAuthorizedPrincipalsFile /etc/ssh/auth_principals/%uinsshd_config. This closes the loop between the GitHub-team authorization gate (enforced at Dex) and which Linux user each certificate is permitted to become on the target host.
Source files for the CA artifacts live in
ansible/roles/ca_trust/files/. The role is a safe no-op until
those files exist — it guards every task on file presence on the
controller and warns if nothing is found. This means the role can be
merged and wired into playbook.yml before the ceremony
without affecting any running host. Principal-file rendering is
gated on ssh_user_ca.pub being present for the same reason: a
principals file without a trusted user CA is meaningless.
How the github: field becomes a working cert path#
The full chain, top to bottom:
github.com: you add the operator to
ccatobs/datacenter.users.yml(this repo): the same operator has a Linux user entry withgithub: <their-github-login>.ca_trustrun:make play-input-ccat T=ca_trust(or the full playbook) renders/etc/ssh/auth_principals/<linux-user>on every target, containing exactly their GitHub login on one line, and ensuressshd_confighasAuthorizedPrincipalsFile.Operator runs
step ssh login: step-cli talks to Dex, Dex checks the GitHub team, step-ca issues a cert whose first principal is their GitHub login (viastep-ca/ssh-user-template.tpl).Operator runs
ssh <linux-user>@target: sshd on target sees the cert, reads/etc/ssh/auth_principals/<linux-user>, matches the cert’s principal list against that file, accepts. Login succeeds.
If any step in the chain is missing, the attempt fails cleanly:
Step 1 missing → Dex rejects at auth time
Step 2 missing → no principals file → sshd falls back to the default “principal must equal username” rule
Step 3 not run → principals file doesn’t exist → same default fallback
Step 4 cert expired → step-cli offers a key, sshd falls back to the key-based path
Step 5 mismatch → permission denied
The chain is designed so a missing link never accidentally grants access: the failure mode is always “cleanly denied,” never “silently promoted.”
Onboarding a new operator#
Confirm they’re in
ccatobs/datacenteron github.com.Add a new user entry to
group_vars/all/users.yml:- user: alice uid: 1002 comment: "Alice Example" groups: "docker,ccat_deploy" password: "{{ vault_user_alice_password }}" github: alice-github
Add
vault_user_alice_passwordto the Ansible vault.Run
make play-input-ccat T=users,ca_trust_principalsto create the Linux user and drop their principals file on all prod hosts. (Or dropT=to apply everything.)Tell them to run
step ca bootstrap+step ssh login, thenssh alice@<host>. The full client onboarding procedure lives in Client setup — SSH with step-ca certificates.
Off-boarding#
Fastest path: remove them from the ccatobs/datacenter GitHub
team. Any new step ssh login fails at Dex. Their current cert
expires within 16h. That’s usually enough.
Belt-and-braces path: also delete the github: field from
their user entry in users.yml and re-run
make play-input-ccat T=ca_trust_principals. The role explicitly
scrubs the stale auth_principals/<user> file on the next run,
so the cert path is closed even if GitHub membership somehow
persists. Add them to users_removed if you also want their
Linux account deleted.
Ansible role: hsm_host — prepare input-b for the HSM#
Applied to: input-b only (inside the - hosts: input-b play in
playbook.yml).
Responsibilities:
Install
openscandopensc-toolspackages on the host.Deploy
99-nitrokey-hsm.rulesudev rule granting theplugdevgroup access to the Nitrokey HSM 2 device node.Run
pkcs11-tool --list-slotsand either warn (default) or fail (when_hsm_enforce_verify: truein host_vars) if the HSM is not detected.
Run standalone:
cd ansible
ansible-playbook playbook.yml --tags hsm_host -l input-b
Sub-tag |
What it does |
|---|---|
|
Install |
|
Deploy |
|
Run |
To make verification strict once commissioning is done (so that an
accidentally-unplugged HSM fails the playbook loudly), create
ansible/host_vars/input-b/hsm.yml with:
_hsm_enforce_verify: true
Lifetime flags for step ca provisioner update#
When updating an existing provisioner’s lifetimes (see CA provisioner management § “Updating lifetimes on existing provisioners”), pass only the flags you want to change:
Flag |
Applies to |
Example |
|---|---|---|
|
x509 certs |
|
|
x509 certs |
|
|
SSH user certs |
|
|
SSH user certs |
|
|
SSH host certs |
|
|
SSH host certs |
|
All durations are passed as Go time.Duration strings — h for hours,
m for minutes. d and w are not supported.
Cross-references#
TLS, Certificates, and Public Key Infrastructure — PKI fundamentals: what a cert is, TLS handshake, root vs intermediate explained from first principles.
CCAT Certificate Authority — Architecture and Design — the design narrative this reference page summarises (provisioner set, lifetimes, GitHub gate, SSHPOP, Pattern A).
CCAT Certificate Authority — Threat Model & Attack Surface — what the cert auth model defends against.
Secrets Management & .env Setup — how the vault pipeline works;
STEP_CA_HSM_PINand the Dex client secrets flow through this.Deployment — compose file layering; where
docker-compose.ca.ymlfits alongside the application stack.Backup and Restore — backup of the step-ca Docker volume.
Client setup — SSH with step-ca certificates — how-to: laptop setup.
CA day-to-day operations — how-to: routine ops.
CA provisioner management — how-to: add/update/remove provisioners; rotate JWK passwords.
CA rotation and disaster recovery — how-to: intermediate / root rotation; disaster recovery.
pki-security-roadmap.md (repo root) — full roadmap including threat analysis and phase plan.
step-ca documentation — upstream docs for provisioner syntax, config options, KMS backends.