Cyphera Open PKI Server
Certificate authority and PKI lifecycle server. Create CAs, issue certificates, manage revocation, and run mTLS. Single binary, SQLite, no external dependencies.
What it does
Cyphera Open PKI Server is a self-contained certificate authority. It creates root and intermediate CAs, issues server and client certificates with profile-based policy, handles certificate signing requests (CSR), publishes CRLs, and runs an OCSP responder.
It works standalone as a general-purpose CA, or paired with Cyphera Open KMIP Server for end-to-end key management and certificate lifecycle.
Features
- Root and intermediate CA creation (Ed25519, ECDSA P-256, P-384)
- Certificate issuance with profile-based policy (server, client, kmip-server, kmip-client)
- CSR-based issuance — private key never leaves the requester
- CRL distribution points embedded in issued certificates
- OCSP responder with Authority Information Access extensions
- Certificate renewal
- Revocation with X.509 reason codes
- Expiration tracking
- CLI for offline operations + REST API for automation
- Embedded management dashboard
- SQLite storage with WAL mode
- Prometheus metrics endpoint
- Single binary, Docker ready (Chainguard base)
Quick start
# Create a root CA open-pki init-ca --name my-root --out ./certs # Issue a server certificate open-pki issue-server-cert \ --profile server \ --cn localhost \ --san localhost --san 127.0.0.1 \ --out ./certs # Start the server in dev mode open-pki serve --dev --db ./open-pki.db --addr 127.0.0.1:8300
KMIP mTLS in 4 commands
Issue certificates for mTLS between a KMIP server and its clients:
# Root CA open-pki init-ca --name kmip-root --out ./certs # Server certificate open-pki issue-server-cert \ --profile kmip-server \ --cn localhost --san localhost --san 127.0.0.1 \ --out ./certs # Client certificate open-pki issue-client-cert \ --profile kmip-client --cn demo-client --out ./certs # Start KMIP server with mTLS open-kmip \ --cert ./certs/localhost.pem \ --key ./certs/localhost-key.pem \ --ca ./certs/ca.pem --api-key my-secret
CSR-based issuance
For production use, generate the private key on the requesting system and send only the CSR. The CA never sees the private key.
# On the requesting system openssl req -new -newkey ed25519 -keyout app-key.pem -out app.csr \ -nodes -subj "/CN=my-app" \ -addext "subjectAltName=DNS:my-app.internal" # On the PKI server open-pki issue --csr app.csr --profile server \ --ca-cert ca.pem --ca-key ca-key.pem --out ./issued
Revocation
Issued certificates include CRL Distribution Point extensions. Revocation status is published through CRL endpoints and OCSP.
# Revoke a certificate open-pki revoke --serial ABC123 --reason key_compromise # Download CRL curl -o root.crl http://localhost:8300/crl/1.crl # Check via OCSP openssl ocsp -issuer ca.pem -cert client.pem \ -url http://localhost:8300/ocsp
REST API
Full REST API for automation and integration:
POST /v1/ca/root Create root CA
GET /v1/ca List CAs
GET /v1/ca/{id} CA detail
GET /v1/ca/bundle Trust bundle (PEM)
GET /v1/ca/{id}/crl CRL (PEM)
POST /v1/certificates/issue Issue certificate
POST /v1/certificates/issue-csr Issue from CSR
POST /v1/certificates/renew Renew certificate
GET /v1/certificates List certificates
GET /v1/certificates/expiring Expiring soon
POST /v1/certificates/{serial}/revoke Revoke
GET /crl/{id}.crl CRL (DER, public)
POST /ocsp OCSP responder (public)
Certificate profiles
Profiles enforce validation rules, key usage, and extended key usage per certificate type.
server 397 days serverAuth DNS/IP SAN validation client 397 days clientAuth Subject validation kmip-server 397 days serverAuth DNS suffix + IP/CIDR rules kmip-client 397 days clientAuth Subject validation
Status
Cyphera Open PKI Server is alpha software (v0.1.0-alpha.1). CA private keys are currently stored unwrapped in SQLite. It is suitable for development, testing, and evaluation. It has not been externally audited. See the security policy for known limitations.
Standards & references
Cyphera Open PKI Server follows the X.509 PKI standards. Primary references: