Configuration¶
gapcert reads YAML. Unknown fields are rejected, so a typo fails loudly instead
of silently disabling a setting. Secrets are referenced by file path (kept
under ~/.config), never inlined.
Config files by mode¶
| Mode | File | Loaded by |
|---|---|---|
| Standalone | ~/.config/gapcert/config.yaml (or $GAPCERT_CONFIG) |
gapcert issue/renew/status |
| Agent | ~/.config/gapcert/agent.yaml (or $GAPCERT_AGENT_CONFIG) |
gapcert agent … |
| Broker | operator-chosen path | gapcertd … |
| Courier inside/outside | operator-chosen paths | gapcert courier export/run/import |
Common fields¶
ca—letsencrypt,letsencrypt-staging,zerossl, or any ACME directory URL (an internal ACME CA such as step-ca works too). Plainhttpis refused except on loopback, so a mistyped scheme can't silently downgrade the channel.email— the ACME account contact; required.ca_bundle— a PEM bundle trusted for an internal ACME CA's TLS certificate.data_dir— where certificates, keys, and account material live. Defaults to~/.local/share/gapcert.key_type(per certificate) —ec256(default),ec384,rsa2048,rsa4096.renew_before_days(per certificate) — renewal window; default 30.hook(per certificate) — a shell command run after a successful (re)issue, withGAPCERT_NAME,GAPCERT_CERT_PATH,GAPCERT_KEY_PATH, andGAPCERT_LIVE_DIRin its environment. Bounded to a 10-minute timeout.
Split-horizon / airgapped resolvers¶
In split-horizon networks the local resolvers may never see the public TXT record gapcert just published, so the propagation pre-check can hang. Point it at resolvers that do see public DNS, or disable the pre-check and rely on the CA's own validation:
DNS-01 solvers¶
The recommended pattern is acme-dns / a dedicated challenge zone: pre-create
_acme-challenge.<name> CNAME <id>.acme.example.com so the solver credential
can only ever write TXT records in a throwaway zone — never production DNS.
Scope every credential as tightly as the provider allows (Route53 condition keys, Cloudflare zone-scoped tokens, TSIG limited to the challenge zone). RFC2136 refuses unauthenticated dynamic update.
Broker, wildcard, and courier fields¶
Those modes add a few fields — listen/server_names/policies for the
broker, strategy: wildcard + agents for wildcards, and allow for the
courier companion. They're documented on the broker,
wildcard, and courier pages. A full
annotated example lives in
examples/config.example.yaml.
At-rest encryption (wildcard mode)¶
The broker encrypts shared wildcard keys with a master key resolved from
GAPCERT_MASTER_KEY (base64 of exactly 32 bytes), else a persisted per-install
random key at <data_dir>/master.key (mode 0600). There is no hardcoded
default — if neither is available, the broker fails closed rather than
encrypting with a known key.