Architecture
CertAutoPilot is a single Go binary that runs in three modes — API, worker, scheduler — backed by MongoDB. This page describes process boundaries, the encryption envelope, and the audit chain.
01The three process modes
The same binary runs different responsibilities depending on the --mode flag.
| Mode | What it does | State |
|---|---|---|
api | HTTP/HTTPS server, REST + GraphQL, session and JWT. | Stateless |
worker | Pulls jobs (issue / renew / distribute / scan) and runs them. | Stateless; many replicas OK. |
scheduler | Enqueues time-driven jobs: renewal windows, drift scans, KEK rotation steps. | Leader-elected. Exactly one active. |
all | All three in one process. Default for the standalone installer. | For small deployments. |
02Data flow for issuance
- API receives
POST /api/v1/certificatesand writes a requested certificate document plus an issue job. - Scheduler is uninvolved here — only renewals and scans are scheduler-driven.
- Worker dequeues the job. It loads the ACME account, talks to the CA, publishes the DNS-01 challenge via the zone's credential, polls for validation, finalizes the order, and writes the chain back.
- Worker emits
cert.requested,cert.issued, andcert.distributedaudit events as it goes; each event is HMAC-chained to the previous one.
03Encryption envelope
Every secret field is wrapped in a per-field DEK (data-encryption key). The DEK is itself wrapped by a versioned KEK (key-encryption key). The KEK lives outside MongoDB — locally, in a file with restricted permissions, or in an HSM (PKCS#11 — SoftHSM2, AWS CloudHSM, Thales Luna, Fortanix).
field {
kek_version: 7,
dek: AES-256-GCM(KEK_v7, plaintext_dek),
ciphertext: AES-256-GCM(plaintext_dek, plaintext_field),
aad: sha256(record_id || field_name)
}
This means rotating a KEK never has to re-encrypt the actual ciphertext — only the small DEK wrappers — so rotation is fast and bandwidth-cheap, even for installations with millions of secrets.
So that a stolen MongoDB dump alone is useless. Decrypting any one field requires (a) the KEK in memory and (b) the DEK from the same field. The AAD ties the ciphertext to the record + field, so cut-and-paste attacks on the dump are detectable.
04Audit chain
Every audit entry includes prev_hmac — an HMAC over the previous entry, keyed with a per-organization audit secret. A tampered or deleted entry breaks the chain, and certautopilot audit verify reports the first broken link.
The same events are forwarded to a SIEM via RFC 5424 syslog or CEF over TCP/UDP/TLS. The forwarder is durable: events are persisted to disk before TCP send, so a SIEM outage does not lose events.
05Multi-tenant RBAC
RBAC is enforced at the API layer with policies declared per route handler. Project-scoped objects also enforce tenancy at the data-access layer — every read and write injects a project filter so an admin in project A literally cannot read project B objects, even with a crafted query.
06Network ports
| Port | Role | Notes |
|---|---|---|
| 443 | HTTPS UI + API | nginx termination by default; pass-through TLS optional. |
| 8080 | Internal HTTP | Bound to 127.0.0.1; nginx proxies to it. |
| 9090 | Prometheus | Scrape-only; bind explicitly. |
| 27017 | MongoDB | Local-only by default. Replica set members talk on this port. |