Skip to content
Registry StackDocsDevelopment (unreleased)

Integrate an Evidence Gateway candidate with Docker Compose

For the operator

View as Markdown

Start with the approved candidate created in Build and deploy an Evidence Gateway project. This guide runs that candidate in an existing Docker Compose application. Compose is an operator-owned deployment adapter, not output from evidencectl build. The candidate bundle stays unchanged across host and container deployments.

Outcome
An approved Evidence Gateway candidate mounted unchanged with a separate runtime, secret root, Transit socket, and persistent audit volume.
Time
About 20 minutes after the image and candidate are approved
Level
Operator-owned Docker Compose deployment
Prerequisites
Docker ComposeAn approved Evidence Gateway candidateA reviewed Evidence Gateway imageA workload-local Transit proxyPersistent storage prepared for UID and GID 65532

You need an approved candidate, a container image whose provenance and digest you have reviewed, an owner-only secret mount, a workload-local Transit proxy, and persistent storage for the audit chain. Do not use repository development images as released production artifacts.

Prepare a container-specific runtime document. It names the same bundle content but container paths, a private Compose-network listener, secret root, audit path, and any required private CA files.

Production and evidence-grade candidates require a workload-local Vault or OpenBao Transit proxy. Run one proxy for Evidence Gateway on the host or in an operator-owned sidecar. Give the proxy a dedicated host directory in which to create transit-proxy.sock, then bind-mount that directory at /run/registry-evidence in the Evidence Gateway container. Make the directory searchable but not writable by the Evidence Gateway identity. The proxy owns the directory and creates a mode 0660 socket whose group admits only that identity.

The proxy owns its provider auto-auth credential, provider trust file, and reviewed HCL configuration. Do not mount those inputs into Evidence Gateway. The proxy configuration must force its auto-auth token, require the X-Vault-Request header, disable request retries, and set socket ownership for the Evidence Gateway process. Use Configure Transit signing for Evidence Gateway and Registry Mint and the maintained deployment-target templates for the exact boundary.

The Git-managed proxy HCL is nonsecret. Provider credentials and generated tokens remain outside Git and outside the Evidence Gateway container. If Compose also owns the sidecar, replace the host bind with a dedicated named volume shared only by the proxy and Evidence Gateway.

The Evidence Gateway service mounts five independently owned paths:

candidate/bundle -> /etc/registry-evidence/bundle read-only
runtime.docker.yaml -> /etc/registry-evidence/runtime.yaml read-only
Evidence Gateway secret root -> /run/secrets/registry-evidence read-only
Evidence Gateway audit volume -> /var/lib/registry-evidence writable
Transit socket directory -> /run/registry-evidence socket access

Keep the bundle and runtime read-only. A read-only mount establishes their immutability, but does not waive secret ownership or mode validation. The maintained Evidence Gateway image runs as UID and GID 65532; pin that identity in the Compose file and make every secret file acceptable to it with the required owner-only permissions. A different reviewed image requires an explicitly reviewed UID and matching ownership. Prepare the persistent audit volume for that same identity before startup. Do not run Evidence Gateway as root to compensate for an audit volume with the wrong owner.

services:
evidence:
image: <reviewed-evidence-image-by-digest>
user: "65532:65532"
read_only: true
volumes:
- <candidate>/bundle:/etc/registry-evidence/bundle:ro
- ./runtime.docker.yaml:/etc/registry-evidence/runtime.yaml:ro
- <evidence-secret-root>:/run/secrets/registry-evidence:ro
- evidence-audit:/var/lib/registry-evidence
- <transit-socket-directory>:/run/registry-evidence:ro

Bind Evidence Gateway to a private Compose-network address. Put TLS termination and public routing in an operator-controlled service ahead of that listener.

Start the Transit proxy, then run evidence check in the target execution context after mounts, ownership, paths, and trust files are in place:

Terminal window
docker compose run --rm evidence \
--runtime /etc/registry-evidence/runtime.yaml check

Changing only the container runtime does not change the governed bundle, so it does not require the fixture suite to run again. Run fixtures again when the bundle changes.

The check exits successfully only when the container can read its immutable inputs, resolve the secret root, validate the configured audit path, reach the Transit proxy, match the pinned provider version to the governed public JWK, and validate the runtime and bundle together. It does not append an audit event.

The bundle revision covers exact bundle bytes and remains the same in host and Compose deployments. The runtime revision covers exact runtime bytes and bound private CA files, so it changes with container paths, listener bindings, or trust files. A configuration revision is narrower than either: it covers one requirement’s own configuration and artifacts. Signed assertions carry the revision of the requirement they answer as configurationRevision, never the runtime or bundle revision. No revision contains secret values or audit contents.

When the same application uses Mint, run Mint as a separate private service. Mint retains its public HTTPS issuer and JWKS URI, while internal routing or split DNS resolves that identity. Evidence Gateway must continue to use the public HTTPS issuer and JWKS URI, not an internal plain-HTTP service name. Strict Mint uses its own proxy, Unix-socket directory, provider identity, policy, and Transit key. Do not share the Evidence Gateway proxy or socket with Mint.

Stop the Compose services without removing the audit volume. Retention and audit-chain verification remain operator responsibilities.

Terminal window
docker compose down