Quickstart · Linux standalone

One binary, one systemd unit.

goca is a single executable with the console, migrations and the full manual built into it (goca docs prints the manual with no network and no separate download). Verified on Ubuntu 24.04 with 1 vCPU and 512 MB RAM: the whole all-in-one process uses about 19 MB RSS.

Request a download link

Two facts up front

Signed release packages are not published yet — you build from the source your download link delivers. Roadmap And this shape needs a PostgreSQL you provide — the installer says so and refuses to pretend otherwise. Embedded, supervised PostgreSQL is the appliance shape, and it is not built.

1 · Build

The PKCS#11 bridge makes the full build cgo-enabled and dynamically linked, so build on the target — or on a build host with a matching libc — rather than copying the binary between libc families.

# build on the target, or on a Linux build host with a compatible C toolchain
CGO_ENABLED=1 go build -trimpath -tags "pkcs11 netgo osusergo" \
  -ldflags "-s -w" -o goca ./cmd/goca

No source yet? Request a download link

2 · Install

# install (on the target, as root)
chmod +x goca
sh deploy/standalone/install.sh ./goca

The installer creates a goca system user, /var/lib/goca, a hardened systemd unit, and /etc/goca/goca.env — then stops and tells you to edit it. Re-running never overwrites that file, because replacing the master secret would orphan every wrapped CA key in the database.

3 · Configure, migrate, start

Provision your external PostgreSQL first, then:

$EDITOR /etc/goca/goca.env      # DSN + master secret, both say CHANGE-ME
timedatectl                     # a CA signs validity windows from the clock

# Apply the schema. The migrations are INSIDE the binary — no checkout, no
# psql, nothing else to copy. Idempotent, so it is safe to re-run and safe to
# put in whatever runs your upgrades.
goca migrate                    # reads GOCA_DB_DSN, or pass --dsn
goca migrate --list             # what this binary carries, if you want to look

systemctl enable --now goca
journalctl -u goca -f

goca migrate needs a credential that may create tables — the database owner is the simple answer. The runtime DSN in goca.env can be the same one for a standalone install; the two only need separating when you split roles.

The system then bootstraps its own PKI unattended — goca-infra-root and ica-infra appear within seconds — and the console is on https://<host>:8085 with the same self-signed first-boot certificate the Compose quickstart explains. Sign in with the bootstrap account and change its password immediately.

4 · Then firewall 9090-9094, because nothing else will

This is the one hardening step the standalone shape does not do for you, and the reason is worth understanding rather than copying. --roles all runs every role in one process, so the internal calls (api → ra, api → issuer, issuer → keysvc) resolve in-process: no hop, no socket for those calls. That is a real reduction in attack surface — and it is not the same as "there is no internal wire". In-process resolution removes the client, not the server: the internal listeners still bind — 9090 keysvc, 9091 issuer, 9092 ra, 9093 crlgen, 9094 notifier, on every interface, because there is no bind-address option — and they still serve the same signing-oracle, issuance and decision endpoints, fronted only by X-GOCA-Caller, a label the caller writes about itself. The Compose bundle neutralizes this with one network per edge of the call graph; a single host has no equivalent, so it is your firewall or nothing.

Two things bound the damage, and neither is a substitute for the firewall: keysvc will not sign without a pre-existing signing intent matching key, purpose, caller and a SHA-256 of the exact bytes presented — and no HTTP surface anywhere can create an intent. The RA's decision endpoint is the softer target, which is why the port list matters more than the ranking. GET /v1/status/transport reports what the transport actually is on a running process — the honest way to check, rather than assuming either posture.

Get the source

Free — download on request.

Request a download link