This file defines the vocabulary used in certdx's code, configs, and
docs. If a term is ambiguous between code and conversation, this file is
the authoritative spelling and meaning. Update it whenever a new domain
term enters the codebase.
- certdx_server: the single ACME issuer for a fleet. Talks to Let's Encrypt or Google Trust Services, caches certificates, and serves them to clients over HTTP and/or gRPC SDS.
- certdx_client: a standalone daemon that pulls certificates from a
certdx_serverand writes them to disk, optionally running a reload command (e.g.systemctl reload nginx). - Caddy plugin (
exec/caddytls): a Caddy module that consumescertdx_serverdirectly via Caddy'sget_certificateextension point, with nocertdx_clientdaemon in between. - Envoy SDS consumer: any Envoy instance that connects to the
certdx_servergRPC SDS endpoint and hot-swaps certificates on receipt. - certdx_tools: the operator CLI for one-shot tasks (cert cache inspection, mTLS material generation, ACME account registration, and the Tencent Cloud / Kubernetes certificate updaters).
- Subscriber: a goroutine registered through the server's internal
subscribe(entry)helper and not yet released. The renewal goroutine is alive while at least one subscriber is registered. - Renewer: the per-entry goroutine spawned by the first subscriber
(the 0→1 transition). It re-checks expiry on
RenewTimeLeftDuration / 4intervals and obtains a new certificate when the cached one expires. - Stop: the public lifecycle hand-off. Both
CertDXServer.Stop()andCertDXClientDaemon.Stop()cancel the daemon's root context exactly once. Every internal subgoroutine selects on the root context, soStopdrains them all without a separate stop chan.
- Cert pack: a single named bundle of domains served as one
certificate. The Envoy SDS protocol identifies cert packs by
ResourceName; the HTTP API does not name them and just returns the cert for the requested domain set. - Cache entry (
certEntry): the in-memory record for one cert pack — current cert + version + subscriber refcount + theupdatedchannel that broadcasts renewal events. - Version: a monotonically increasing renewal counter on each cache
entry. Subscribers pass the last version they observed to
WaitForUpdate; the renewer increments it on every successful renewal. Pairs with theupdatedchannel to make the broadcast miss-free. - Snapshot: an atomic read of
(cert, version)from a cache entry. Always read the pair viaentry.Snapshot()rather than separately, so callers don't observe a torn pair across a renewal.
- Allow-list (
ACME.allowedDomains): the set of base domains acertdx_serveris willing to issue under. Any cert request whose domains aren't all subdomains of this list is rejected withdomain.ErrNotAllowed. - Provider (
ACME.provider): the ACME directory to use —r3,r3test,google,googletest, or the in-processmock. The list and URL lookup live inpkg/acme/acmeproviders/. - Mock provider: an in-process ACME stand-in (
pkg/acme/mock.go) that mints self-signed leaf certs without contacting any ACME server. The e2e test suite uses it for hermetic test runs. - Challenge provider: the DNS-01 or HTTP-01 backend that satisfies
the ACME challenge. Lives under
pkg/acme/challengeproviders/—cloudflare,tencentcloud, ands3(HTTP-01). The Google EAB helper sits separately underpkg/acme/acmeproviders/google/; it is not a challenge backend.
- Main, Standby: the two
CertDXgRPCClientinstances acertdx_clientin gRPC mode runs against. Main is the preferred server; standby is engaged when main has been unreachable forRetryCount * 15s. - Failover session: a single FAILOVER → TRY_FALLBACK →
RESTART_MAIN cycle on the gRPC client. Scoped by a
sessionCtxderived fromrootCtx. Cancelled either when main recovers (the fallback goroutine sees a message arrive) or whenStop()fires. - Reset: legacy term for "cancel the current failover session". The
current implementation expresses this as
sessionCancel()followed by the dispatcher creating a fresh session.
Path resolution is owned by pkg/paths. Two install modes:
- FHS: linux + unresolved exe path in
/usr/bin/*or/usr/sbin/*. Config under/etc/certdx/, state (mtls/,private/,cache.json) under/var/lib/certdx/. - Local: everything else. Config under
<exeDir>/config/, state next to the resolved binary.
--data-dir <path> (or CERTDX_DATA_DIR) overrides the state root for
all binaries. --conf <path> overrides the config-file location; when
omitted, the binary uses <ConfigDir>/{server,client}.toml.
mtls/: directory holding mTLS material under the resolved data root. Bundle files are0600; the directory is0700.cache.json: server's persisted cert store, in the data root. Schema is the JSON encoding ofmap[domain.Key]certStoreEntry.private/: ACME account private keys under the data root. One key per(email, provider)pair, named<email>_<provider>.key.mtls/counter.txt: next CA serial number. Used only bycertdx_tools make-server/make-client.
The repo is a Go workspace (go.work at the root) of six modules:
- root (
pkg.para.party/certdx) — the library packages underpkg/. exec/server,exec/client,exec/tools— the standalone binaries. Each has its owngo.modso heavy per-binary deps (e.g. k8s client inexec/tools) stay out of the root module.exec/caddytls— the Caddy plugin, kept as its own module so its Caddy / certmagic dependency tree never leaks into the others.test/e2e— the end-to-end harness, isolated so test deps stay out of prod modules.
Every submodule has a replace pkg.para.party/certdx => ../.. directive
for environments that don't load the workspace (e.g. xcaddy's temp
build dir). For local development the go.work is what makes
go build ./... from any subdirectory resolve pkg.para.party/certdx
to the local checkout — no replace plumbing required.
When iterating on the Caddy plugin, xcaddy must be told about the parent
module explicitly (it does not honor go.work):
xcaddy build \
--with pkg.para.party/certdx/exec/caddytls=./exec/caddytls \
--replace pkg.para.party/certdx=./
release/build.py does this for releases. See docs/caddytls.md for
the full xcaddy invocation.
- HTTP API:
POST /on the server with a JSON bodyapi.HttpCertReq, returningapi.HttpCertResp. Called bycertdx_clientin HTTP mode and the Caddy plugin in HTTP mode. - gRPC SDS: the standard Envoy
SecretDiscoveryServiceprotocol on the server, with cert-pack metadata in theNode.Metadatafield under thedomainskey. Consumed by Envoy directly and bycertdx_clientin gRPC mode. - Caddyfile syntax: the
certdx { ... }global option and thecertdx <cert-id>get_certificateprovider directive. - Kubernetes annotation:
party.para.certdx/domains. Comma- separated, case-insensitive, de-duplicated.