A simple PKI management tool for local development. Create and manage three-tier certificate authorities, intermediate CAs, and TLS certificates with a single CLI.
brew tap bcollard/homepki
brew install --cask homepki# Create root CA
homepki root-ca --domain runlocal.dev
# Create intermediate CA
homepki intermediate-ca --domain runlocal.dev --name bu1
# Create server certificate
homepki server-cert --domain runlocal.dev --intermediate bu1 --server kong-gateway
# Create client certificate
homepki client-cert --domain runlocal.dev --intermediate bu1 --client my-clientCertificates and keys are stored in ~/.homepki by default.
Override the default storage location using:
- The
--workdirflag:homepki root-ca --domain runlocal.dev --workdir /path/to/pki
- The
HOMEPKI_WORKDIRenvironment variable:export HOMEPKI_WORKDIR=/path/to/pki homepki root-ca --domain runlocal.dev
homepki implements a three-tier PKI structure:
- Root CA: The top-level certificate authority
- Intermediate CA: Organization/tenant-specific intermediate certificate authorities
- End-entity certificates: Server and client certificates for services
go build -o homepki.
├── main.go # Entry point
├── go.mod
├── cmd/
│ ├── root.go # CLI setup, --workdir flag
│ ├── root_ca.go # root-ca command (generate + list)
│ ├── intermediate_ca.go # intermediate-ca command (generate + list)
│ ├── server_cert.go # server-cert command (generate + list)
│ └── client_cert.go # client-cert command (generate + list)
└── pkg/
└── pki/
└── pki.go # PKI helpers (OpenSSL wrappers, cert parsing)
homepki root-ca --domain runlocal.dev
# List root CAs (table, default)
homepki root-ca list
# List as JSON
homepki root-ca list -o jsonThis creates:
- Root CA directory structure
- Root CA private key and self-signed certificate
homepki intermediate-ca --domain runlocal.dev --name bu1
# List intermediate CAs (table, default)
homepki intermediate-ca list --domain runlocal.dev
# List as JSON
homepki intermediate-ca list --domain runlocal.dev -o jsonThis creates:
- Intermediate CA private key and certificate signed by the root CA
- Certificate chain file (
{name}-intermediate-ca-chain.crt)
homepki server-cert --domain runlocal.dev --intermediate bu1 --server kong-gateway
# List server certificates (table, default)
homepki server-cert list --domain runlocal.dev --intermediate bu1
# List as JSON
homepki server-cert list --domain runlocal.dev --intermediate bu1 -o jsonhomepki client-cert --domain runlocal.dev --intermediate bu1 --client my-service
# List client certificates (table, default)
homepki client-cert list --domain runlocal.dev --intermediate bu1
# List as JSON
homepki client-cert list --domain runlocal.dev --intermediate bu1 -o jsonAll list subcommands verify the certificate's chain of trust and support two output formats via -o/--output:
| Format | Description |
|---|---|
table |
Human-readable table with coloured chain status (default) |
json |
Machine-readable JSON array, no extra output |
Chain validity is checked at list time:
root-ca list— verifies each root cert is validly self-signedintermediate-ca list— verifies the intermediate was signed by the root CAserver-cert list/client-cert list— verifies the leaf cert chains through the intermediate to the root CA
Example JSON output:
[
{
"name": "kong-gateway.crt",
"expires": "2027-04-01",
"days_left": 360,
"chain_valid": true
},
{
"name": "old.crt",
"expires": "2025-01-01",
"days_left": -270,
"chain_valid": false,
"chain_error": "x509: certificate has expired or is not yet valid"
}
]- 2048-bit RSA keys for strong encryption
- UTF-8 encoding for international character support
- Proper file permissions (700 for private directories)
- Certificate database tracking for revocation management
- Serial number management for unique certificate identification
- Chain verification on all
listcommands
{domain-name}/
├── ca/
│ ├── {domain-name}-root-ca.crt # Root certificate
│ └── private/ # Protected private keys
│ └── {domain-name}-root-ca.key # Root private key
{domain-name}/
└── {organization}/
├── {org}-intermediate-ca.crt # Intermediate certificate
├── {org}-intermediate-ca-chain.crt # Certificate chain
├── server-tls/ # Server certificates
├── client-tls/ # Client certificates
└── private/ # Protected private keys
└── {org}-intermediate-ca.key # Intermediate private key
- Key size: 2048-bit RSA
- Digest: SHA-256
- Validity: 365 days for leaf certs, 2190 days (~6 years) for CAs
- Extensions: Proper X.509 extensions for CA and end-entity certificates
- Secure storage: Keep private keys in secure, encrypted storage
- Access control: Limit access to CA private keys
- Backup: Regularly backup CA certificates and keys
- Rotation: Plan for certificate renewal and CA rotation
- Monitoring: Track certificate expiration dates
- Permission denied: Ensure proper file permissions on private directories
- Certificate validation: Check certificate chains and trust relationships
- Expired certificates: Monitor and renew certificates before expiration
- Configuration errors: Validate OpenSSL configuration syntax
# Inspect a certificate
openssl x509 -in certificate.crt -text -noout
# Manually verify a certificate chain
openssl verify -CAfile root-ca.crt -untrusted intermediate-ca.crt end-entity.crt
# Check a private key
openssl rsa -in private-key.key -checkMIT — see LICENSE.
- Test changes thoroughly in isolated environments
- Follow existing naming conventions
- Ensure security best practices are maintained