Skip to content

Environment variables

Subspace is configured almost entirely through environment variables read at boot. There is no separate config file: set a variable before starting the server (or export it in your process manager / systemd unit) and it takes effect on the next boot. This page is the exhaustive reference; see Self-hosting for a narrative setup walkthrough.

The baseline variables every install cares about: where data lives, what port and host to bind, and which deterministic fakes to use in dev/test.

Variable Default Purpose
SUBSPACE_HOME ~/Subspace Root data directory: embedded Postgres (pg/, unix socket only, no TCP) and content-addressed blobs (blobs/). Migrations run transactionally on every boot.
SUBSPACE_PORT 4780 HTTP/WebSocket port the server listens on.
SUBSPACE_HOST 127.0.0.1 Bind address. Only 127.0.0.1, localhost, or a tailnet address are legal; the server refuses to boot on a public bind (see Security and trust).
SUBSPACE_SEED unset Set to mock-world to seed the shared e2e/demo fixture (distinct inboxes, calendars, CRM rows) on first boot.
PROVIDERS unset Set to fake to swap every external seam (Jupyter kernel, search embedder, mail/calendar/IM providers, LLM calls, dev-login) for deterministic fakes. Used by tests and pnpm dev:sandbox.
SUBSPACE_SHELL $SHELL Shell binary terminals spawn on the server host.
SUBSPACE_AUTH unset Set to off to disable identity entirely (legacy single-user behavior). The server refuses to boot with this on a non-loopback SUBSPACE_HOST.
SUBSPACE_DEVICE_TOKEN unset Bearer device token a non-browser client (desktop, mobile) stamps on every request; see Device pairing.
SUBSPACE_MODEL claude-sonnet-5 Model id used for agent runs, event-triage classification, mail-rule matching, and other LLM seams (Vercel AI SDK + Anthropic).
ANTHROPIC_API_KEY unset Seeds the llm.anthropic capability in the capability broker on first boot (insert-only; see Tools and approvals).
OPENAI_API_KEY unset Needed for real embeddings (text-embedding-3-small) when PROVIDERS=fake is not set; also seeds the llm.openai capability.

Set any WAL-G repository variable to turn on continuous archiving; the nightly backup job and monthly restore drill pick the rest up automatically. See Backup and restore for the full lifecycle.

Variable Default Purpose
WALG_S3_PREFIX, WALG_FILE_PREFIX, WALG_GS_PREFIX, WALG_AZ_PREFIX, WALG_SSH_PREFIX, WALE_*_PREFIX unset Any one of these (standard WAL-G repository variables) turns on PostgreSQL archive_command (archive_timeout=60s) and enables the 02:10 nightly backup-push job, which retains 14 full backups.
SUBSPACE_WALG_BIN bundled WAL-G 3.0.8 Dev override for the WAL-G binary path.
SUBSPACE_BLOB_REPLICA_URL unset Enables the durable blob-replicator outbox consumer: referenced blobs upload to ab/cd/<sha256> at this URL; deletes become seven-day delayed tombstones.
SUBSPACE_BLOB_REPLICA_TOKEN unset Bearer auth for SUBSPACE_BLOB_REPLICA_URL.
RESTIC_REPOSITORY unset With this set, the same nightly job snapshots okf/ (the canonical markdown dump) via restic and retains 14 daily snapshots.
SUBSPACE_RESTIC_BIN restic Dev override for the restic binary path.

Configuring SUBSPACE_GITOPS_REPO turns on declarative config deployment from a git repo: config pages and the plugin set sync from the repo on boot and on a poll interval. See GitOps for the full model.

