Configuration
Spork uses TOML for configuration. The spork.toml file controls CA behavior, certificate profiles, and operational settings.
File search order
Spork searches for configuration in this order:
--configcommand-line argument./spork.tomlin current directory$CA_DIR/spork.tomlin CA directory~/.config/spork/spork.tomluser config
Basic configuration
# spork.toml
[ca]
# CA directory (overridden by --ca flag)
path = "./pki/issuing"
# Default signature algorithm
algorithm = "ecdsa-p384" # see Algorithm selection below
# Key encryption
key_encryption = "aes-256-gcm"
require_passphrase = true
[database]
# Storage backend: sqlite (default) or postgresql (planned)
type = "sqlite"
path = "spork.db" # relative to CA directory
# PostgreSQL (planned — not yet available)
# type = "postgresql"
# url = "postgres://user:pass@localhost/spork"
[logging]
level = "info" # trace, debug, info, warn, error
format = "json" # json, text
file = "spork.log"
Algorithm selection
| Algorithm string | Description |
|---|---|
ecdsa-p384 |
ECDSA P-384 (192-bit classical security; no quantum resistance) |
rsa-2048 |
RSA 2048-bit (compatibility; not recommended for new PKI) |
rsa-3072 |
RSA 3072-bit |
rsa-4096 |
RSA 4096-bit |
mldsa44 |
ML-DSA-44 (FIPS 204 — NIST category 2, post-quantum) |
mldsa65 |
ML-DSA-65 (FIPS 204 — NIST category 3, post-quantum) |
mldsa87 |
ML-DSA-87 (FIPS 204 — NIST category 5, post-quantum) |
ecdsa-p384+mldsa65 |
Hybrid: ECDSA P-384 with ML-DSA-65 composite |
Certificate profiles
Profiles define templates for certificate issuance. Each profile specifies key usage, extended key usage, and validity constraints. The profile name is passed to spork issue --profile <name>.
# TLS server certificate profile
[profiles.tls-server]
key_usage = ["digitalSignature"]
extended_key_usage = ["serverAuth"]
validity_days = 365
# Require SAN; CN alone is not sufficient
require_san = true
allowed_san_types = ["dns", "ip"]
[profiles.tls-server.subject]
required = ["CN"]
allowed = ["O", "OU", "L", "ST", "C"]
forbidden = ["emailAddress"]
# TLS client certificate profile
[profiles.tls-client]
key_usage = ["digitalSignature"]
extended_key_usage = ["clientAuth"]
validity_days = 365
require_san = false
allowed_san_types = ["email", "uri"]
[profiles.tls-client.subject]
required = ["CN"]
allowed = ["O", "OU", "emailAddress"]
# Code signing certificate profile
[profiles.code-sign]
key_usage = ["digitalSignature"]
extended_key_usage = ["codeSigning"]
validity_days = 365
require_san = false
[profiles.code-sign.subject]
required = ["CN", "O"]
allowed = ["OU", "L", "ST", "C"]
Validity periods
[validity]
root_ca_years = 20
policy_ca_years = 15
issuing_ca_years = 10
end_entity_days = 365
# Maximum end-entity validity enforced by this CA
max_end_entity_days = 365
# CRL update schedule
crl_validity_days = 7
crl_overlap_days = 1 # generate new CRL before current one expires
Spork is intended for private CAs. Public-web Baseline Requirements (CA/Browser Forum ballot SC-081v3) cap TLS end-entity validity at 200 days as of March 2026; private CAs may choose longer periods appropriate to their policy. Set max_end_entity_days to whatever your policy requires.
Extension templates
Extensions configured here are embedded in every certificate issued by the CA. Replace placeholder URLs with your own infrastructure endpoints.
[extensions]
# Authority Information Access
[extensions.aia]
ocsp = "http://ocsp.example.com/"
ca_issuers = "http://aia.example.com/issuing-ca.crt"
# CRL Distribution Points
[extensions.cdp]
uris = [
"http://crl.example.com/issuing-ca.crl",
"ldap://ldap.example.com/cn=Issuing%20CA,ou=PKI,o=Example,c=US"
]
# Certificate Policies
[extensions.policies]
oids = ["2.23.140.1.2.2"] # Organization Validated (example)
cps_uri = "http://www.example.com/pki/cps"
# Name Constraints (for CA certificates)
[extensions.name_constraints]
permitted_dns = [".example.com", ".example.org"]
excluded_dns = [".forbidden.example.com"]
permitted_email = ["@example.com"]
Full example
Complete spork.toml for a private issuing CA:
[ca]
path = "/opt/pki/issuing"
algorithm = "mldsa65"
key_encryption = "aes-256-gcm"
require_passphrase = true
[database]
type = "sqlite"
path = "spork.db"
[logging]
level = "info"
format = "json"
file = "/var/log/spork/issuing.log"
[validity]
end_entity_days = 365
max_end_entity_days = 365
crl_validity_days = 7
[extensions.aia]
ocsp = "http://ocsp.example.com/"
ca_issuers = "http://aia.example.com/issuing-ca.crt"
[extensions.cdp]
uris = ["http://crl.example.com/issuing-ca.crl"]
[profiles.tls-server]
key_usage = ["digitalSignature"]
extended_key_usage = ["serverAuth"]
validity_days = 365
require_san = true
allowed_san_types = ["dns", "ip"]
[profiles.tls-server.subject]
required = ["CN"]
allowed = ["O", "OU", "L", "ST", "C"]