certz create -- Reference

February 26, 2026 ยท View on GitHub

Create X.509 certificates for local development or as a Certificate Authority.

See also: RSA vs ECDSA | Subject Alternative Names | Certificate Lifecycle | Certificate Chain | Windows Trust Store


Overview

certz create has two subcommands:

SubcommandPurpose
create devLeaf certificate for a hostname. TLS server auth, 90-day default.
create caCertificate Authority. Signs other certs, 10-year default.

Typical flow: create a CA once, then sign any number of dev certificates with it:

graph LR
    CA["certz create ca<br/>--name Dev CA"] -->|signs| DEV["certz create dev<br/>api.local --issuer-cert ca.pfx"]
    DEV --> Browser["Browser trusts api.local<br/>(because Dev CA is in trust store)"]
    CA -->|trust add| Store["Windows / macOS<br/>trust store"]
    Store --> Browser

Development Certificates (create dev)

Quick Examples

GoalCommand
Basic localhost certcertz create dev localhost
Auto-trust after creationcertz create dev api.local --trust
30-day validitycertz create dev app.local --days 30
Extra SANscertz create dev app.local --san "*.app.local" --san "192.168.1.10"
Signed by your CAcertz create dev api.local --issuer-cert ca.pfx --issuer-password pass
RSA keycertz create dev app.local --key-type RSA --key-size 4096
Custom output filenamescertz create dev app.local --file server.pfx --cert server.cer --key server.key
Ephemeral (no files)certz create dev app.local --ephemeral
Pipe to stdoutcertz create dev app.local --pipe

Defaults

When you run certz create dev app.local without extra flags:

PropertyValue
Key typeECDSA P-256
Validity90 days
SANsCN (app.local), localhost, 127.0.0.1 (auto-added)
EKUServer Authentication
Outputapp.local.pfx, app.local.cer, app.local.key
PasswordAuto-generated, printed to console

Full Options

OptionDefaultDescription
<domain>(required)Common Name and primary SAN.
--san <name>(none)Additional Subject Alternative Names. Repeatable. certz auto-detects IP vs DNS. See SANs.
--eku <value>serverAuthExtended Key Usage. Repeatable. Values: serverAuth, clientAuth, codeSigning, emailProtection. See EKU.
--days <n>90Validity in days. Maximum 398 (CA/B Forum limit for leaf certs).
--key-typeECDSA-P256Key algorithm: ECDSA-P256, ECDSA-P384, ECDSA-P521, RSA. See RSA vs ECDSA.
--key-size3072RSA key size in bits: 2048, 3072, 4096. Only applies when --key-type RSA.
--hash-algorithm, --hashautoHash algorithm for signing: sha256, sha384, sha512, or auto. auto selects based on key type -- see Hash Algorithm Auto-Selection below.
--issuer-cert(none)Sign with this CA file (PFX or PEM+key). Without this, cert is self-signed.
--issuer-key(none)CA private key file. Required when --issuer-cert is a PEM file without an embedded key.
--issuer-password(none)Password for a PFX --issuer-cert.
--trustfalseInstall to the trust store immediately after creation.
--trust-locationCurrentUserTrust store scope: CurrentUser or LocalMachine. LocalMachine requires admin. See Windows Trust Store.
--file<domain>.pfxOutput PFX filename.
--cert<domain>.cerOutput certificate filename.
--key<domain>.keyOutput private key filename.
--password(auto-generated)PFX password. Printed to console when auto-generated.
--password-file(none)Write the generated password to this file instead of the console.
--ephemeral, -efalseGenerate in memory only. No files written. See Ephemeral Mode below.
--pipefalseStream certificate to stdout. No files written. See Pipe Mode below.
--pipe-formatpemOutput format for --pipe: pem, pfx, cert, key.
--pipe-password(auto-generated)Password for --pipe --pipe-format pfx. Written to stderr.
--dry-run, --drfalsePreview what would be created (subject, SANs, key type, validity, output file) without creating anything. Exit 0 on valid options, 1 on invalid.
--guidedfalseLaunch the interactive wizard. After creation, prints the equivalent direct CLI command so you can reproduce the result without re-running the wizard.
--formattextOutput display format: text or json.
--verbosefalseEmit diagnostic lines to stderr: key gen, file writes, trust store access, full exception details.

Ephemeral Mode

--ephemeral generates the certificate entirely in memory. Nothing is written to disk.

# View cert details without saving any files
certz create dev app.local --ephemeral

# Machine-readable output for CI checks
certz create dev app.local --ephemeral --format json

