Skip to content

Configuration

A corralai brain is configured entirely through environment variables — there is no config file to hand-edit, so dev mode and a production deployment run the exact same code paths. Everything below is optional; a brain with no environment set at all boots in dev mode against sensible ~/.claude/* defaults.

Every store defaults under ~/.claude/; point them elsewhere to relocate a brain’s data or to isolate a test/demo brain.

Variable What it is Default
CORRALAI_ADDR Listen address (loopback by default; front it with a tunnel/proxy) 127.0.0.1:9019
CORRALAI_DB Coordination SQLite (missions, tasks, claims) ~/.claude/corralai_coord.sqlite3
CORRALAI_MEMORY_DB Memory DuckDB (the searchable knowledge store) ~/.claude/corralai_memory.duckdb
CORRALAI_MEMORY_DIR Where new memory entries are written (markdown files) ~/.claude/projects/default/memory
CORRALAI_RECORDINGS_DB Recordings DuckDB for scrubbed replay exports ~/.claude/corralai_recordings.duckdb
Variable What it is Default
CORRALAI_TASK_STALL_SECONDS How long a claimed-but-untouched task may sit before the brain treats it as stalled and lets the herd reclaim it 300

This is the knob behind graceful degradation over deadlock: a worker that claims a task and then dies (crash, quota blip) must never strand the mission — after the stall window its lease is reclaimable by the rest of the herd.

With CORRALAI_OIDC_ISSUER unset, auth is disabled (dev mode — any caller is trusted). Set it to any OIDC provider to turn auth on.

Variable What it is
CORRALAI_OIDC_ISSUER / CORRALAI_OIDC_AUDIENCE The primary trusted OIDC issuer + expected audience (empty issuer ⇒ auth off)
CORRALAI_OIDC_CLIENTS Extra trusted clients, "issuer|aud,issuer|aud"
CORRALAI_ALLOWED_PRINCIPALS Day-0 seed of member emails (the DB is canonical afterward)
CORRALAI_ADMIN_PRINCIPALS Day-0 seed of superuser emails
CORRALAI_ALLOWED_HOSTS Accepted Host headers (add the public hostname a tunnel exposes)
CORRALAI_MEMORY_OWNERS Emails allowed to read/write memory
Variable What it is
CORRALAI_GIT_TOKEN Forge PAT for clone + PR; empty ⇒ repo engine off unless CORRALAI_REPO_ENABLE=1
CORRALAI_FORGES Multi-forge config (GitHub / GitLab / Gitea) — each token is only ever used against its own host
CORRALAI_REPO_WORKSPACE Root dir for per-mission working copies

The token lives only in the brain — it is scrubbed from the environment, injected into a push URL for one call, and never written to .git/config. See Trust & security.

Variable What it is
MODEL_BACKEND / OPENAI_BASE_URL Bring your own model — point at any OpenAI-compatible endpoint (local Ollama to frontier)
CORRALAI_EMBED_URL Embeddings endpoint for reference RAG + semantic code search
CORRALAI_MOTHERDUCK Fleet-sync target (md:<db> or a .duckdb path); empty ⇒ sync off
CORRALAI_BRAIN_ID Tag for this brain’s rows in the fleet (default: hostname)

Provider API keys and the worker token are configured with the embedded keystore rather than left in a plaintext env file:

Terminal window
corral secret set OPENAI_API_KEY # value read from stdin — never a CLI arg
corral secret set OPENROUTER_API_KEY # one OpenRouter key covers gemini + gpt + claude
corral secret list # names only, never values
corral secret rm GEMINI_API_KEY

Each secret resolves through env var → OS keyring → an age-encrypted file (first hit wins, so an env var always overrides a stored value). On a desktop the OS keychain (macOS Keychain, Windows Credential Manager, Linux Secret Service) holds it directly. On a headless server it’s an age-encrypted store under your config dir (CORRAL_CREDS_DIR to override), whose encryption identity comes from CORRAL_AGE_IDENTITY, a systemd credential (age-identity), or a 0600 key file — and fails closed if that source is present but malformed, so it never silently orphans your store. Secret values are redacted to a fingerprint in every log and error, and corral-agent reads OPENAI_API_KEY / ANTHROPIC_API_KEY / CORRALAI_BRAIN_KEY through the keystore — so they need never sit in the process environment at all.

See Running it for how these come together in dev vs. auth-on, and Multi-model herds for the model story.