Concepts

Security Model

How uPKI RA authenticates requests and protects the mTLS boundary.

Security Model

Threat model

uPKI RA sits between ACME clients (potentially untrusted) and the CA (highly trusted). Its security model ensures:

  1. Only authorised callers can request certificates
  2. The CA private key is never exposed to the RA
  3. Admin operations require mutual TLS authentication

Endpoint authentication

Route prefixAuth methodWho can call
/acme/*JWS (ACME account key)Any ACME client with a registered account
/api/v1/public/*NoneAnyone (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:

Set 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:

  1. Trust the CA certificate (ca.crt from /api/v1/public/ca)
  2. 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.

Do not hard-code 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

PortExposed toRationale
8000ACME clients, admin toolsACME + 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.

Copyright © 2026