CLI reference
Every CertAutoPilot subcommand, every flag, every exit code. The binary is the same on standalone hosts (/usr/local/bin/certautopilot) and in Kubernetes pods (run via kubectl exec). All subcommands read the same config.yaml and env vars as the main server, so run them from the same host or an equivalent one with MongoDB access.
Standalone hosts: use the cap wrapper. MongoDB credentials and KEK material live in /etc/certautopilot/secrets.env, which systemd loads into the service process — your interactive shell does not, so a naked certautopilot user list or certautopilot kek status fails with Command find requires authentication. The installer drops /usr/local/bin/cap, which sources secrets.env, re-execs itself under sudo when needed, and passes --config=/etc/certautopilot/config.yaml for you:
cap user list
cap kek status
cap-kek (the older, kek-only wrapper) still works as a shim: cap-kek status = cap kek status. The bare-binary forms below apply to Kubernetes / Docker / dev environments where the credentials are already in the process environment.
Global flags
| Flag | Default | Purpose |
|---|---|---|
--config <path> | configs/config.yaml | Alternate config file location. Standalone installs use /etc/certautopilot/config.yaml. |
--help, -h | — | Subcommand help. |
serve
certautopilot serve [--mode=api|worker|scheduler|all] [--config=...]
The main entry point. Runs the HTTP API, the job worker, and the leader-elected scheduler in the selected mode (all by default).
| Flag | Default | Notes |
|---|---|---|
--mode | all | api, worker, scheduler, or all. |
Three independent modes so you can scale each surface horizontally (e.g. many API pods, a few worker pods, exactly 2 scheduler pods for leader-election redundancy).
version
certautopilot version
Prints the embedded build metadata (semver, commit, build date, Go version). Injected at build time via -ldflags.
kek
KEK lifecycle management — inspect, rotate, retire, verify. CLI-only in Phase 1 (no REST equivalent so the rollout story stays simple).
kek status
certautopilot kek status
Lists all loaded KEK versions, the active version, the provider, the last rotation record, and the current cluster heartbeat roster. Use as a pre-flight check before and during rotation.
kek verify
certautopilot kek verify [--target=N] [--local]
| Flag | Default | Purpose |
|---|---|---|
--target | 0 | Report readiness for target version N. 0 = just list live processes. |
--local | false | Skip the cluster heartbeat check; only verify the local process can round-trip wrap/unwrap. |
Exit codes: 0 READY; 2 NOT READY (with a laggard list on stderr); 1 error.
kek rotate
certautopilot kek rotate --from-version=M --to-version=N [--batch-size=100] [--concurrency=2]
certautopilot kek rotate --cancel
| Flag | Default | Purpose |
|---|---|---|
--to-version | — | Target version (required unless --cancel). |
--from-version | 0 (= infer from keystore) | Source version — the version the DB's envelopes are currently wrapped with. When omitted, the CLI reads the keystore's active row (same source the running service uses). Pass it only when you know the keystore is mid-transition and want to be explicit. |
--batch-size | 100 | Records per batch. |
--concurrency | 2 | Parallel collection batches. |
--cancel | false | Request a graceful stop on the active rotation. |
Returns a rotation ID immediately; the actual re-encryption runs as a leader-elected background job. Resume-safe (see failure modes).
kek remove
certautopilot kek remove --version=N [--force]
| Flag | Default | Purpose |
|---|---|---|
--version | — | Version to retire (required). |
--force | false | Skip the reference-count safety check (CLI-side scan of every encrypted collection). Lab use only. The service-side fleet safety check (refuse if any live process still has the version as its current KEK) always runs — --force does not bypass it, because it addresses a different failure mode (stale instances writing new envelopes with the version being removed). |
Two safety gates stack here. The reference-count check catches leftover envelopes (a rotation that left some rows on the old version, typically because of per-batch failures). The fleet heartbeat check catches lagging nodes whose in-memory current KEK is still the version being removed; the error lists each such node so the operator knows exactly which to restart (or wait for the heartbeat-tick auto-reload to converge). Combined: kek remove is safe to call immediately after a rotation completes, as long as the heartbeat window (~30 s) has passed.
kek pkcs11-init
certautopilot kek pkcs11-init --version=N [--probe-only]
Provisions the HSM-backed KEK for version N: probes HSM capabilities (CKM_AES_GCM), generates an AES-256 key inside the token labelled <prefix>N, verifies wrap/unwrap round-trip, then writes keystore metadata. Idempotent — re-running on an already-initialised version is a no-op.
| Flag | Default | Purpose |
|---|---|---|
--version | — | Version to initialise (required). |
--probe-only | false | Run probes against a throwaway key and exit without persisting. Use to validate a new HSM before committing. |
kek pkcs11-register
certautopilot kek pkcs11-register --version=N [--config=...]
For workflows where the HSM key is created by a separate administrator (key ceremony, vendor policy), pkcs11-register attaches an existing key to the keystore. Does NOT create HSM material; only inserts metadata + the install lock. The key must already exist with the configured label.
user
Offline user administration — recovery commands that talk straight to MongoDB, for when nobody can log in to the panel.
user list
certautopilot user list [--org-id=<id>] # standalone: cap user list
Lists local panel users with display name, org role, auth source, active/2FA state, and last login. Use it to find the account you need before user reset-password.
| Flag | Default | Purpose |
|---|---|---|
--org-id | — | Only list users in this org. |
user reset-password
certautopilot user reset-password --username <user> --password '<new>' \
[--org-id=<id>] [--clear-totp] # standalone: cap user reset-password ...
Rewrites the account's bcrypt hash in MongoDB (does NOT touch MongoDB's own password). The new password must meet the panel's password policy. LDAP accounts are rejected — reset those in your directory.
| Flag | Default | Purpose |
|---|---|---|
--username | — | Account to reset (required). |
--password | — | New password (required). |
--org-id | — | Disambiguate a username shared across orgs. |
--clear-totp | false | Also disable two-factor (TOTP) — e.g. a lost authenticator device. |
Exit codes
| Code | Meaning |
|---|---|
0 | Success. |
1 | Error — details on stderr. |
2 | Not ready (kek verify) or state rejected (kek rotate during an active rotation without --cancel). |
Environment variables
Every subcommand respects the same CERTAUTOPILOT_* env overrides as serve — see Environment variables. In particular, CERTAUTOPILOT_ENCRYPTION_ENV_KEK_V{N} and CERTAUTOPILOT_ENCRYPTION_PKCS11_PIN must be loaded for KEK subcommands to operate.
sudo alone does NOT load systemd's EnvironmentFile — on a standalone host use the cap wrapper, which sources /etc/certautopilot/secrets.env before invoking the binary:
cap kek status