A new generation of certificate authority — built for the modern world.
Written purely in Go — no third-party frameworks, no SDKs, no application server — and it deploys scalable by default: stateless roles as container-native microservices that scale independently. The single-box modes exist for what they're good at — offline roots and testing. Two direct dependencies: a supply chain you can audit over coffee.
Most CAs in production are twenty-year-old codebases retrofitted for a container world — application servers, plugin jars, and a supply chain nobody can enumerate. They run on proprietary operating systems with license costs, or as single containers that cannot scale in today's world. goca was designed for today's infrastructure from the first commit.
Protocols ACME + ARI REST API CMP SCEP EST OCSP CRL distribution ML-DSA, SLH-DSA Merkle tree certificates (draft)
Algorithms RSA Elliptic curves ML-DSA, SLH-DSA Merkle tree certificates (draft)
Key Custody PKCS#11 HSM hardware-KEK wrapped AWS KMS Azure Key Vault Google Cloud KMS YubiKey keys in hardware or wrapped under a hardware KEK — and a product that tells you the difference honestly. 16 preconfigured HSM vendor profiles, and it works with any PKCS#11-compliant module; e.g. YubiKey-backed offline roots; cloud KMS in pure Go
Identity SPIFFE every component holds a SPIFFE identity for mutual TLS across the mesh
The quickstart and training reflect what ships today.
Capabilities
Built for the person who has to defend the CA in an audit.
goca is a CA engine — the hardened core behind your RA/CLM, not a lifecycle portal. The controls a PKI team actually asks about — dual control, custody you can name, hardware you can point at — are the platform, not the enterprise tier.
Four-eyes approval, fail-on by construction. Sensitive operations require a second person, and the control is designed so that deleting the approval state turns it on, not off. An attacker with database access can break the mechanism — and by breaking it, lock issuance, not open it.
HSM support, proven on real hardware
PKCS#11 with 16 preconfigured vendor profiles — and it works with any PKCS#11-compliant module. A runtime-pin catches a swapped library, and verification happens on real hardware, not a simulator. A vendor not covered yet? Get in touch via support — we'll work with you to get your module deployed with the product.
Cloud KMS in pure Go
AWS KMS, Azure Key Vault, and Google Cloud KMS clients with no vendor SDKs — hand-written request signing you can read, in the same custody vocabulary as the HSMs.
Key custody, stated honestly
Three custody modes, ranked in print, with a table that says where the private key is at the moment a signature happens — see the custody table below.
Post-quantum as a peer
ML-DSA, SLH-DSA, and composite signatures next to ECDSA and RSA — same templates, same custody model, same audit trail.
Scales without ceremony
Every role is stateless; state lives in PostgreSQL. It is the same
one binary in every seat — add capacity with
--scale, not with an architecture meeting.
Configuration as code
The whole CA is declarative, versioned documents — endpoints, templates, policies, custody. Plan, apply, diff, detect drift: spin up a completely configured CA with no manual actions.
eIDAS-profile templates
18 seeded certificate templates, including eIDAS-profile templates for QWAC, QSeal, QSigC, and PSD2 — profiles that match the spec, ready to adapt to your policy.
ACME + ARI
RFC 8555 issuance with ACME Renewal Information, so fleets renew on the CA's schedule instead of guessing at half-lifetime.
REST API with console parity
Everything the console does is a public REST call. There is no hidden admin channel to reverse-engineer — automate what you clicked.
Merkle audit, no retention knob
The audit log is a Merkle tree with signed checkpoints — tampering is provable, and there is no retention setting, and never will be.
Offline TOTP MFA
MFA works with no internet, the admin minimum is compiled into the binary, and enrolled factors are tamper-evident.
Break-glass Shamir cards
Emergency access is split across physical cards — a quorum reconstructs it, no single card does. The break-glass path is audited like everything else.
Distroless, no shell
The container image has no shell, runs non-root on a read-only root filesystem — there is nothing to drop into.
Key custody
"HSM-backed" is a phrase that hides the difference.
A stored key's custody is one of three answers to a single question: where is the private key at the moment a signature happens? goca refuses to blur this — and so does this page.
| Mode | Where the key is when it signs | Signing rate | A stolen database gets an attacker |
|---|---|---|---|
software |
In the service's process memory, unwrapped under the KEK derived from your master secret | CPU speed | Every CA key — if they also have the master secret |
pkcs11-wrapped |
In the custody tier's process memory, unwrapped by the token, for the duration of the call | CPU speed | Nothing usable — the wrapping key is on the token and is not extractable |
pkcs11 |
Inside the token. Every signature is one C_Sign |
Bounded by the appliance's signature rate | Nothing usable |
The ranking is pkcs11 > pkcs11-wrapped ≈
software, and it will keep being stated that way.
An audited acceptance gate
Wrapped custody isn't a checkbox: a backend earns it through an audited acceptance gate, and a Save button is test-gated — a backend is saved because a test proved it, not because you clicked.
Custody follows the platform
The same custody vocabulary spans PKCS#11 tokens, cloud KMS on AWS, Azure, and GCP, and the Windows CNG bridge — one honest model everywhere the key can live.
Post-quantum
PQC as a peer, not a preview.
ML-DSA, SLH-DSA, and composite signatures sit next to ECDSA and RSA as equals — same templates, same custody model, same audit trail. You choose the algorithm; nothing else changes.
ML-DSA
Lattice-based signatures for everyday issuance — root, issuing CA, and end-entity alike.
SLH-DSA
Hash-based, conservative-assumption signatures — a common choice for long-lived roots.
Composite
Classical and post-quantum in one signature, for relying parties that need both to agree.
Strict-PKCS#11 ML-DSA — the private key never leaving the token — verified on real, post-quantum-capable HSM hardware, 2026-08-16. Not a simulator, not a software fallback.
Interfaces & protocols
Every door a device knocks on.
The platform is designed to speak to everything in the estate — from ACME-native fleets to the network gear that still insists on SCEP.
| Interface | Role in the platform |
|---|---|
| REST API | Console parity — everything the console does is a public REST call |
| ACME + ARI | RFC 8555 issuance with renewal information |
| SCEP / EST / CMP | Enrollment for network gear, embedded fleets, and the estates that standardized on them |
| CRL distribution | CRL-first revocation: issuance may stop; validation must not — with delta and sharded CRLs in the design |
| OCSP | Online status alongside the CRL backbone |
| Certificate templates | 18 seeded, including eIDAS-profile templates (QWAC, QSeal, QSigC, PSD2) |
| External-parent CAs / adopt-existing-key | Bring a CA signed elsewhere, or adopt a key that already exists |
| SPIFFE mesh identity | Mutual TLS across the mesh; enforcement is staged — opt-in per listener with a migration path |
| Admin console & notifications | Docs embedded in the binary, served from the console; expiry and lifecycle events |
Architecture
No externally reachable component can mint a certificate alone.
goca is a multi-tier architecture: only the protocol heads face the network — everything with real authority lives behind them, and signing happens last, in an isolated tier, after independent checks that no exposed surface can perform on its own.
multi-tier: only the protocol heads are exposed; custody signs last
Only protocol heads are exposed
The tiers that talk to the network hold no signing keys and no issuance authority. Everything that decides or signs sits behind them, on its own network segment.
Least-privilege database roles
Every tier has its own database role with only the grants it needs — and the exposed tiers hold none at all. A captured front door reads nothing.
Encryption separation
Secrets are sealed per tier: each one can decrypt only what belongs to it, and CA keys are usable only inside the custody tier — or never leave the HSM at all.
Supply chain
Two direct dependencies. That's the list.
No frameworks, no ORM, no gRPC, no vendor SDKs. When the code that mints your certificates fits in one review, "trust us" becomes "read it".
Written in-house
ASN.1/DER encoding, AWS SigV4, QR codes, Shamir secret sharing, SPIFFE identity, and a certificate linter — hand-rolled, in the repo, readable.
cgo: 3 files
Native code is confined to three files — the PKCS#11 and Windows CNG bridges. Everything else is pure Go, including the cloud KMS clients.
No moving targets
Two dependencies is a diff you can actually read on update day. A dependency tree that fits on one screen is a security control, not an aesthetic.
Deployment
Scalable by default.
Deploy everywhere — in your remote offline facility, your own datacenter, or your cloud provider. The default deployment is the scaled-out one: stateless roles as container-native microservices, each scaling independently. The single-box shapes exist for what they're good at — offline roots and testing.
Scaled out — the default
- Docker Compose distributed — the issuance split across containers and network segments, each role scaling independently
- Kubernetes — the same roles, scheduled
- Island mode — regions that keep issuing autonomously when the WAN doesn't
- Stateless by construction — adding capacity is a scale command, not a re-architecture
Single-box shapes — offline roots and testing
- Offline root — an air-gapped ceremony host with YubiKey-backed custody; external-parent and
GOCA_MODE=root-caas the working path today - Docker Compose all-in-one — one host for evaluation and testing, segmented networks per edge of the call graph
- Linux standalone — one binary under systemd, external PostgreSQL
- Appliance image and Windows service for estates that deploy that way
Fifteen minutes to a verified CA.
Request to download. Follow the quickstart, take the operator training, or ask the support assistant — it has read the entire manual, answers with "that isn't built yet" when that is the truth, and files bug reports and feature requests for you.
Not to be confused with github.com/kairoaraujo/goca — an unrelated Go
library of the same name that wraps crypto/x509 for basic CA and CSR
operations. Different authors, different scope. If that is what you were looking
for, you want the library, not this.