Variable Default Purpose
SUBSPACE_GITOPS_REPO unset Clone URL or local path of the config repo. Setting this enables gitops sync.
SUBSPACE_GITOPS_BRANCH main Branch to sync from.
SUBSPACE_GITOPS_PATH repo root Subdirectory within the repo holding pages/** and an optional plugins.json.
SUBSPACE_GITOPS_POLL 300 (seconds) Poll interval after the blocking boot sync; 0 means boot-only (no poll).
SUBSPACE_GITOPS_MODE readonly Set to write-back so managed pages become editable again: every edit exports back to the repo as a commit.
SUBSPACE_GITOPS_WRITEBACK_BRANCH the sync branch In write-back mode, picks direct-to-branch commits (default) or a PR side branch.
SUBSPACE_GITOPS_TOKEN unset Seeds the gitops.git.token secret: private HTTPS remotes authenticate through GIT_ASKPASS, injected per git invocation. Absent = ambient auth (ssh-agent, credential helper).
SUBSPACE_GITOPS_GIT_USERNAME x-access-token Overrides the basic-auth username paired with SUBSPACE_GITOPS_TOKEN.
SUBSPACE_GITOPS_WEBHOOK_SECRET unset Seeds the gitops.webhook.secret used to verify POST /gitops/webhook (GitHub/Gitea HMAC or GitLab token header). No secret configured means the webhook 403s for everyone.
SUBSPACE_PLUGINS unset Comma/space-separated npm plugin specs to reconcile at boot; a repo-pinned plugins.json (when gitops is configured) wins over this.

Subspace runs as a single all-in-one process by default. Opt-in posture B splits it into a trusted web plane and a secret-scrubbed worker plane over the same home, selected with a CLI flag rather than an env var:

Terminal window
subspace-server --role=web # tier 0: HTTP/WS/tRPC, Postgres, approvals, broker routes
subspace-server --role=worker # tier 1: agent workflow world, scrubbed env, broker RPC only
subspace-server --role=all # default: single process, both roles
Variable Default Purpose
SUBSPACE_WORKER_URL :4781 Loopback control API the web role uses to start/resume workflows on the worker role.

Provider and platform credentials are never read ambiently by tool code; they seed the encrypted ops.secrets table once at boot (insert-only, a rotated row is never clobbered by a stale env var) and are acquired through the capability broker from then on:

Variable Seeds capability
SLACK_BOT_TOKEN slack.send
SLACK_APP_TOKEN slack.socket
TELEGRAM_API_ID, TELEGRAM_API_HASH, TELEGRAM_SESSION telegram
GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET google.oauth (also Google login)
DEEPGRAM_API_KEY deepgram.stt
ANTHROPIC_API_KEY llm.anthropic
OPENAI_API_KEY llm.openai
WANDB_API_KEY wandb.api
DAGSTER_API_TOKEN dagster.api
DEVIN_API_KEY devin.api
DROPBOX_ACCESS_TOKEN provider.dropbox
MICROSOFT_GRAPH_ACCESS_TOKEN, MICROSOFT_GRAPH_DRIVE_ID provider.sharepoint
SUBSPACE_GITOPS_TOKEN gitops.git.token
SUBSPACE_GITOPS_WEBHOOK_SECRET gitops.webhook.secret

Variables that override binaries, timings, or debug behavior. Most are only relevant when developing Subspace itself or writing e2e fixtures.

Variable Default Purpose
SUBSPACE_CLAUDE_BIN claude Overrides the Claude Code CLI binary the coding-agent dispatch ladder (code.claude.run) spawns.
SUBSPACE_BD_BIN bd Overrides the bd issue-tracker CLI binary code.task.create shells out to.
SUBSPACE_OS_EXEC unset Set to 1 to enable the os.exec agent tool (also implicitly on under PROVIDERS=fake).
SUBSPACE_CONTAINERS unset Set to 1 to enable the real docker containers.* agent tools.
SUBSPACE_DOCKER_BIN docker Overrides the docker binary for containers.* (e2e points this at a fixture).
EVALS_LIVE unset Set to 1 to run the eval harness against the real model instead of recorded fixtures (SUBSPACE_MODEL). See Evals.
SUBSPACE_GRADER_MODEL claude-haiku-4-5 Model used for the cheap post-run observation grader and the weekly pattern clusterer.
RUN_INTROSPECTION off off | observe | full (gates post-run observation grading and pattern clustering).
SUBSPACE_INDEX_DEBOUNCE_MS 0 under PROVIDERS=fake, 1500 otherwise Debounce window for the search indexer; 0 means synchronous (embed on every commit).
SUBSPACE_MCP_SERVERS unset JSON array ([{name, command, args?}], stdio) of MCP servers to bind, for names not claimed by an mcp/ page. Page-defined servers take precedence per name. See MCP servers.
SUBSPACE_DEVIN_SWEEP_MS 120000 (2 min) Poll interval for the Devin session status sweep.
SUBSPACE_MLOPS_SWEEP_MS 20000 (20s) Poll interval for the mlops run-watcher sweep.