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_setup_vms.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_setup_vms.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_setup_vms.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.