Configuration
Brain Server is configured entirely through environment variables — there is no config file to edit. Most resolve in src/config.rs; a few live in the module that owns them (BIND_* in src/server/bootstrap.rs, the PRF_*/QUALITY_* retrieval knobs in src/config.rs + src/search/, CAPACITY_* in src/capacity.rs, MCP_* in src/bin/mcp.rs). This page is the complete reference, grouped by concern.
Core server
| Variable | Default | Description |
|---|---|---|
BIND_HOST | 127.0.0.1 | Bind address. 0.0.0.0 without BIND_PUBLIC set logs a loud warning and still binds (the opt-in is env presence — any value, including 0, counts); an unparseable host without BIND_PUBLIC refuses boot; and any non-loopback bind with no auth token configured refuses boot (enforce_loopback_bind_guard). |
BIND_PORT | 8765 | Listen port |
BRAIN_DB_PATH | ~/.openclaw/workspace/brain.db | SQLite database path |
BRAIN_DATA_ROOT | — | v1.0 relocation knob — root for all on-disk paths |
BRAIN_WORKER_THREADS | # cores | Tokio runtime worker threads (set 2 on Jetson) |
CORS_ORIGINS | http://localhost:3000,http://localhost:8080 | CORS allowlist |
BRAIN_CLIENT_DIST | client/dist | Directory served at /app (the web GUI) |
BRAIN_CHAIN_CHECK_SECS | 60 | How often the background audit-chain integrity check runs |
BRAIN_MULTI_DB | — | Enables per-domain SQLite files (multi-DB mode) |
BRAIN_CONTROLLER_NAME | brain-server operator | Operator/controller identity label for the Art 30 register (GET /art30); empty/unset falls back to the default. Non-secret — must not hold PII. |
MODEL_PROFILE | edge-default | Retrieval profile selector → embedding model + rerank arming. See Retrieval profiles & embedding models. |
DOMAIN_MIN_COUNT | 1 | Minimum chunk count for a domain’s routing centroid (below it, the centroid is deleted so routing skips the near-empty bucket) |
BRAIN_MODEL_MANIFEST | — | Path to a SHA-256 model manifest; when set, boot fails closed unless every pinned artifact matches |
BRAIN_REGION | — | Data-residency stamp (e.g. eu-west-1, ph-manila) written onto stored rows + certificates; unset = no stamp |
BRAIN_FCR_WINDOW_DAYS | 7 | First-contact-resolution repeat-contact attribution window on the workflow scoreboard (a recurring contact within the window counts the predecessor as not resolved) |
BRAIN_REASK_WINDOW_DAYS | 3 | Re-ask duplicate-detection window: two OPEN CRM cases with the same hashed subject within this window file a pending case_merge_suggested HITL proposal (exact hash match only — no fuzzy matching, nothing merges automatically) |
BRAIN_CASE_STATUS_KEY_FILE | — | 0600-mode salt file for the public case-status ref HMAC (BRAIN_CASE_STATUS_KEY inline as last resort). Unreadable/wide-mode file fails closed; without any salt configured, ref minting refuses |
Authentication
| Variable | Default | Description |
|---|---|---|
AUTH_TOKEN / AUTH_TOKEN_FILE | — | Opaque bearer token(s). Newline-separated = live rotation. Off if unset. Twokeys (v1.28.70): with a token FILE, line 1 = operator (full authority) and line 2 = the agent token — agent bearers authenticate as the scoped agent@loopback principal (no Admin, no purge/domains/revoke/dsar, no DPO boards; writes land as proposals under BRAIN_WRITE_POSTURE=review; the Blackout kill-switch revokes it by name). A single line keeps the legacy all-superuser posture — a boot warn is the nudge, never a forced migration. AUTH_TOKEN env content keeps the all-operator semantics. |
BRAIN_REQUIRE_AUTH | — | Refuse unauthenticated boot (v1.28.80): 1 fails startup when no token resolves; unset keeps the loopback single-user default with a loud boot warning. Any other value refuses boot (fail-closed parse). |
BRAIN_ALLOW_WILDCARD_GRANT | — | Admit total-grant scopes (v1.28.80): 1 lets a scope wildcarding both team and domain (*/*) grant; unset means such scopes grant nothing. Loud boot warning when admitted. |
AGENT_TOKEN_FILE | — | Alternative agent-token source (0600 file, one bearer string — same secret-file law as AUTH_TOKEN_FILE). When set, the agent token comes from here and the operator token file’s ENTIRE content stays operator. Boot-time source: a swapped agent file takes effect at restart (the rotation watcher follows the operator file; a line-2 edit reloads live with it). A leaked (group/world-readable) or empty agent file refuses the boot. |
BRAIN_JWT_ISSUER | — | Enables JWT mode when set + keys loaded. URL of the issuer (verified against the iss claim). |
BRAIN_JWT_KEY_DIR | ~/.config/brain-server/keys/ | Directory holding JWT signing key PEMs (mode 0700; private keys 0600). |
BRAIN_JWT_AUDIENCE | brain-server | Expected aud claim value. |
BRAIN_JWT_AZP | — | Per-application azp binding when BRAIN_JWT_AUDIENCE is tenant-wide: binds the token to one named application (the OIDC azp claim), so an audience shared across apps still admits only the app this deployment trusts. Present but blank refuses boot (fail-closed); rejections surface on /metrics as brain_jwt_azp_rejected_total. |
BRAIN_PUBLIC_BASE_URL | — | Public base URL for OIDC discovery. Never inferred from Host. |
BRAIN_UMP_KEY_DIR | ~/.config/brain-server/ump/ | Directory holding the UMP operator Ed25519 signing key (distinct from the JWT key dir). |
BRAIN_TRUST_PROXY | off | Truthy flag (1|true|yes|on): when set, trust the X-Forwarded-For header for real-IP + rate-limit accounting. There is no proxy-naming vocabulary — any other value parses as OFF. Off by default so a spoofed header can’t bypass rate limits. |
GDL provider profile (R35)
The GDL launch boundary has one server-owned provider profile. Configure all four variables together; the request body carries only the ticket.
| Variable | Description |
|---|---|
BRAIN_GDL_PROVIDER_BASE_URL | HTTPS provider endpoint, including its bounded path. Userinfo, query strings, fragments, unsafe URL shapes, and non-HTTPS schemes are refused. |
BRAIN_GDL_PROVIDER_MODEL | Server-selected provider model identifier; never accepted from the launch request. |
BRAIN_GDL_PROVIDER_SECRET_FILE | Provider bearer file, relative to BRAIN_GDL_PROVIDER_SECRET_ROOT (or an already-confined absolute path). The file must be regular, owner-only, non-empty, single-line, and within the size bound. |
BRAIN_GDL_PROVIDER_SECRET_ROOT | Absolute directory that confines the provider secret. The path and bearer are never returned in an error, readiness body, audit detail, or log. |
All four variables absent means the GDL provider is explicitly disabled. A partial, empty, or otherwise invalid profile refuses bootstrap with a fixed configuration error; if the environment changes while the process is running, /ready reports gdl_provider: "invalid" and NOT_READY. A complete, statically valid profile reports configured.
After authentication, domain Write, and the GDL-local workflow role checks, the launch boundary validates the endpoint shape before reading the secret, then performs the existing address screen and DNS pinning. Redirects are not followed. The transport uses a 5-second connect timeout, a 30-second first-byte/read timeout, a 25-second total request/body deadline, and a 4 MiB response cap. Dropping the stream receiver cancels the in-flight HTTP future; a slow-drip body still ends at the total deadline.
A provider failure after GDL admission is recorded as a terminal, non-retryable gdl_provider_failed outcome: the first launch returns HTTP 503 with that stable code, and a later launch against the same run returns HTTP 409 with the same code without replaying provider work. Provider bodies, bearer values, secret paths, and secret-bearing URLs are not persisted or logged. The provider client is constructed at the authenticated launch boundary; no provider client is stored in AppState, and this round adds no public recovery API.
The least-privilege workflow-operator role can be granted through the public role contract. It carries workflow only; the agent preset remains without workflow, and role-less or unknown-role JWTs remain denied.
Delivery bindings (R61)
The delivery loop’s standing authority over external systems is a server-owned
bindings profile — the structural sibling of the GDL provider profile above:
complete-or-absent, resolved and validated at boot, and never selected by a
request. Consent to an external authority is given by configuring a binding
here and withdrawn by setting active = 0 on its row — a request can never
create or widen an authority.
| Variable | Description |
|---|---|
BRAIN_DELIVERY_BINDINGS | JSON array of binding descriptors (≤ 64 KiB, no control characters). Each entry needs domain (≤ 100 chars), target_kind (from the closed TARGET_KINDS vocabulary), target_ref (≤ 200 chars), endpoint (validated to the exact API host at boot — an operator typo must not become a bearer sent somewhere else), and secret_file_name (a FILE NAME, never a path — a separator refuses, so a configured value cannot escape the root). A capabilities string is optional; missing = the read-only default (reads, no intents), never a wildcard. |
BRAIN_DELIVERY_BINDINGS_SECRET_ROOT | Absolute directory per-binding secret file names resolve against; root-confined by the reader on every use. Required when BRAIN_DELIVERY_BINDINGS is set. |
Absent BRAIN_DELIVERY_BINDINGS = no bindings (the default posture). A partial,
empty, oversized, or otherwise invalid profile refuses bootstrap with a
fixed delivery bindings configuration is invalid or incomplete error that
carries no configured value — an operator’s target ref and secret name must not
ride a boot log. Capabilities parse with refusal and endpoints pass the API-host
assertion before the profile is stored, so boot provisions from the same value
it validated.
Retrieval & expansion
| Variable | Default | Description |
|---|---|---|
PRF_ENABLED | true | PRF query expansion on/off |
PRF_DEPTH | 10 | PRF expansion depth |
PRF_TERMS | 5 | Number of expansion terms |
PRF_MAX_RANK | 5 | Max rank for expansion candidates |
QUALITY_OVERLAP_WEIGHT / QUALITY_GAP_WEIGHT / QUALITY_RR_WEIGHT / QUALITY_LEX_WEIGHT | 0.4 / 0.3 / 0.2 / 0.1 | The retrieval quality estimator’s fusion weights (overlap / gap / reciprocal-rank / lexical agreement). Invalid values fall back to the default per key. |
QUALITY_AGREEMENT_MIN | 2 | Minimum agreeing-retriever count before the estimator expresses any confidence. |
QUALITY_GAP_THRESHOLD / QUALITY_CONFIDENCE_THRESHOLD / QUALITY_RERANK_THRESHOLD | 0.023 / 0.6 / 0.85 | Quality-estimator decision thresholds (abstention / low-confidence / recommend-reranker bands). Invalid values fall back to the default per key. |
BRAIN_RECALL_ROUTING_ENABLED | true | Automatic retrieval routing (v1.13.1). false restores legacy shim behavior. |
BRAIN_GRAPH_RESCUE_ENABLED | true | Complexity-gated graph rescue pass on abstention (v1.12) |
Retrieval profiles & embedding models
MODEL_PROFILE selects the retrieval profile. (BRAIN_MODEL_PROFILE is not
a config key; it appears only inside a re-embed hint string.) Each resolves to an
embedding model via config::model_id_for_profile + embed::embedder_for_profile. Note: the old
multilingual profile name is wrong — potion-base-2M is an English model (distilled from
BAAI/bge-base-en-v1.5), not multilingual. It was renamed compact (the smallest static
model); MODEL_PROFILE=multilingual still resolves to the same profile for backward compatibility.
| Profile | Embedding model | Dim | Backend | Rerank tier armed at boot |
|---|---|---|---|---|
edge-default (default) | minishlab/potion-retrieval-32M | 512 | static model2vec | no |
quality-local | minishlab/potion-retrieval-32M | 512 | static model2vec | yes |
compact (was multilingual) | minishlab/potion-base-2M | 512 | static model2vec | no |
air-gapped | minishlab/potion-retrieval-32M | 512 | static model2vec | no |
enterprise | BAAI/bge-m3 (--features neural-embed) | 1024 | FastEmbed BGEM3Q | yes |
desktop | Alibaba-NLP/gte-base-en-v1.5 (--features neural-embed) | 768 | FastEmbed GTEBaseENV15 | yes |
enterprise/desktop require the neural-embed Cargo feature (pulls fastembed); without it they
fall back to the static default model. The migration creates vec_knowledge at the active
embedder’s store_dim() and stamps embedding_dim — switching profiles across dimensions fails
closed (a 1024-d DB refuses an edge-default start with the --re-embed instruction).
Rerank tier
The cross-encoder rerank tier (rerank-tier Cargo feature) runs after RRF fusion on the profiles
that arm it (see table above); it is off by default (edge stays pure-static, the v0.9.5
doctrine). The server sets BRAIN_RERANK_ENABLED=1 at boot for those profiles. It is fail-open
(a model/output fault leaves the RRF order untouched) and boot-warmed (never downloaded in the
request path). Model resolution, in order: the golden mixedbread-ai/mxbai-rerank-large-v1
(BYO-ONNX, int8) loaded from a local dir, falling back to the in-enum BAAI/bge-reranker-v2-m3.
| Variable | Default | Description |
|---|---|---|
BRAIN_RERANK_MODEL_DIR | models/mxbai-rerank-large-v1/ (never loads) | Local dir holding the mxbai-rerank-large-v1 files (onnx/model_quantized.onnx + the 4 tokenizer files) for the BYO-ONNX seam. Supply-chain guard: a CWD-relative path is REFUSED with a warning — the compiled default is inert by design; only an ABSOLUTE path (via this env) loads the mxbai model, otherwise the tier falls back to the in-enum bge-reranker-v2-m3. |
BRAIN_RERANK_TOP_N | 50 | Max candidates scored per rerank call; beyond this the provenance rerank_truncated flag reports the drop honestly. |
Write-back gating (v1.14)
PII control is deterministic read-time output redaction (always-on for
principals without pii:read/Admin); there is no write-time placeholder vault
and no BRAIN_REDACT_PII knob (removed v1.20.19).
| Variable | Default | Description |
|---|---|---|
INJECTION_POLICY | quarantine | quarantine | reject | allow — how prompt-injection-suspicious input is handled. |
BRAIN_INGEST_SKIP_PATTERNS | — (off) | Newline- or comma-separated prefixes; text beginning with any is skipped at ingest (e.g. `!redacted,```). Opt-in; default behavior unchanged. |
BRAIN_INJECTION_CLASSIFIER | on | Layer-2 classifier selector (v1.28.71 “Pores” auto-on): on/unset loads when the default artifact ~/.config/brain-server/models/injection-classifier/{model.onnx,tokenizer.json} resolves (absent posture otherwise, layer 1 unaffected); off opts out; any other value is an explicit model path — a non-existent path refuses the boot (fail-closed). Echoed as injection_classifier: on|off|absent on /health/db. Operators who prefer an external verdict (a guard-model HTTP endpoint in front of ingest) can leave this off and enforce at their own seam; layer 1 still runs. |
BRAIN_INJECTION_TOKENIZER | — | Tokenizer used by the injection classifier (required alongside an explicit BRAIN_INJECTION_CLASSIFIER path) |
BRAIN_INJECTION_THRESHOLD_HIGH | 0.9 | Classifier banding: score ≥ this → reject |
BRAIN_INJECTION_THRESHOLD_LOW | 0.7 | Classifier banding: score ≥ this (below high) → quarantine |
BRAIN_PROPOSAL_TTL_SECS | 604800 (7 d) | How long a proposal can sit pending before auto-expire (audited). |
BRAIN_APPROVAL_QUORUM | 1 | Two-principal approvals (v1.28.80): 2 requires two distinct approvers before a proposal promotes (first returns pending_second, same-principal repeat refused). Any other value refuses boot. |
BRAIN_EXPORT_MAX_BYTES | 1073741824 (1 GiB) | Ceiling on the materialized GDPR export bundle; a bare byte count overrides, anything else (including 0) refuses boot. The chunked export path is the escape hatch past it. |
BRAIN_DSAR_WINDOW_DAYS | 30 | GDPR Art 17 response window shown on DSARs |
BRAIN_DSAR_LEDGER_DAYS | 30 | Retention window for the DSAR ledger |
BRAIN_RETENTION_ENABLED | enabled (true) | Per-kind query-time retention expiry; false|0|no|off restores exact legacy behavior (only per-chunk expires_at governs decay) |
BRAIN_RETENTION_KIND_DAYS | JSON map over SDK defaults | Per-kind overrides as a JSON map ({"fact":365,"episodic":30}), merged over the built-in table — fact 365, episodic 30, procedure/step/decision 730, entitlement 1825 (single owner: crates/brain-engine-sdk/src/policy.rs). Unknown keys are accepted; invalid JSON or non-integer values degrade to the default per key |
BRAIN_WRITE_POSTURE | open | Agent-write posture (Seatbelt): open writes insert directly; review routes the six agent-facing write surfaces through the proposal queue instead (agents propose, operators dispose). An unknown value refuses boot. v1.28.75: the installer writes review into the plist only when NO explicit posture is set yet (new-install default) — an operator-set value (including a deliberate open) is never stomped by a re-run; the compiled default stays open so unattended upgrades never change behavior |
BRAIN_RBAC_ROLELESS_POSTURE | pass | The RBAC evaluator’s posture for a principal whose roles claim is EMPTY. pass (default) keeps the shipped back-compat: roles are additional restrictions for those who hold them, and a token with no roles is not default-denied. deny is the opt-in for a deployment that has minted roles at its IdP and wants a token with no roles to get nothing. An unknown value refuses boot (the BRAIN_WRITE_POSTURE pattern), and the resolved value is printed at boot and echoed by GET /ops/authz/explain. The middleware itself has NO off switch: this knob chooses how a role-less token is treated, not whether RBAC runs |
BRAIN_SYNCHRONOUS | full | Per-connection SQLite durability on the MAIN pool (Headroom): full fsyncs every commit (the pre-1.28.59 effective behavior — a fresh pooled connection always ran the compile default); normal is the WAL-mode tuning posture (commit fsyncs move to checkpoint time; on power loss recent commits may roll back but the DB stays uncorrupted). Applied beside busy_timeout=5000 at every pooled connection’s init; the applied policy is echoed by /health/db under durability. An unknown value refuses boot. |
BRAIN_WAL_AUTOCHECKPOINT | 1000 | WAL autocheckpoint threshold in pages (Headroom) — the SQLite compile default and the pre-1.28.59 effective value. Lower = checkpoints run more often, bounding brain_wal_pages_pending lag at the cost of more frequent checkpoint I/O. Integer, 1..=65536; 0 (autocheckpoint off — unbounded WAL) and out-of-range values refuse boot |
BRAIN_LOOM | off | Opt-in CPU parallelism for the two loom fan-out sites (Loom): the batch-ingest embed stage and the consolidate near-dup scan’s pure-CPU preprocessing. Active only when ALL THREE hold: the loom cargo feature is compiled in, the capacity target is not jetson, and this var is 1. 0/unset keeps the byte-identical serial path; any other value refuses boot (fail-closed parse). The pool is capped at min(cores-1, 4) so ingest never starves the tokio blocking pool; the resolved decision is echoed by /health/db as loom: active (N threads) or off:no-feature / off:jetson / off:env. No cross-chunk reduction exists by design — every fan-out is an ordered per-item map (loom_preserves_fused_ranks) |
BRAIN_ALERT_WEBHOOK_URL / BRAIN_ALERT_WEBHOOK_SECRET | — | Outbound alert webhook sink (resolve → validate → pin egress: a private/metadata sink refuses the boot unless BRAIN_EGRESS_ALLOW_PRIVATE=1) |
Observability & audit (v1.15)
| Variable | Default | Description |
|---|---|---|
BRAIN_AUDIT_CHAIN_KEY_FILE | — | Explicit path to the audit-chain HMAC key. Resolution order: inline BRAIN_AUDIT_CHAIN_KEY (hex) → this file → audit-chain.key beside the DB → a generated 0600 key. A resolution failure is a loud warning, not a boot refusal; writes to hmac256-epoch DBs fail closed per-write until a key resolves |
BRAIN_AUDIT_SIGNING_KEY_FILE | — | Explicit path to the Art 50/decision-provenance Ed25519 signing key (0600; installer-provisioned). Absent = marks are present but visibly unsigned |
BRAIN_AUDIT_READ_EVENTS | on (JWT) / off (loopback) | When on, /recall, /search, /get/{id}, /multi-get emit hash-chained audit rows (no content, no raw query). |
BRAIN_AUDIT_READ_SAMPLE_RATE | 1.0 | Read-event sampling (0.0..=1.0); 1.0 = every read event. |
BRAIN_AUDIT_RETENTION_DAYS | unset = forever | Audit retention window; when set, expired rows are pruned and the chain re-anchored. Deployers subject to AI Act Art 26(6) guidance: set ≥180. |
BRAIN_DSAR_WEBHOOK_URL / BRAIN_DSAR_WEBHOOK_SECRET | — | Opt-in Art 19 onward-notification: on a completed DSAR purge, POSTs {subject, certified_at, certificate_id} HMAC-SHA256-signed. Fail-soft. |
BRAIN_EGRESS_ALLOW_PRIVATE | — | The ONE egress opt-out (Deadbolt): 1 admits a private/loopback/metadata webhook sink at boot with a LOUD warn (the sink stays DNS-pinned). Unset = private sinks refuse the boot; any other value refuses the boot (fail-closed parse). |
BRAIN_SSE_REAUTH_SECS | 30 | SSE heartbeat re-auth cadence (v1.28.86): re-consults the identity kill-switch every N seconds on long-lived streams (revoked → {"revoked":true} frame then close). 0 = admission-only (the pre-.86 ceiling, explicit opt-in, loud boot warn); 1–3600 allowed; anything else refuses the boot. |
BRAIN_OTEL_ENABLED / BRAIN_OTEL_ENDPOINT | enabled on --features otel builds / http://127.0.0.1:4318/v1/traces | OpenTelemetry OTLP export. Kill-switch only: 0|false|no|off disables the compiled-in exporter (a default build compiles no exporter at all) |
CORS_METHODS | GET,POST,PUT,DELETE,OPTIONS | Allowed CORS methods |
CORS_HEADERS | content-type,authorization | Allowed CORS request headers |
Features & kill switches
| Variable | Default | Description |
|---|---|---|
BRAIN_SUGGEST_ENABLED | true | v1.9 kill switch: when false, the /suggest/* routes return 501. |
BRAIN_RECALL_GRAPH_ENABLED | true | v1.12 kill switch for the graph (Personalized PageRank) recall leg — false disables it process-wide (per-request graph=false still works). |
BRAIN_MAX_DOMAIN_DBS | 256 | v1.27.16 cap on registered per-domain SQLite files; registration beyond the cap fails closed (507 insufficient_storage). |
Capacity envelope (v0.9.9)
| Variable | Default | Description |
|---|---|---|
CAPACITY_MAX_DOCS / CAPACITY_MAX_DB_MIB / CAPACITY_MAX_RSS_MIB / CAPACITY_MAX_P95_MS | capacity profile | Tighten the /health/db capacity envelope (desktop RSS default 1 024 MiB, docs 50 000, DB 2 048 MiB; jetson 512 / 10 000 / 512; _P95_MS the bench-only search-latency ceiling). Writes over the envelope return HTTP 507; reads are never blocked. |
Webhooks, standby, keys & misc (the unglamorous but real knobs)
| Variable | Default | Description |
|---|---|---|
BRAIN_WEBHOOK_TIMESTAMP_REQUIRED | off | Enforce the Standard-Webhooks timestamp tolerance on webhook receivers (replay-window hardening). |
BRAIN_REQUIRE_WEBHOOK_SIGNING | required | Outbound webhook signing posture (v1.28.86): unset/1 = REQUIRED — a sink URL without its secret refuses the boot; explicit 0 admits unsigned ALERT sends with loud warn + /ready webhook_signing:off + signed:false on every payload. The DSAR/Art-19 path ignores the opt-out (refused unconditionally). Any other value refuses the boot. |
BRAIN_SIGNAL_WEBHOOK_SECRET_FILE / BRAIN_KB_FEEDBACK_SECRET_FILE | — | Per-surface HMAC secrets (Signal gateway; KB feedback relay). |
BRAIN_STANDBY_DIR | ~/.local/share/brain-server/standby | Warm-standby follower directory (brain standby start/status/promote-check). |
BRAIN_CAPACITY_TARGET | jetson (conservative) | The capacity envelope tier. ONLY the literal desktop selects the desktop envelope; unset, empty, and unknown values all resolve to jetson (fail-closed to the smaller envelope). Also gates the loom CPU-parallelism tier. |
BRAIN_RSS_RESTART | — | RSS watchdog opt-in (boolean 1|true|yes|on): when set, a breach of the capacity envelope’s max_rss_mib on two consecutive samples makes the process exit(1) so the supervisor restarts it; default (unset) is log-only. The threshold itself is the envelope’s CAPACITY_MAX_RSS_MIB, not this var. |
BRAIN_CONNECTOR_CONFIG_DIR | $HOME/.config/brain-server/connectors | Connector config dir (same literal path on every platform); included in backups. |
BRAIN_AUDIT_CHAIN_KEY / _FILE | — | Key for the hmac256 audit-chain epoch (absent = SHA-256 links; keyed chains refuse to write without the key). |
BRAIN_AUDIT_SIGNING_KEY / _FILE | — | Art.12 decision-record signing key. |
BRAIN_BACKUP_PASSPHRASE_FILE | — | Backup/restore passphrase for brain backup/restore (the --passphrase-file flag reads the same seam; a passphrase is REQUIRED — no unencrypted backup exists). Note: the inline BRAIN_BACKUP_PASSPHRASE env is read only by the brain-migrate-rehearse helper binary, not by brain backup/restore. |
BRAIN_TOKEN / BRAIN_TOKEN_FILE | ~/.config/brain-server/auth-token | The brain CLI’s bearer resolution ladder (server side: AUTH_TOKEN_FILE → AUTH_TOKEN). |
BRAIN_DPO_CONTACT / BRAIN_SECURITY_CONTACT | — | DPO + security contact strings surfaced on /health/db and /.well-known/security.txt. |
BRAIN_ENGINE_EXEC_ALLOWLIST / BRAIN_ENGINE_HTTP_ALLOWLIST / BRAIN_ENGINE_WORKDIR | — | The hostcall door’s allowlists + workdir (the engine’s tool-effect boundary). |
BRAIN_ENGINE_SANDBOX_BACKEND | inherited (the platform OS backend under the enterprise model profile) | The exec path’s OS boundary: inherited (screened, same-user), sandbox-exec (macOS Seatbelt, deny-default profile), or landlock (Linux LSM). Unknown values refuse exec fail-closed; the profile text is compiled-in and never operator-supplied. |
BRAIN_LEGAL_DB_PATH | — (unset) | The curated legal-rules DB file the /legal/rules diff reads. UNSET by default: the legal route refuses NAMED (legal_db_unconfigured) and everything else is unaffected. When set, the file is opened READ-ONLY per request (no restart needed after a DPO import) and never written by the server. See docs/legal-db-import.md for the DPO import procedure. |
MCP_TRANSPORT / MCP_HTTP_PORT / MCP_HTTP_ADDR / MCP_HTTP_TOKEN | stdio | The MCP binary’s transport: stdio (default) or Streamable HTTP + SSE. See docs/mcp.md. |
PACKING_WEIGHTS | built-in | Evidence-packing weight overrides (advanced). |
BRAIN_STEWARD_BIN | — | Override the workflow-crank harness binary. TWO seams read it: the server-side crank (resolve_harness_bin) requires an ABSOLUTE path — relative refuses (steward_bin_relative), PATH is never consulted, and the fallback is the binary beside the kernel; the CLI crank (brain workflow crank) accepts the override verbatim, then falls back to the binary beside brain, then to PATH. Point the override at an absolute path and both seams behave identically. |
The source of truth for every tunable is
src/config.rsand the owning modules named above (src/server/bootstrap.rs,src/capacity.rs,src/search/,src/bin/mcp.rs) in the repository.
Next steps
- Installation — applying these in practice.
- Security — how the auth variables work together.
- API Reference — the contract those configs gate.
Auxiliary binaries & harness (client-side env)
These are read by the operator CLIs and optional binaries — not the server process — so they sit outside the main table.
| Variable | Default | Description |
|---|---|---|
BRAIN_URL | http://127.0.0.1:8765 | Base URL every client-side binary addresses (brain, mcp, bench, the connector stubs) |
BRAIN_MCP_SCOPE | full | MCP dispatch scope (read|full, fail-closed parse): read refuses brain_ingest, ump.remember, ump.revise, ump.forget at the dispatch seam and annotates them x-brain-scope: read-denied in tools/list |
BRAIN_GH_APP_TOKEN | — | GitHub App installation token for brain-connector-gh (the binary refuses to run on the placeholder) |
BRAIN_EVAL_JUDGMENTS | — | Judged-query fixture path for bench --eval (missing file fails the eval run) |
BENCH_* harness knobs (BENCH_SCALES, BENCH_SEARCHES, BENCH_CLIENTS,
BENCH_SEED, BENCH_ENVELOPE, …) are documented in the bench binary’s
own header (src/bin/bench.rs) with worked invocations in
BENCHMARKS.md.