CLI reference
Every command and flag, as homepki <command> --help prints them in v0.8.0.
On this page
Commands
| Command | What it does |
|---|---|
root-ca | Generate a self-signed Root CA. root-ca list lists them. |
intermediate-ca | Generate an Intermediate CA signed by a Root CA, with its chain file. |
server-cert | Generate a serverAuth certificate and key under an Intermediate CA. |
client-cert | Generate a clientAuth certificate and key under an Intermediate CA. |
sign | Sign a certificate signing request generated elsewhere. |
revoke | Revoke a leaf and re-sign the CRLs. |
crl | Write or re-sign the CRLs without revoking anything. |
trust | Install, remove or check a Root CA in the system, Firefox/NSS and Java trust stores. |
skill | Install the Agent Skill for AI coding tools. |
version | Print the version, commit and build date. |
completion | Generate a shell completion script (cobra built-in): homepki completion zsh. |
Global flags
| Flag | Short | Default | Description |
|---|---|---|---|
--workdir | $HOMEPKI_WORKDIR, then ~/.homepki | Working directory holding every PKI. Accepted by every command. | |
--help | -h | Help for any command. | |
--version | -v | Print the version (root command only). |
The working directory is resolved in this order: --workdir, then the HOMEPKI_WORKDIR environment variable, then ~/.homepki. In a script that runs several commands, exporting HOMEPKI_WORKDIR once is shorter than repeating the flag.
Errors and exit codes
- A successful command exits
0. Any failure exits1. - An unknown flag, or a value a typed flag cannot parse, prints the error followed by the command's usage.
- Every other error prints on its own, without usage: a missing required flag, existing material without
--force, a missing tier, a name-constraint violation, a failedsudo. - Generate commands print what they do and each file written on stdout. Errors go to stderr. In scripts, rely on the exit code and check results with
list -o json.
root-ca
Generate a self-signed Root CA for a domain. The certificate and key go to <workdir>/<domain-with-dashes>/ca/. The root may sign intermediates only (pathlen:1).
| Flag | Short | Default | Description |
|---|---|---|---|
--domain | -d | required | Root CA domain name, e.g. runlocal.dev. |
--key-type | rsa | Private key algorithm: rsa, ecdsa, ecdsa-p256, ecdsa-p384, ecdsa-p521, ed25519. | |
--validity | 2190d | Days (90d) or a Go duration (24h, 30m). | |
--name-constraint | Repeatable. Restrict the names this CA may issue for, in openssl syntax: permitted;DNS:.example.internal or excluded;IP:10.0.0.0/8. Types: DNS, IP, email, URI. permitted; may be omitted. | ||
--force | -f | false | Replace an existing Root CA. Orphans every certificate under it. |
$ homepki root-ca -d runlocal.dev
$ homepki root-ca -d klimax.internal --key-type ecdsa --validity 3650d \
--name-constraint "permitted;DNS:.klimax.internal"
See Name constraints and Server and client certificates for key types and validity.
intermediate-ca
Generate an Intermediate CA signed by the domain's Root CA. It writes the certificate, the key and <name>-intermediate-ca-chain.crt (intermediate followed by root). An intermediate may sign leaves only (pathlen:0).
| Flag | Short | Default | Description |
|---|---|---|---|
--domain | -d | required | Root CA domain name. |
--name | -n | required | Intermediate CA name, e.g. bu1. |
--key-type | rsa | Same values as root-ca. | |
--validity | 2190d | Capped at the Root CA's expiry, with a note. | |
--name-constraint | Repeatable. Same syntax as root-ca. | ||
--force | -f | false | Replace an existing Intermediate CA and delete its CRLs. Orphans every leaf under it. |
$ homepki intermediate-ca -d runlocal.dev -n bu1
$ homepki intermediate-ca -d klimax.internal -n bu1 \
--name-constraint "permitted;DNS:.bu1.klimax.internal"
server-cert
Generate a key and a serverAuth certificate under an Intermediate CA, in <intermediate>/server-tls/. The common name is <server>.<intermediate>.<domain>, which is also the first SAN. The certificate is verified against its chain before anything is written.
| Flag | Short | Default | Description |
|---|---|---|---|
--domain | -d | required | Root CA domain name. |
--intermediate | -i | required | Intermediate CA name. |
--server | -s | required | Server name, e.g. kong-gateway. |
--san | Repeatable. Additional Subject Alternative Name. Bare values are detected as IP or DNS; prefix with DNS:, IP:, email: or URI: to force a type. | ||
--key-type | rsa | Same values as root-ca. | |
--validity | 365d | Capped at the Intermediate CA's expiry, with a note. | |
--pkcs12 | false | Also write <server>.p12 with the key, certificate and CA chain. | |
--pkcs12-password | changeit | Password of the PKCS#12 file. | |
--force | -f | false | Replace an existing certificate of the same name. The key is regenerated. |
$ homepki server-cert -d runlocal.dev -i bu1 -s kong-gateway \
--san kong.local --san 192.168.1.10 --san 'DNS:*.kong.local'
$ homepki server-cert -d runlocal.dev -i bu1 -s kong-gateway --validity 24h --pkcs12 --force
Quote SANs that contain *. zsh expands an unquoted --san DNS:*.kong.local and fails the command with no matches found.
client-cert
Generate a key and a clientAuth certificate under an Intermediate CA, in <intermediate>/client-tls/. Same naming and checks as server-cert.
| Flag | Short | Default | Description |
|---|---|---|---|
--domain | -d | required | Root CA domain name. |
--intermediate | -i | required | Intermediate CA name. |
--client | -c | required | Client name, e.g. my-client. |
--san | Repeatable. Same syntax as server-cert; use URI: for a SPIFFE ID. | ||
--key-type | rsa | Same values as root-ca. | |
--validity | 365d | Capped at the Intermediate CA's expiry, with a note. | |
--pkcs12 | false | Also write <client>.p12 with the key, certificate and CA chain. | |
--pkcs12-password | changeit | Password of the PKCS#12 file. | |
--force | -f | false | Replace an existing certificate of the same name. The key is regenerated. |
$ homepki client-cert -d runlocal.dev -i bu1 -c my-client \
--san URI:spiffe://runlocal.dev/ns/default/sa/my-client
$ homepki client-cert -d runlocal.dev -i bu1 -c my-client --pkcs12
list subcommands
Every tier has a list subcommand, with aliases ls and l. It reports expiry, days left and a verified chain of trust. Leaf lists also report revocation.
| Command | Required flags | What it verifies |
|---|---|---|
root-ca list | none (lists every root in the workdir) | Each root is a CA and correctly self-signed. |
intermediate-ca list | -d | Each intermediate is a CA signed by the root. |
server-cert list | -d, -i | Chain to the root, serverAuth usage, not revoked. |
client-cert list | -d, -i | Chain to the root, clientAuth usage, not revoked. |
| Flag | Short | Default | Description |
|---|---|---|---|
--output | -o | table | table (coloured, for people) or json (for scripts). |
$ homepki server-cert ls -d runlocal.dev -i bu1 -o json \
| jq -e 'all(.[]; .chain_valid)' >/dev/null || echo "broken chain"
The JSON format is described in Listing and verification.
sign
Sign a PEM certificate signing request with an Intermediate CA. Only the subject (C, ST, L, O, OU, CN) and the SANs are taken from the request. Basic constraints and key usages are set by homepki, so a request cannot ask to become a CA. The subject must carry O= the root's literal name and OU= the intermediate name.
| Flag | Short | Default | Description |
|---|---|---|---|
--domain | -d | required | Root CA domain name. |
--intermediate | -i | required | Intermediate CA name. |
--csr | required | Path to the PEM request. | |
--type | server | server or client: sets the extended key usage and the destination directory. | |
--name | first label of the CN | File name for the certificate. | |
--out | Write the certificate here instead of server-tls/ or client-tls/. | ||
--validity | 365d | Capped at the Intermediate CA's expiry. | |
--force | -f | false | Replace an existing certificate at the output path. |
$ homepki sign -d runlocal.dev -i bu1 --csr my-service.csr
$ homepki sign -d runlocal.dev -i bu1 --csr my-client.csr --type client --name my-client --out ./my-client.crt
revoke
Add a leaf's serial number to the Intermediate CA's CRL, then re-sign the intermediate CRL, the root CRL and the CRL chain file. Pass exactly one of --server, --client or --cert. Revoking a certificate that is already revoked prints a message and exits 0.
| Flag | Short | Default | Description |
|---|---|---|---|
--domain | -d | required | Root CA domain name. |
--intermediate | -i | required | Intermediate CA name. |
--server | -s | Server certificate to revoke, by name. | |
--client | -c | Client certificate to revoke, by name. | |
--cert | Path of a certificate to revoke, e.g. one written by sign --out. It must have been issued by this intermediate. | ||
--reason | unspecified | RFC 5280 reason: affiliationChanged, cACompromise, certificateHold, cessationOfOperation, keyCompromise, privilegeWithdrawn, superseded, unspecified. Case-insensitive. | |
--validity | 365d | How long the CRLs stay current (their nextUpdate). |
$ homepki revoke -d runlocal.dev -i bu1 -c my-client --reason keyCompromise
$ homepki revoke -d runlocal.dev -i bu1 --cert ./my-service.crt
crl
Write or re-sign the CRLs of an Intermediate CA and its Root CA, keeping every revocation already recorded. Use it before anything is revoked, since a server configured with a CRL file refuses to start without one, and to push nextUpdate forward before the CRLs go stale.
| Flag | Short | Default | Description |
|---|---|---|---|
--domain | -d | required | Root CA domain name. |
--intermediate | -i | required | Intermediate CA name. |
--validity | 365d | How long the CRLs stay current. Capped at each issuer's expiry. |
$ homepki crl -d runlocal.dev -i bu1
$ homepki crl -d runlocal.dev -i bu1 --validity 7d
See Revocation for the files written.
trust
Manage the trust stores that accept a Root CA. --store takes system, nss and java, repeated or comma-separated. Without it, every store available on the host is used; a store named explicitly must be available.
trust install
Add the Root CA to each selected store. A store that already trusts it is skipped. The system store, and a Java cacerts file you cannot write, are changed under sudo.
| Flag | Short | Default | Description |
|---|---|---|---|
--domain | -d | required | Root CA domain name. |
--store | every available store | system, nss, java. |
trust uninstall
Remove the Root CA from each selected store. Stores that do not hold it are skipped. Same flags as install.
trust status
Report which stores accept the Root CA. Alias st. Needs no privileges and never prompts.
| Flag | Short | Default | Description |
|---|---|---|---|
--domain | -d | every Root CA in the workdir | Root CA domain name. |
--store | every available store | system, nss, java. | |
--output | -o | table | table or json. |
$ homepki trust install -d runlocal.dev --store nss,java
$ homepki trust status -d runlocal.dev -o json | jq '.[0].trusted'
See Trusting the root CA for each store and the JSON fields.
skill
Install the Agent Skill compiled into the binary. See Agent Skill.
skill install
| Flag | Short | Default | Description |
|---|---|---|---|
--claude | true | Install into Claude Code's user skills directory, ~/.claude/skills/homepki. | |
--print | false | Write the skill to stdout instead of installing. | |
--force | -f | false | Overwrite an existing installed skill. |
skill path
Print where the skill is installed for Claude Code: ~/.claude/skills/homepki/SKILL.md. No flags.
$ homepki skill install
$ homepki skill install --print > ./SKILL.md
version
Print the version, commit and build date. Alias v; homepki --version prints the same.
$ homepki version