# Inspect a specific key type before committing
certz create dev app.local --ephemeral --key-type RSA --key-size 4096

Use cases:

  • CI/CD: verify certz settings are correct without leaving files to clean up
  • Security-sensitive environments where private keys must never touch disk
  • Demonstrations and training

Restrictions -- --ephemeral cannot be combined with:

  • --file, --cert, --key (file output)
  • --trust (cannot install an in-memory certificate)
  • --password-file (no file to protect)
  • --pipe (mutually exclusive; pick one)

Pipe Mode

--pipe streams certificate content to stdout, making it composable with other tools. No files are written to disk.

# Default: PEM cert + key to stdout
certz create dev app.local --pipe

# Create Kubernetes TLS secret without intermediate files
certz create dev app.local --pipe | kubectl create secret tls app-tls --cert=/dev/stdin --key=/dev/stdin

# Certificate only
certz create dev app.local --pipe --pipe-format cert

# Private key only
certz create dev app.local --pipe --pipe-format key

# Base64-encoded PFX, explicit password
certz create dev app.local --pipe --pipe-format pfx --pipe-password "MySecret"

# Base64-encoded PFX, auto-generated password written to stderr
certz create dev app.local --pipe --pipe-format pfx 2>password.txt > cert.b64

Pipe formats:

--pipe-formatOutput written to stdout
pem (default)PEM certificate followed by PEM private key
certPEM certificate only
keyPEM private key only
pfxBase64-encoded PKCS#12. Password printed to stderr (or via --pipe-password).

Restrictions -- --pipe cannot be combined with:

  • --file, --cert, --key (file output)
  • --trust (cannot install a piped certificate)
  • --password-file
  • --ephemeral (mutually exclusive; pick one)

JSON Output Schema

certz create dev app.local --format json

Example output:

{
  "subject": "CN=app.local",
  "thumbprint": "A1B2C3D4E5F6...",
  "notBefore": "2026-02-21T00:00:00Z",
  "notAfter": "2026-05-22T00:00:00Z",
  "keyType": "ECDSA-P256",
  "sans": ["app.local", "localhost", "127.0.0.1"],
  "outputFiles": ["app.local.pfx", "app.local.cer", "app.local.key"],
  "password": "Xk9!mP2rLq",
  "passwordWasGenerated": true,
  "wasTrusted": false,
  "isCA": false,
  "pathLength": -1,
  "isEphemeral": false,
  "wasPiped": false
}
FieldTypeDescription
subjectstringFull subject DN (CN=...)
thumbprintstringSHA-1 thumbprint (hex, no colons)
notBeforeISO 8601Validity start (UTC)
notAfterISO 8601Validity end (UTC)
keyTypestringECDSA-P256, ECDSA-P384, ECDSA-P521, or RSA
sansstring[]All Subject Alternative Names on the certificate
outputFilesstring[]Files written (empty when ephemeral or piped)
passwordstring or nullPFX password (only present when auto-generated)
passwordWasGeneratedbooltrue when certz chose the password
wasTrustedbooltrue when --trust was used and succeeded
isCAboolfalse for dev certs
pathLengthint-1 for leaf certs
isEphemeralbooltrue when --ephemeral was used
wasPipedbooltrue when --pipe was used

Hash Algorithm Auto-Selection

When --hash-algorithm auto (the default) is used, certz selects the signing hash based on key type and size to match the security level of the key:

Key typeKey size / curveHash selected
ECDSAP-256SHA-256
ECDSAP-384SHA-384
ECDSAP-521SHA-512
RSA2048SHA-256
RSA3072SHA-384
RSA4096+SHA-512

Use an explicit value only when a compliance requirement mandates a specific algorithm:

# Force SHA-384 regardless of key type
certz create dev app.local --hash sha384

# Force SHA-512 for a FIPS-140 environment
certz create ca --name "Internal CA" --key-type RSA --key-size 4096 --hash sha512

Troubleshooting

ProblemLikely causeFix
Auto-generated password missing from output--pipe sends the cert to stdout; the password goes to stderrCapture stderr: certz ... --pipe 2>pass.txt
"File already exists" errorPrevious run left an output file with the same nameDelete the file or use --file to specify a different name
Browser still shows untrusted after --trustCurrentUser store is not used by all browsersTry --trust-location LocalMachine (requires admin). See Windows Trust Store.
IP SAN not accepted by browserIP address formatted as DNS SANUse --san "192.168.1.1" -- certz auto-detects IP vs DNS type
"Validity exceeds 398 days"--days set over the CA/B Forum limitUse 398 or fewer. For long-lived certs, use a CA and sign leaf certs.

