Security Model
Security Model
Threat model
uPKI RA sits between ACME clients (potentially untrusted) and the CA (highly trusted). Its security model ensures:
- Only authorised callers can request certificates
- The CA private key is never exposed to the RA
- Admin operations require mutual TLS authentication
Endpoint authentication
| Route prefix | Auth method | Who can call |
|---|---|---|
/acme/* | JWS (ACME account key) | Any ACME client with a registered account |
/api/v1/public/* | None | Anyone (health check, CA cert download) |
/api/v1/* | mTLS (client certificate) | Admins with a CA-issued client cert |
/api/client/* | mTLS (client certificate) | Registered clients with a CA-issued cert |
mTLS setup
Admin and client endpoints require the caller to present a certificate signed by the same CA as the RA. The RA verifies the client certificate against its local ca.crt on every request.
The RA's own TLS certificate is stored in ra.crt / ra.key inside the data directory. It is issued by the CA during bootstrap.
ACME account security
ACME accounts are tied to a JWK (JSON Web Key). Every ACME request is signed with the account's private key and verified by the RA. The RA never stores account private keys — only the public JWK.
Auto-bootstrap security
The bootstrap process uses CA port 5001 (RA registration) with the shared CA seed. This is intentionally a one-time operation:
UPKI_RA_SANSbefore the first start. The RA's certificate SAN list cannot change after bootstrap without re-registration. Ensure all hostnames clients will use to reach the RA are listed.TLS configuration
When UPKI_RA_TLS=true (default in Docker), uvicorn serves HTTPS using the RA's own certificate. Clients must:
- Trust the CA certificate (
ca.crtfrom/api/v1/public/ca) - Present a valid client certificate for protected endpoints
Seed security
The UPKI_CA_SEED environment variable is used only once (during bootstrap) and is not stored on disk by the RA.
UPKI_CA_SEED in Docker Compose files committed to source control. Use Docker secrets, environment files outside the repo, or a secrets manager.Network exposure
| Port | Exposed to | Rationale |
|---|---|---|
| 8000 | ACME clients, admin tools | ACME + admin API |
The RA does not need to be publicly internet-accessible. It only needs to be reachable by your ACME clients (Traefik, cert-manager, etc.) within your private network.