Registry stack documentation: machine-readable Markdown.
Index of all pages: https://docs.registrystack.org/v/0.38.0/llms.txt
Full corpus: https://docs.registrystack.org/v/0.38.0/llms-full.txt

# Environment variable reference

> Environment variables read by Registry Stack runtimes, adopter tooling, and installers, with the secret reference grammars that name operator-chosen variables.

This page lists Registry Stack's supported fixed environment-variable interfaces for runtimes,
adopter tooling, and installers. It also records how Relayctl keeps fixture scratch state independent
of host temporary-directory configuration.

The stack's other kind of environment variable is operator-named. Secret material such as a cursor integrity key is not read from a fixed variable name: a configuration field carries a reference that names the variable, and the operator chooses the name. Relay, Base Registry Engine, and Evidence Gateway work that way, and the reference grammar is closed rather than free-form. Each reads a secret from an operator-named variable only when its runtime file opts in to the environment provider, as its section records.

## Configuration expansion

Evidence Gateway substitutes `${VAR}` and `${VAR:-default}` in string values of its runtime file after parsing, in `RuntimeConfig::parse_yaml` (`crates/registry-evidence/src/config.rs`), and refuses a `${...}` expression in a secret reference or under `secretProviders`, and refuses any `${...}` expression in the governed bundle, so the reviewed bundle is the one that runs. Relay substitutes `${VAR}` and `${VAR:-default}` in string values of its runtime file after parsing, in `RelayRuntime::parse_yaml` (`crates/registry-relay-v2/src/contract.rs`), and refuses any `${...}` expression in the authored `registry.yaml` in `RegistryContract::parse_yaml`, so the reviewed contract is the one that runs. Base Registry Engine substitutes `${VAR}`, `${VAR:-default}`, and `${VAR:?message}` in string values of its runtime file after parsing, through the shared configuration loader, and refuses any `${...}` expression in the authored project or module files, as [its section](#base-registry-engine) records.

There is no escape for a literal `${` in a runtime file that substitutes. Put the literal text in a variable and reference that variable: a substituted value is not expanded again.

## Relay

The `relay` binary reads these variables.

| Name | Purpose | Default or required |
| --- | --- | --- |
| `RELAY_HEALTHCHECK_URL` | Complete HTTP or HTTPS URL of the unauthenticated `/health` endpoint to probe. Equivalent to the `--url` flag on `relay healthcheck`. | Defaults to `http://127.0.0.1:8080/health`. |
| `RELAY_LOG` | Level for the JSON operational records the process writes on standard error. | Defaults to `info`. |

`RELAY_LOG` is a closed enumeration, not a tracing filter directive. It accepts exactly `off`, `error`, `warn`, `info`, `debug`, and `trace`, and each value applies to the `registry_relay_v2` target only. Any other value, including a valid-looking directive such as `trace,hyper=trace`, falls back to `info`. An arbitrary directive could enable dependency events carrying URLs or headers, so the process refuses to accept one.

### Secret references in `runtime.yaml`

Relay reads no variable for the runtime path: `relay check` and `relay serve` take it as the required absolute `--runtime-config <FILE>` flag. Relay resolves secrets through the providers `runtime.yaml` declares under `secretProviders`: `environment: {}` enables `secret:env/` references and `file: {root: <absolute directory>}` enables `secret:file/` references. One field takes a reference: `cursor.integrityKeyRef`, which applies when the deployment enables cursors. Other runtime values may use `${VAR}` or `${VAR:-default}` substitution; a field ending in `Ref` and every value under `secretProviders` refuse it, so the environment cannot choose which secret is read or where it comes from.

| Grammar | Resolves to | Accepted name |
| --- | --- | --- |
| `secret:env/<NAME>` | The value of the environment variable `<NAME>`, when `secretProviders.environment` is declared | Starts with an uppercase ASCII letter, then uppercase ASCII letters, digits, or `_`, up to 128 characters |
| `secret:file/<name>` | A file named `<name>` under `secretProviders.file.root` | Starts with a lowercase ASCII letter, then lowercase ASCII letters, digits, `.`, `_`, or `-`, up to 128 characters |

A reference that matches neither grammar, or names a provider the document does not declare, makes the runtime document invalid, so the process refuses to start rather than serving with an unresolved secret. The variable names themselves are the operator's choice and appear nowhere in Relay's source. See [Configure Relay](../../configure/relay/) for the fields around them.

### Relay installer

The install script reads these variables. They are read by the script, not by the running binary.

| Name | Purpose | Default or required |
| --- | --- | --- |
| `RELAY_VERSION` | Relay tag to install. A published installer asset embeds its own tag and refuses an override that does not match it. | Defaults to the installer's pinned tag. |
| `RELAY_INSTALL_DIR` | Directory the script installs into. | Defaults to `~/.local/bin`. |
| `RELAY_ASSET_DIR` | Directory of already-downloaded release assets to read instead of downloading. Use it after verifying a release with `release/VERIFY.md` at that release's tag. | Optional. |

The script verifies the downloaded `relay` and `relayctl` binaries against the release
`SHA256SUMS` before anything reaches the install directory. It installs both binaries together or
preserves the previous pair. It does not verify release authenticity.

## Relayctl

`relayctl` reads no environment variable. Workflow registries and projects arrive through positional
paths, explicit flags, or authored files. `tooling editor` may use its documented current-directory
default, and the language server receives authoring documents through its protocol session. Secret
references remain inside the project's `runtime.yaml` for `relay` to resolve at startup.

`relayctl test` ignores host temporary-directory variables. It validates the canonical project's
parent hierarchy, creates an owner-only transient workspace beside the project, and removes that
workspace after the fixture run. The project itself may be read-only, but its parent must be trusted
and writable. Scratch placement cannot select a Registry, deployment environment, credential, or
governed behavior.

## Evidence Gateway

`evidence` reads one fixed variable, `EVIDENCE_LOG`, and only in `evidence serve`.

| Name | Purpose | Default or required |
| --- | --- | --- |
| `EVIDENCE_LOG` | Tracing filter for the operational records the serving process writes as line-delimited JSON on standard error. | Defaults to `info`. Read by `evidence serve` only; offline commands install no log subscriber. |

Evidence Gateway reads no variable for the runtime path. Every subcommand that reads the runtime
file takes it as the required `--runtime-config <FILE>` flag after the subcommand, for example
`evidence check --runtime-config /etc/registry-evidence/runtime.yaml`. The global `--runtime` flag
and the `REGISTRY_EVIDENCE_RUNTIME` variable are removed: `evidence` refuses either one at startup
and names `--runtime-config` as the replacement, rather than silently ignoring it.

### Secret references

Evidence Gateway resolves secrets through the providers `runtime.yaml` declares under
`secretProviders`: `file: {root: <absolute directory>}` enables `secret:file/<name>` references, which
resolve to an owner-only regular file under that directory, and `environment: {}` enables
`secret:env/<NAME>` references, which resolve to the operator-named environment variable. The
grammars and accepted names are the ones in [the Relay table](#secret-references-in-runtimeyaml).
A reference in the runtime file or the governed bundle that names a provider the runtime file does
not declare is refused at startup, so an environment-backed secret is always an explicit operator
choice. See [Configure Evidence Gateway](../../configure/evidence/) for the runtime file and the
bundle it binds.

## Evidencectl

| Name | Purpose | Default or required |
| --- | --- | --- |
| `EVIDENCE_BIN` | Path to the `evidence` binary used by commands that delegate runtime validation or evaluation. An explicit `--evidence-bin` takes precedence, then this variable, then PATH lookup. | Optional. |

### Evidence Gateway toolset installer

The Evidence Gateway toolset installer stages `evidence`, `evidencectl`, and
`evidence-oid4vci`, then verifies every binary against `SHA256SUMS` before anything reaches the
install directory. The commands switch version together through a single toolset-pointer rename,
and a failed switch leaves the previously installed toolset active. Checksum verification does
not authenticate `SHA256SUMS`; follow the `release/VERIFY.md` procedure at the tag you install when authenticity
matters. The installer reads these variables; the installed binaries do not.

| Name | Purpose | Default or required |
| --- | --- | --- |
| `EVIDENCECTL_VERSION` | Registry Stack tag whose Evidence Gateway toolset assets are installed. A published installer pins its own tag. | Defaults to the installer's pinned tag. |
| `EVIDENCECTL_INSTALL_DIR` | Directory that receives the toolset and the `evidence`, `evidencectl`, and `evidence-oid4vci` command symlinks. | Defaults to `~/.local/bin`. |
| `EVIDENCECTL_ASSET_DIR` | Directory of already-downloaded release assets to use instead of downloading. | Optional. |

## Evidence OID4VCI supporting service

| Name | Purpose | Default or required |
| --- | --- | --- |
| `EVIDENCE_OID4VCI_CONFIG` | YAML configuration path for `evidence-oid4vci check`, `inspect`, and `serve`. Equivalent to `--config`. | Required for those three subcommands, by flag or by variable. |
| `RUST_LOG` | Tracing filter installed for every subcommand. | Defaults to `info`. |

## Base Registry Engine

The `breg` binary reads one fixed variable.

| Name | Purpose | Default or required |
| --- | --- | --- |
| `BREG_LOG` | Level for the JSON operational records the process writes on standard output. | Defaults to `info`. |

`BREG_LOG` is a closed enumeration, not a tracing filter directive. It accepts exactly `error`, `warn`, and `info`, and the level applies to the `registry_breg` target only. Any other value is refused: the process reports that the operational log level was refused and exits with status 2 instead of falling back to `info`.

### Expansion and secret references in `runtime.yaml`

`breg` substitutes `${NAME}` expressions in the string values of `runtime.yaml` after parsing it, so a substituted value is always text: it cannot add a key, change a number or boolean, or carry YAML structure, and a line break inside it stays part of the string. A bare `${NAME}` refuses the file when the variable is unset or empty, `${NAME:-fallback}` substitutes the fallback in that case, and `${NAME:?message}` refuses the file without repeating the message. A field whose name ends in `Ref` and every value under `secretProviders` refuse an expression, so the environment cannot choose which secret is read or where it comes from. The authored project and module files refuse any `${...}` expression, so the reviewed package is the one that runs. A refused substitution stops the process at startup.

Secret references use the same two grammars as Relay: `secret:env/<NAME>` names an operator-chosen environment variable and `secret:file/<name>` a file under the `secretProviders.file.root` directory. `secret:env/<NAME>` resolves only when `runtime.yaml` declares `secretProviders.environment`; without that declaration the reference is refused. See [Deploy a registry](../../operate/breg/#write-the-runtime-configuration) for the fields that take a reference.

### Bregctl

`bregctl` reads no fixed environment variable. Projects, runtime files, credentials, and packages
arrive through positional paths and explicit flags. Every command that takes `--runtime-config`
loads the runtime file the way `breg` does, so the `${NAME}` expressions in that file resolve from
the environment of the `bregctl` process.

### Base Registry Engine installer

The install script reads these variables. They are read by the script, not by the installed binaries.

| Name | Purpose | Default or required |
| --- | --- | --- |
| `BREG_VERSION` | Base Registry Engine tag to install. A published installer asset embeds its own tag and refuses an override that does not match it. | Defaults to the installer's pinned tag. |
| `BREG_INSTALL_DIR` | Directory the script installs into. | Defaults to `~/.local/bin`. |
| `BREG_ASSET_DIR` | Directory of already-downloaded release assets to read instead of downloading. Use it after verifying a release with `release/VERIFY.md` at that release's tag. | Optional. |

The script verifies the downloaded `breg` and `bregctl` binaries against the release
`SHA256SUMS` before anything reaches the install directory. It installs both together or
preserves the previous set. It does not verify release authenticity.

{/* Evidence: crates/registry-breg/install.sh; crates/registry-breg/src/main.rs; crates/registry-breg/src/runtime_config.rs. */}



## Base Registry Engine citizen gateway

`breg-mcp` and `breg-review` are supporting services beside the Base Registry Engine: an MCP gateway a chat host uses to read a citizen's own data and prepare a change-request draft, and a review page the citizen submits it from. Each reads one fixed variable for its operational log level.

| Name | Purpose | Default or required |
| --- | --- | --- |
| `BREG_MCP_LOG` | Level for the JSON operational records `breg-mcp` writes on standard output. | Defaults to `info`. |
| `BREG_REVIEW_LOG` | Level for the JSON operational records `breg-review` writes on standard output. | Defaults to `info`. |

Both are closed enumerations, not tracing filter directives. Each accepts exactly `error`, `warn`, and `info`; any other value is refused, and the process reports the error on standard error and exits with status 2 instead of falling back to `info`. `BREG_REVIEW_LOG` applies to the `breg_review` and `registry_breg_review` targets. A runtime configuration that cannot be loaded stops either process with status 1: `breg-mcp` reports it as an `ERROR` JSON record on standard output, and `breg-review` reports it on standard error. [Operate the citizen chat assistant](../../operate/breg-mcp/) lists the records worth watching.

Both services use the shared runtime loader for `${VAR}`, `${VAR:-default}`, and
`${VAR:?message}` in ordinary string values. Fields ending in `Ref` or `Refs` and
all of `secretProviders` refuse environment expressions. Credential values come
from their declared `secret:env/` or `secret:file/` provider. See
[configure the citizen chat assistant](../../configure/breg-mcp/#handle-secrets).

{/* Evidence: crates/registry-breg-mcp/src/config.rs, RuntimeConfigLoader;
    crates/registry-breg-review/src/config.rs, RuntimeConfigLoader;
    crates/registry-platform-config/src/loader.rs. */}



## Source

The fixed environment variable names in this reference are transcribed from the CLI definitions, binary entry points, and install
scripts. Relay CLI ownership is in `crates/registry-relay-v2/src/cli.rs`, with logging in `main.rs`,
secret grammar in `contract.rs`, and resolution in `startup.rs`. Evidence CLI ownership is in
`crates/registry-evidence/src/cli.rs`, logging in `main.rs`, runtime-file substitution and the
secret grammar in `config.rs`, and secret resolution in `registry-platform-config`. Evidencectl binary selection is in
`crates/registry-evidencectl/src/evidence_binary.rs`; its installer is
`crates/registry-evidencectl/install.sh`. OID4VCI CLI ownership is in `crates/registry-evidence-oid4vci/src/cli.rs`,
with logging and dispatch in `main.rs`. Base Registry Engine logging is in
`crates/registry-breg/src/main.rs` and `startup.rs`, runtime-file expansion and the secret grammar in
`runtime_config.rs` over `registry-platform-config`, and its installer is
`crates/registry-breg/install.sh`. Citizen gateway logging is in
`crates/registry-breg-mcp/src/main.rs`; review page logging is in
`crates/registry-breg-review/src/main.rs`.