CA Certificates (create ca)

Quick Examples

GoalCommand
Basic dev CAcertz create ca --name "Dev CA"
Trust it immediatelycertz create ca --name "Dev CA" --trust
10-year validitycertz create ca --name "My CA" --days 3650
Restrict to signing leaf certs onlycertz create ca --name "Issuing CA" --path-length 0
With CRL and OCSP URLscertz create ca --name "My CA" --crl-url http://crl.example.com/ca.crl --ocsp-url http://ocsp.example.com

Path Length

--path-length controls how many intermediate CA layers are allowed beneath this CA.

graph TB
    Root["Root CA<br/>(path-length = 1)"] --> Int["Intermediate CA<br/>(path-length = 0)"]
    Int --> Leaf1["leaf: api.local"]
    Int --> Leaf2["leaf: app.local"]
    Root -. "cannot sign leaf directly" .-> Leaf1
--path-lengthMeaning
-1 (default)Unlimited: can sign any depth of intermediates
0Can only sign leaf certificates (cannot sign other CAs)
1Can sign one level of intermediate CAs, which then sign leaf certs

For a simple local dev setup, -1 (unlimited) is fine. Use 0 when creating an issuing CA under a root CA to prevent the issuing CA from being used to create further sub-CAs.

Full Options

OptionDefaultDescription
--name(required)Common Name for the CA. Becomes the certificate subject.
--days <n>3650Validity in days (~10 years). CA certs are not subject to the 398-day leaf limit.
--path-length <n>-1Chain depth limit. See above.
--key-typeECDSA-P256Key algorithm: ECDSA-P256, ECDSA-P384, ECDSA-P521, RSA.
--key-size3072RSA key size. Only applies when --key-type RSA.
--hash-algorithm, --hashautoHash algorithm for signing: sha256, sha384, sha512, or auto. See Hash Algorithm Auto-Selection below.
--crl-url(none)CRL Distribution Point URL embedded in the certificate.
--ocsp-url(none)OCSP responder URL embedded in the Authority Information Access extension.
--trustfalseInstall to trust store after creation.
--trust-locationCurrentUserCurrentUser or LocalMachine. See Windows Trust Store.
--file<name>.pfxOutput PFX filename.
--cert<name>.cerOutput certificate filename.
--key<name>.keyOutput private key filename.
--password(auto-generated)PFX password.
--password-file(none)Write the generated password to this file.
--ephemeral, -efalseGenerate in memory only.
--pipefalseStream to stdout.
--pipe-formatpempem, pfx, cert, key.
--pipe-password(auto-generated)Password for --pipe --pipe-format pfx. Written to stderr.
--dry-run, --drfalsePreview what would be created (subject, key type, validity, output file) without creating anything. Exit 0 on valid options, 1 on invalid.
--guidedfalseLaunch the interactive wizard. After creation, prints the equivalent direct CLI command so you can reproduce the result without re-running the wizard.
--formattexttext or json.
--verbosefalseEmit diagnostic lines to stderr: key gen, file writes, trust store access, full exception details.

JSON Output Schema

certz create ca --name "Dev CA" --format json

Example output:

{
  "subject": "CN=Dev CA",
  "thumbprint": "B3C4D5E6F7A8...",
  "notBefore": "2026-02-21T00:00:00Z",
  "notAfter": "2036-02-21T00:00:00Z",
  "keyType": "ECDSA-P256",
  "sans": [],
  "outputFiles": ["Dev CA.pfx", "Dev CA.cer", "Dev CA.key"],
  "password": "Lp3!qN8wXz",
  "passwordWasGenerated": true,
  "wasTrusted": false,
  "isCA": true,
  "pathLength": -1,
  "isEphemeral": false,
  "wasPiped": false
}

The schema is identical to create dev. Key differences for CA output:

FieldCA value
isCAtrue
sansEmpty array (CAs do not require SANs)
pathLengthThe value passed to --path-length (default -1)

Troubleshooting

ProblemLikely causeFix
Certs signed by this CA not trusted by browserCA is not in the system trust storeRun certz trust add <ca.pfx> or recreate with --trust
"Path length exceeded" error when signingCA has --path-length 0 and you tried to sign an intermediateUse --path-length -1 or sign leaf certs directly from this CA
--trust prompts for elevationLocalMachine store requires admin privilegesRun as admin, or use CurrentUser and share the CA cert manually