Examples

Configuration examples.

goca is configured as documents: the create-CA form is the POST /v1/cas body, and every other object is a versioned YAML/JSON resource behind one uniform API. Everything the console does is a public REST call — so every example on this page is also exactly what you would click together in the console.

These examples target the current build

Verified against the product manual on 2026-08-16. Where a field is stored but not yet enforced (for example an endpoint's sourceRanges), the example leaves it out rather than pretending. Free — download on request.

ECC issuing CA (ECDSA P-384)

One POST /v1/cas creates the CA, and the optional spec block sets labels, path length, CRL cadence and the publication URLs at creation time — before the first certificate can be issued without them.

POST /v1/cas
{
  "name": "ica-tls", "commonName": "ACME TLS Issuing CA G1",
  "algorithm": "ecdsa-p384", "validityYears": 10, "issuerRef": "acme-root",
  "spec": {
    "labels": { "family": "tls", "env": "prod" },
    "constraints": { "pathLen": 0 },
    "crl": { "full": { "interval": "24h", "validity": "72h" }, "onRevocation": "immediate" },
    "publication": { "baseUrl": "http://pki.acme.example" },
    "rollover": { "mode": "manual" }
  }
}

Key generation is executed by keysvc in the selected custody — the management process never receives a CA private key.

Post-quantum root CA (SLH-DSA)

No issuerRef means a self-signed root; slh-dsa-sha2-192s is the manual's conservative PQC root choice (ECDSA P-384 the classical one).

POST /v1/cas
{
  "name": "root-pqc",
  "commonName": "Example Root CA G1",
  "organization": "Example",
  "algorithm": "slh-dsa-sha2-192s",
  "validityYears": 20
}

For production hierarchies, prefer running CA creation as a ceremony (plan → quorum approval → execute); the direct API path creates immediately and is fine for evaluation.

ACME endpoint (RFC 8555)

An AcmeEndpoint document publishes a directory at https://<head>/acme/<name>/directory; allowed templates are advertised as ACME profiles, registration defaults to external account binding, and order retention lives on the endpoint because the endpoint is what produced the orders.

PUT /v1/config/resources/AcmeEndpoint/web
{
  "spec": {
    "enabled": true,
    "defaultTemplate": "tls-server-ecdsa",
    "templates": ["tls-server-ecdsa", "tls-server-pqc"],
    "registration": { "mode": "eab-required" },
    "challenges": ["http-01", "dns-01"],
    "retention": { "orders": "720h" }
  }
}

Endpoint lint requires automatic approval on the bound templates — ACME clients expect prompt order completion. Set GOCA_ACME_BASE_URL to the external origin clients use.

TLS server template → CA binding

Which CA issues under a template is declared on the template (issuerRef) — endpoints bind a template and the CA follows, so the binding is maintained in exactly one place; the seeded TLS server templates ship unbound by design, so the first save picks the CA. When the same profile must issue from several CAs, derive instead of copying:

# a derived template's ENTIRE document (POST /v1/templates)
derivedFrom: tls-server-pqc   # the master
issuerRef: ica-tls-dev        # the only thing allowed to differ

A derived template mirrors the master's latest version at resolution time. Known caveat in the current build: derived templates carry a registered defect (build-gap register CA-011) — check the register before relying on them.

YubiKey PIV as a PKCS#11 module

A Pkcs11Module document names the vendor library, the token and a PIN reference — never the PIN itself; this exact custody path is verified on real YubiKey hardware.

PUT /v1/config/resources/Pkcs11Module/yubikey-piv
# body: { "spec": { ... } } — spec shown as YAML:
displayName: YubiKey PIV
library: /usr/lib/x86_64-linux-gnu/libykcs11.so
tokenLabel: "YubiKey PIV #19923655"
keyLabelPrefix: goca-
presenceRequired: true        # touch policy: unattended signing is refused, not retried
login:
  mode: pin
  pinRef: secret:hsm-pin      # a reference — the document never holds the PIN

A YubiKey PIV applet permits one session, so serve it from exactly one keysvc (bind the module to a site only that keysvc proves, or name it in that keysvc's GOCA_PKCS11_MODULE allowlist). A touch-policy key suits an offline root, not an issuing CA with scheduled CRLs.

AWS KMS provider

A KmsProvider document names the region and an auth mode — instance-role stores no credential anywhere and is the production choice; GOCA_KMS_PROVIDER on keysvc selects the document.

PUT /v1/config/resources/KmsProvider/aws-prod
# body: { "spec": { ... } } — spec shown as YAML:
provider: aws-kms
region: eu-central-1
auth:
  mode: instance-role         # IRSA / ECS task role / EC2 instance profile — no stored secret
# on-prem alternative:
#   mode: access-key
#   accessKeyId: AKIA…
#   secretAccessKeyRef: secret:aws-kms-secret   # a reference, never the value

AWS and Google Cloud KMS are built and accepted by the validator, but the console's provider editor currently offers Azure only — apply an AWS or GCP document through the API as above. A PQC (ML-DSA/SLH-DSA) CA on any cloud provider uses kms-wrapped custody; strict kms on AWS signs classical algorithms up to P-521.

MFA policy and four-eyes approval

The MFA floor is compiled in — system-admin always requires a second factor and no document can turn that off; an MfaPolicy may only add roles. Multi-person approval counts people including the proposer, so four eyes is people: 2.

PUT /v1/config/resources/MfaPolicy/default
{
  "spec": {
    "requiredRoles": ["system-admin", "ca-officer"]
  }
}

POST /v1/approval/enable
{ "people": 2, "scope": "security" }

Enablement refuses until at least people + 1 administrators are eligible, and once it is on you cannot turn it off alone — only a full quorum, or the break-glass cards. Deleting the approval state turns the control on, not off.

Try them against a running instance.

The fifteen-minute Docker Compose quickstart gives you a CA these documents can be applied to.

Request a download link Quickstart

Free — download on request.