Versioned archive. You are viewing v0.38.0. For the latest released guidance, use Latest release. Report archive issues on GitHub.
If you are planning a production Evidence Gateway deployment, this is what you provide, what the product does not depend on, and what stays your job once it runs. None of it is needed for the local tutorials, which start disposable versions of everything on your machine.
What you provide
Section titled “What you provide”- A host for one process. Evidence Gateway is a single binary that serves one trust domain. It runs on the platforms in platform support.
- HTTPS in front of it. The process listens on a private address; your reverse proxy or ingress terminates TLS and routes traffic to it.
- A token issuer. Evidence Gateway verifies bearer tokens from one OpenID Connect issuer and issues none. Configure a compatible OAuth issuer for this role.
- A signing key you control. Production signing uses a Vault or OpenBao Transit key that never leaves the vault, reached through a proxy on the same host. A local development profile may use a key file instead.
- Durable storage for the audit trail. Every request appends minimized JSON lines to an audit file on disk, or to standard output for your log collector. The disk it lands on, and the append-only store you ship it to, are yours.
- The authoritative source. Each question makes one fixed request to a system your institution already operates, over HTTP or against a read-only SQLite extract. That system has to answer within the timeout you configure.
- A reviewed bundle. Your authors write the questions, sources, and derivations as a project and hand you an immutable bundle. You mount it read-only beside a runtime file that names the listener, paths, and secrets for this host.
What it does not need
Section titled “What it does not need”There is no database. Evidence Gateway stores no records, no requests, and no answers; the only durable state it writes is the audit trail. There is no message broker, worker pool, cache, or service mesh, and nothing requires Kubernetes. One process, one bundle, and one audit path make one deployment. A second issuer, or a second customer who must not trust the first, means a second deployment.
Registry Relay and Base Registry Engine are separate products, not dependencies. Evidence Gateway can use either one as a source through the same fixed HTTP request it makes to any other system.
How it ships
Section titled “How it ships”Choose a published <tag> from the
latest release.
Each release publishes reproducible binaries for the runtime, the evidencectl authoring tool,
and the wallet delivery service, with an installer that verifies checksums before installing. It
also publishes ghcr.io/registrystack/evidence:<tag>, built on Distroless cc-debian13 with no
shell and running as the nonroot user. The image runs /usr/local/bin/evidence serve with
/etc/registry-evidence/runtime.yaml and uses /var/lib/registry-evidence as its working
directory. Mount the runtime file, bundle, and secrets read-only, and mount the audit directory
read-write. The release manifest records the exact promoted digest. Deploy that digest instead of
the mutable tag.
Starting with v0.38.0, an eligible published release also carries the separate
ghcr.io/registrystack/evidence-oid4vci:<tag> image. Its installation and runtime paths are in
Configure Evidence OID4VCI delivery.
The release ships no Helm chart or hosted offering. A Docker Compose file is a reasonable adapter around the published image, and Deploy with Docker Compose shows the shape: the reviewed bundle mounted unchanged, a separate runtime file and secret root, a persistent audit volume, and TLS in front.
What stays your job
Section titled “What stays your job”Keys. You generate the signing key and the two audit and subject-binding secrets, and you rotate them. When you rotate the signing key, the published key set has to keep every previous public key for as long as an assertion signed with it may still be verified, or a verifier holding an older assertion fails.
Immutable inputs. The runtime file and the bundle must not be writable by the service, and the process refuses to start when they are. There is no hot reload or override layer; a change means a new bundle, a fresh check, and a restart.
The audit trail. One process owns one audit path, so scaling out means several processes, each
with its own audit path, or a stdout destination gathered by your log collector. The file
rotates on its own and the runtime deletes sealed files after retainDays, so shipping each
sealed file to append-only storage before then is operator work, and that store is the only place
the log is tamper-evident.
Readiness. The health endpoint answers when the process is alive. The readiness endpoint fails closed while any secret, signing provider, audit sink, or source credential is unavailable. Route traffic on readiness. Metrics are off until you open a second, private-address listener for them.
Changing a published question
Section titled “Changing a published question”A deployment serves exactly one revision of each question. The bundle configures each requirement
URI once, and every assertion for it carries that requirement’s configurationRevision, which a
relying party pins in its verification policy. Editing the requirement, its source, one of its
selector profiles, an authority grant that names it, or any script, schema, codelist, or fixture it
reaches moves that revision. From the moment the new candidate serves, assertions carry the new
revision and fail verification under the old pin. No window exists in which the same deployment
answers under both revisions, so decide what kind of change it is before you build the candidate.
A semantic change mints a new requirement URI. When the change alters what an answer means,
such as a different rule, threshold, concept, source of record, or disclosure, publish the new
question under a new requirement URI, for example urn:example:requirements:adult-status:v2 beside
...:v1. Relying parties then choose when to move. Keep the old requirement in the bundle, with its
own grants, for an announced transition period, and remove it in a later candidate once that period
ends. A revision covers only what its own requirement reaches, so adding the new requirement leaves
the old one’s revision alone, unless the two share a source, selector profile, or artifact that you
also edit. Both requirements are enabled together, so review the bundle as one disclosure surface
before the new one serves.
A clarifying change is a re-pin event. When the answer keeps its meaning, such as a corrected
script that returns the same answers, a tighter schema, or a moved source endpoint, keep the
requirement URI. The revision still moves, so every relying party that pinned the requirement
has to re-pin it. Announce the change before you activate the candidate: tell each relying party
that consumes the requirement what changes, why its meaning does not, and when the new revision
will serve, and leave a notice window long enough for them to review it. At the announced time,
activate the candidate. Relying parties read the new configurationRevision through authenticated
discovery at GET /v1/evidence-definitions, not from refused requests, and update their pins.
If you cannot tell which kind of change it is, treat it as semantic. A new URI costs a transition period. A meaning change shipped as a clarification leaves a relying party accepting answers it never reviewed.
Some edits move no requirement’s revision at all: publishing, activating, retiring, or revoking a signing key; revoking an identity-provider key; and changing runtime-only paths or listeners. They change what relying parties trust or where the process runs, not what an answer means. The signing-key rotation and verifier trust procedures cover them.
Capacity
Section titled “Capacity”No throughput or latency figure is part of the Version 1 contract. The cost that shapes throughput is durability: a successful request pays two durable audit writes, or three when it searches before it fetches, and the audit writer batches writes that overlap so a busy deployment amortizes the disk barrier. Measurements taken on macOS are kept in the product’s performance note, and it asks you to measure again on the Linux host you will run before you size anything. Because each process owns its own audit path, N processes give close to N times the throughput.
Stability
Section titled “Stability”Registry Stack is pre-1.0, so a minor release may change APIs and deployment contracts, and security fixes land only in the latest release; see the support window. Within that, the Evidence Gateway Version 1 assertion contract, runtime, and operator contract are implemented, not exploratory. Document evidence, credential lifecycles beyond the SD-JWT VC serialization, multi-source answers, and a public catalog are named non-goals, and a future profile would need its own approved concept.