Skip to content

cyphera-labs/open-pki-server

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

20 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Cyphera Open PKI Server

Alpha software. For development and evaluation only. This release is not externally audited and is not suitable for production CA infrastructure. CA private keys are currently stored unwrapped in SQLite. In normal mode, start the server with an API key, TLS certificates, and an explicit public base URL. Use --dev only on localhost for local development.

Open-source certificate authority and PKI lifecycle server for developers. Create CAs, issue certificates, manage revocation, and run mTLS — without fighting OpenSSL or depending on heavyweight enterprise platforms.

Works standalone or paired with Cyphera Open KMIP Server for end-to-end key management + certificate lifecycle.

What it does

  • Create root and intermediate CAs (Ed25519, ECDSA P-256/P-384)
  • Issue server and client certificates with profile-based policy
  • Issue from CSRs — private key never leaves the requester
  • Revoke certificates with X.509 reason codes
  • Publish signed CRLs per issuing CA
  • OCSP responder for real-time revocation checks
  • Embed CRL Distribution Points and OCSP URLs in issued certificates
  • Track certificate lifecycle with audit events
  • Browse everything from an embedded dashboard
  • Expose Prometheus metrics for monitoring
  • Single binary. SQLite. No external dependencies.

Install

go install github.com/cyphera-labs/open-pki-server/cmd/open-pki@latest

Or use Docker:

# Dev mode (localhost only, no auth, for local testing)
docker run -d -p 127.0.0.1:8300:8300 -v pki-data:/data \
  ghcr.io/cyphera-labs/open-pki-server \
  serve --dev --db /data/open-pki.db --addr :8300

# Authenticated mode
docker run -d -p 127.0.0.1:8300:8300 -v pki-data:/data \
  ghcr.io/cyphera-labs/open-pki-server \
  serve --api-key "$PKI_API_KEY" --db /data/open-pki.db --addr :8300

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

# Issue a client certificate
open-pki issue-client-cert \
  --profile client \
  --cn my-service \
  --out ./certs

# Inspect it
open-pki inspect ./certs/localhost.pem

# Verify it
open-pki verify ./certs/localhost.pem --ca ./certs/ca.pem

# Start the server in dev mode (localhost only)
open-pki serve --dev --db ./open-pki.db --addr 127.0.0.1:8300

# Start with TLS and authentication
open-pki serve \
  --api-key "$PKI_API_KEY" \
  --tls-cert ./certs/pki.pem --tls-key ./certs/pki-key.pem \
  --base-url https://localhost:8300 \
  --db ./open-pki.db

Dashboard at http://localhost:8300 (dev mode) or https://localhost:8300 (TLS mode).

KMIP mTLS in 4 commands

open-pki init-ca --name kmip-root --out ./certs

open-pki issue-server-cert \
  --profile kmip-server \
  --cn localhost --san localhost --san 127.0.0.1 \
  --out ./certs

open-pki issue-client-cert \
  --profile kmip-client \
  --cn demo-client \
  --out ./certs

open-kmip \
  --cert ./certs/localhost.pem \
  --key ./certs/localhost-key.pem \
  --ca ./certs/ca.pem \
  --api-key my-secret

CLI Reference

open-pki init-ca                Create a self-signed root CA
open-pki init-intermediate      Create an intermediate CA signed by a parent
open-pki issue-server-cert      Issue a server certificate
open-pki issue-client-cert      Issue a client certificate
open-pki issue --csr <file>     Issue a certificate from a CSR
open-pki inspect <file>         Inspect a PEM certificate
open-pki verify <file> --ca     Verify a certificate against a CA
open-pki bundle <files...>      Create a trust bundle
open-pki revoke --serial        Revoke a certificate
open-pki crl --ca-id            Generate and export a CRL
open-pki list                   List certificates
open-pki list --status revoked  Filter by status
open-pki serve                  Start the server with REST API and dashboard

REST API

Method Endpoint Description
GET /v1/health Health check
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
GET /v1/certificates/{serial} Certificate detail
POST /v1/certificates/{serial}/revoke Revoke
GET /crl/{id}.crl CRL (DER, public)
POST /ocsp OCSP responder (public)
GET /v1/inventory Asset inventory
GET /v1/audit Lifecycle events
GET /v1/stats Stats
GET /metrics Prometheus metrics

Certificate Profiles

Profile Type Validity EKU
server Server 397 days serverAuth
client Client 397 days clientAuth
kmip-server Server 397 days serverAuth
kmip-client Client 397 days clientAuth

KMIP profiles enforce SAN and subject validation rules.

Revocation

Issued certificates include CRL Distribution Point extensions. Revocation is published through CRL and OCSP.

# Revoke
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

Supported reasons: unspecified, key_compromise, ca_compromise, affiliation_changed, superseded, cessation_of_operation, certificate_hold, remove_from_crl, privilege_withdrawn, aa_compromise.

CA Hierarchy

# Root CA (long-lived, signs intermediates)
open-pki init-ca --name root --validity-days 3650 --out ./certs

# Intermediate CA (medium-lived, signs end-entity certs)
open-pki init-intermediate --name issuing-ca \
  --ca-cert ./certs/ca.pem --ca-key ./certs/ca-key.pem \
  --out ./certs

# End-entity certs signed by intermediate
open-pki issue-server-cert --cn app.internal \
  --ca-cert ./certs/issuing-ca.pem --ca-key ./certs/issuing-ca-key.pem \
  --out ./certs

CSR-Based Issuance

For production use, generate the private key on the requesting system and send only the CSR:

# 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 — validates CSR against profile policy before signing
open-pki issue --csr app.csr --profile server \
  --ca-cert ca.pem --ca-key ca-key.pem --out ./issued

The CA never sees the private key.

License

Apache License 2.0

Links

About

Cyphera Open PKI Server — internal certificate authority and certificate lifecycle server

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors