Concepts
Security Model
How uPKI CA protects the root of trust.
Security Model
Trust anchor isolation
The CA is the root of trust for your entire PKI. uPKI CA's design choices reflect this responsibility:
- No HTTP interface — the only attack surface is ZMQ, which is not reachable from the internet in a standard deployment
- No remote admin UI — administration is done via ZMQ from authorised nodes or the CLI
- Seed-based authentication — the CA only issues node certificates to callers who present the correct registration seed (port 5001)
Seed security
The --seed flag (or UPKI_CA_SEED environment variable) is a shared secret used to:
- Derive the CA's private key material deterministically (on
init) - Authenticate new RA registration requests (port 5001)
Treat the seed as a root credential. Store it in a secrets manager (Vault, AWS SSM, etc.), not in plain text on disk. If the seed is compromised, any node could register itself with the CA.
Admin node list
After bootstrapping, only nodes listed in the CA's admin list (managed via add_admin / remove_admin) are allowed to perform sensitive CA operations. The list_admins command returns the current list.
CRL and OCSP
- The CA maintains a CRL that is updated on
generate_crl - OCSP status is available via
ocsp_check— but there is no built-in OCSP responder HTTP endpoint (use a reverse proxy if needed)
Key storage
Private keys are stored as plain PEM files under UPKI_DATA_DIR/nodes/<cn>/key.pem. Filesystem permissions are the only protection at rest.
For production deployments, mount
UPKI_DATA_DIR on an encrypted volume and restrict access to the upki-ca process user.Network exposure
Recommended firewall rules:
| Port | Exposed to | Rationale |
|---|---|---|
| 5000 | RA nodes, admin tools only | CA operations require authenticated nodes |
| 5001 | RA nodes during initial registration only | Close after all RAs are registered |
Docker security
The official Docker image runs as a non-root user. The data directory is mounted as a volume — ensure its host path is owned by the same UID as the container process.