Skip to main content

Environment Variables

All Crewship configuration can be set via environment variables. These override values from the YAML config file. The mapping is defined in applyEnvOverrides in internal/config/config.go.
As of PR #446, no env vars are required for first boot — secrets are auto-generated and persisted. Set variables here only to override a default or hand a secret to an external manager. Jump to a group: Server · Container · Storage · Auth · Encryption · Keeper · CLI client · Installer.

Server

VariableDefaultDescription
CREWSHIP_HOST0.0.0.0Server listen address
CREWSHIP_PORT8080Server listen port

IPC

VariableDefaultDescription
CREWSHIP_SOCKET_PATH/tmp/crewship.sockUnix socket path for internal IPC

Container

VariableDefaultDescription
CREWSHIP_CONTAINER_PROVIDERdockerContainer provider: docker, apple, auto (Kubernetes provider on the v0.2 roadmap)
CREWSHIP_CONTAINER_NETWORKcrewship-agentsDocker bridge network name
CREWSHIP_CONTAINER_PREFIX(empty)Container name prefix for multi-instance isolation
CREWSHIP_RUNTIME_IMAGEdebian:bookworm-slimDefault agent runtime image for crews without an explicit runtime_image. Any glibc-based Linux image works — Crewship bind-mounts the sidecar and entrypoint at runtime.
CREWSHIP_SIDECAR_ENABLEDfalseEnable sidecar proxy (true or 1)
CREWSHIP_SIDECAR_PATHautodetectedAbsolute host path to the crewship-sidecar Go binary. See Devcontainers reference for autodetect order.
CREWSHIP_ENTRYPOINT_PATHautodetectedAbsolute host path to entrypoint.sh.
CREWSHIP_SKIP_SIDECAR(unset)Set to 1 to bypass fail-fast autodetect (tests only — never set in production).
CREWSHIP_CONTAINER_PREFIX is essential for multi-instance deployments. Without it, multiple Crewship instances will create containers with colliding names like crewship-team-engineering.

Storage

VariableDefaultDescription
CREWSHIP_DATA_DIR~/.crewshipRoot directory for crewship.db, output, chats, logs, skills, and workspace memory. Resolved by database.DefaultDataDir — every admin / backup / doctor / start path flows through it.
DATABASE_URL(unset)Direct DSN override for crewship admin only. Bypasses CREWSHIP_DATA_DIR resolution. Use when running admin commands against a SQLite file outside the standard data-dir tree.
CREWSHIP_STORAGE_PROVIDERlocalfsStorage backend: localfs or s3
CREWSHIP_STORAGE_BASE_PATH/var/lib/crewshipBase path for local file storage
CREWSHIP_LOG_PATH/var/log/crewshipPath for log files

State

VariableDefaultDescription
CREWSHIP_STATE_PROVIDERbboltState store: bbolt (postgres on the v0.2 roadmap)
CREWSHIP_BOLT_PATH/var/lib/crewship/state.dbBoltDB file path

Public-facing URL

VariableDefaultDescription
CREWSHIP_PUBLIC_URL(unset)Externally-reachable base URL of the Crewship server. Required for password-recovery emails and for /expose-port (port-exposed agent containers). Without it the recovery email link is degraded and /expose-port returns 503 with a CREWSHIP_PUBLIC_URL not set log line.

Origin enforcement (CORS / EnforceOrigin)

VariableDefaultDescription
CREWSHIP_ALLOWED_ORIGINS(unset — same-origin only)Comma-separated allowlist of cross-origin scheme://host[:port] values that may issue state-changing requests (POST/PUT/PATCH/DELETE). Parsed by internal/api/origin_check.go; matched as exact host equality after url.Parse (no suffix wildcards, no IDN tricks — those previously enabled bypasses). Required whenever the frontend is served from a different origin than the daemon (cross-origin Playwright E2E, separate :3001 dev frontend on nuke-reset envs, reverse-proxy host with custom domain). dev.sh writes this automatically alongside NEXTAUTH_URL/CREWSHIP_PORT so the value survives ./dev.sh nuke. Example: CREWSHIP_ALLOWED_ORIGINS=https://app.crewship.io,https://staging.crewship.io.

Rate limiting & proxy trust

VariableDefaultDescription
CREWSHIP_TRUSTED_PROXY_CIDRS(unset — only loopback 127.0.0.0/8 and ::1/128 trusted)Comma-separated list of CIDR ranges whose X-Forwarded-For header the rate limiter and client-IP extractor will trust. Set this to the address(es) of your reverse proxy (nginx/Caddy/load balancer) so per-IP throttles see the real client IP. Leaving it unset means any non-loopback client presenting a forged X-Forwarded-For is ignored (the header is only honoured from trusted hops). Read by internal/api/ratelimit.go.
CREWSHIP_ENV(unset — treated as non-prod)Deployment environment label. When set to prod or production (case-insensitive), the server refuses to start if rate limiting has been disabled, and tightens WebSocket origin enforcement. Any other value (or unset) is treated as non-production. Read by internal/api/ratelimit.go and internal/ws/hub.go.

Metrics

VariableDefaultDescription
CREWSHIP_METRICS_TOKEN(unset — metrics only reachable from loopback)Bearer token gating non-loopback access to the Prometheus /metrics endpoint. Loopback peers are always allowed; remote scrapers must send Authorization: Bearer <token>. When unset, non-loopback requests are rejected outright. Read by internal/server/routes.go.

Webhooks / hooks (SSRF guard)

VariableDefaultDescription
CREWSHIP_HOOKS_ALLOW_PRIVATE(unset — private destinations blocked)Set to 1/true/yes/on to allow hook/webhook handlers to dial loopback and RFC1918 private addresses. Off by default so a misconfigured hook cannot reach localhost services or internal LAN hosts. Link-local (cloud metadata IMDS 169.254.169.254), multicast, and unspecified addresses stay blocked regardless of this flag. Read by internal/hooks/http.go.

Profiling & observability

These are off by default and intended for operators debugging performance.
VariableDefaultDescription
CREWSHIP_PPROF_ADDR(unset — pprof disabled)Bind address for the Go net/http/pprof server (recommended: 127.0.0.1:6060, loopback only). Exposing pprof publicly is an info-leak and DoS vector, so it stays off unless explicitly set. Read by internal/server/server.go.
CREWSHIP_PYROSCOPE_URL(unset — push profiling disabled)Pyroscope server URL. When set, the binary continuously pushes CPU/heap/goroutine/alloc profiles. Read by internal/server/server.go.
CREWSHIP_PYROSCOPE_TAG_SLOT(hostname)Value for the slot tag attached to Pyroscope profiles, used to filter the Grafana flame-graph per dev slot/instance. Falls back to the machine hostname when unset. Read by internal/telemetry/pyroscope.go.
OTEL_EXPORTER_OTLP_ENDPOINT(unset — noop tracer)Standard OpenTelemetry OTLP HTTP endpoint for GenAI traces. When unset, tracing silently degrades to a no-op tracer so local dev runs without an observability stack. Read by internal/server/server.go / internal/telemetry/provider.go.
CREWSHIP_SERVICE_NAMEcrewshipdOverrides the OpenTelemetry service.name resource attribute. Set per binary (e.g. crewship-sidecar) or per tenant to differentiate traces. Read by internal/telemetry/service_name.go.

Crash reporting (Sentry)

VariableDefaultDescription
CREWSHIP_SENTRY_DSN(vendor default, baked-in at build time)Operator override for the crash-reporting DSN. Empty string disables crash reporting at startup even when telemetry consent is on. Read by internal/crashreport/crashreport.go.

Email (password recovery)

VariableDefaultDescription
RESEND_API_KEY(unset — recovery emails disabled)Resend API key for transactional email delivery. When unset, password-recovery flows surface a “configure RESEND_API_KEY or share the reset link manually” message instead of sending.
RESEND_FROM(unset — required together with API key)From: address used for outbound recovery emails (e.g. Crewship <recovery@example.com>).

Google sign-in (optional)

VariableDefaultDescription
GOOGLE_CLIENT_ID(unset — Google sign-in disabled)OAuth 2.0 client ID for the “Sign in with Google” flow. Loaded via applyEnvOverrides in internal/config/config.go.
GOOGLE_CLIENT_SECRET(unset)OAuth client secret paired with the client ID. Required when GOOGLE_CLIENT_ID is set.

Logging

VariableDefaultDescription
CREWSHIP_LOG_LEVELinfoLog level: debug, info, warn, error
CREWSHIP_LOG_FORMATjsonLog format: json or text

Authentication

VariableDefaultDescription
NEXTAUTH_SECRETAuto-generated on first bootJWT signing secret for user authentication. Generated via crypto/rand (32 bytes → 64 hex chars) and persisted to <dataDir>/secrets.env on first start; subsequent boots read the file back. Explicit env vars always win, so Vault / Kubernetes secret mounts / EnvironmentFile= keep working unchanged.
CREWSHIP_NEXTJS_URLAuto-derived from portInternal URL for self-referencing API calls
CREWSHIP_INTERNAL_TOKENAuto-generated on first bootToken for sidecar-to-crewshipd IPC authentication. Same auto-gen + persist path as NEXTAUTH_SECRET; stays stable across restarts once the file exists.
CREWSHIP_ALLOW_SIGNUPfalseAllow new user registration (true or 1)
CREWSHIP_BOOTSTRAP_WINDOW(unset — open until first admin)Opt-in finite first-run window. Unset (default), /bootstrap stays open until the first admin account exists (the empty user table is the gate). Set to a positive Go duration (e.g. 5m, 30s, 1h) to arm a deploy-race window that refuses /bootstrap with 410 after it elapses — for instances exposed to the internet before they’re bootstrapped. Invalid or non-positive values are ignored (falls back to the open-until-admin default).
As of PR #446 (internal/secrets), NEXTAUTH_SECRET, ENCRYPTION_KEY and CREWSHIP_INTERNAL_TOKEN are all bootstrapped on first start: missing values are generated with crypto/rand, persisted atomically to <dataDir>/secrets.env at mode 0600, and re-exported into the process environment so existing os.Getenv call sites see them unchanged. Explicit env vars override the file; partial persistence is handled (one missing key is filled, the other valid keys are preserved). For clustered deployments, set them explicitly via your secret manager.

Auto-Derived Values

  • CREWSHIP_NEXTJS_URL: If not explicitly set, defaults to http://localhost:{CREWSHIP_PORT}. In single-binary mode, the internal resolver calls itself on the same port.
  • CREWSHIP_INTERNAL_TOKEN: Auto-generated on first boot and persisted (see Note above). Stays stable across restarts.

Encryption

VariableDefaultDescription
ENCRYPTION_KEYAuto-generated on first boot256-bit hex-encoded AES key for credential encryption. Same auto-gen + persist path as NEXTAUTH_SECRET (32 bytes → 64 hex chars in <dataDir>/secrets.env).
ENCRYPTION_KEY_V2(optional)Rotated encryption key (for key versioning)

Composio integrations

VariableDefaultDescription
COMPOSIO_API_KEY(unset — provider off)Server-wide Composio project API key (ak_…). When set, auto-enables the Composio provider unless COMPOSIO_ENABLED is explicitly set. Fallback when a workspace has no per-workspace key. Single-tenant: one key = one Composio project shared by all workspaces.
COMPOSIO_ENABLED(derived from COMPOSIO_API_KEY)Gates only the server-env path (true/1false/0): it forces the env-key auto-enable on without a key, or off so a present COMPOSIO_API_KEY is ignored. It is not a global kill switch — a workspace that has saved its own key (composio_settings) keeps Composio regardless, since the per-workspace key takes precedence over the env fallback.
COMPOSIO_BASE_URL(Composio production host)Override the Composio API host (self-host / proxy / testing).
COMPOSIO_DEFAULT_CONNECTORfalseWhen true/1, every agent without an explicit per-agent Composio binding inherits a workspace-wide default connector (full access to all connected apps), and legacy non-Composio MCP servers are excluded at resolve time. Behaviour switch only — never auto-enables the provider.
NEXT_PUBLIC_LEGACY_MCP_INTEGRATIONS(unset)Build-time dashboard flag. =true restores the legacy self-hosted MCP integrations UI at /integrations (default is the managed Composio UI).

Keeper (AI Security Gatekeeper)

VariableDefaultDescription
KEEPER_ENABLEDfalseEnable Keeper AI gatekeeper (true or 1)
KEEPER_OLLAMA_URLhttp://localhost:11434Ollama API URL for Keeper LLM
KEEPER_MODEL(none)Model for Keeper evaluations (e.g. claude-haiku-4-5, or an Ollama model name). No default — an enabled Keeper with an empty model fails startup validation.
Setting KEEPER_OLLAMA_URL auto-enables Keeper (unless KEEPER_ENABLED is explicitly false). This means you only need to set the URL to activate Keeper.

LLM Proxy

VariableDefaultDescription
(YAML only)llm_proxy.enabled: trueEnable LLM proxy
(YAML only)llm_proxy.token_sync_interval: 30sToken sync interval
(YAML only)llm_proxy.health_check_interval: 60sHealth check interval

Paymaster (Billing Modes)

These variables tag every cost-ledger row written from inside an agent run. The orchestrator sets them on the agent’s environment from the credential type before exec; the sidecar reads them once at startup and includes them on every POST /api/v1/internal/cost/record call.
VariableDefaultDescription
CREWSHIP_BILLING_MODEmeteredmetered (per-token $ math) or flat_rate (subscription credential, marginal cost = $0). Source: internal/orchestrator/exec_env.go:142,153, internal/sidecar/server.go:168.
CREWSHIP_SUBSCRIPTION_PLAN(empty)Display label for flat-rate credentials. Currently the orchestrator hard-codes "Anthropic Max" for the OAuth Claude Code path; future credential types ("Cursor Ultra", "ChatGPT Plus") will surface their own labels. Set when CREWSHIP_BILLING_MODE=flat_rate; the Paymaster surfaces it on the Subscriptions panel. Source: internal/orchestrator/exec_env.go:143, internal/sidecar/server.go:172.
Operators do not set these manually for normal use. They are propagated automatically based on the credential’s auth type (API key → metered, OAuth/subscription → flat_rate). They are listed here only for sidecar-image authors and tooling that intercepts the orchestrator handoff.
See Paymaster for the full billing-mode model and Migrations for the v62 cost-ledger schema.

Ollama (Episodic Memory + Keeper)

VariableDefaultDescription
OLLAMA_MODELS~/.ollama/modelsDirectory where Ollama stores model blobs. Used by the Keeper gatekeeper LLM, the Episodic memory embedder, and the Consolidator. On macOS dev machines this is typically pointed at an external SSD: OLLAMA_MODELS="/Volumes/SSD 990 PRO/ollama-models". Set this before starting Ollama (./dev.sh start or ollama serve); changing it requires a restart.

Feature toggles & runtime tuning

VariableDefaultDescription
CREWSHIP_CONSOLIDATE_HITL(unset — off)Set to 1/true/yes/on to route the memory consolidator through a human-in-the-loop approval step instead of writing directly. Read on every tick so it can be flipped without a restart. Read by internal/consolidate/runner.go.
CREWSHIP_PIPELINE_RUNNER(unset — orchestrator runner)Selects the pipeline execution backend. Set to llm_direct to run pipeline steps through the in-process LLM runner instead of spawning orchestrator containers (also the automatic fallback when no container provider is available). Read by cmd/crewship/cmd_start.go.
CREWSHIP_FORECAST_RATES(built-in rate table)Overrides the provider price table used by crewship cost forecast. Format: Name,inPerM,outPerM;Name,inPerM,outPerM;… (USD per million tokens). Malformed entries fall back to the defaults with a one-time stderr warning. Read by cmd/crewship/cmd_cost_forecast.go.
CREWSHIP_QUERY_DEPTH0Default crew-to-crew query recursion depth when a request does not specify one. Hard-capped at 2 (deeper queries are rejected to prevent loops). Read by internal/sidecar/query.go.

License

VariableDefaultDescription
CREWSHIP_LICENSE_FILE(empty)Path to license file

Seed Data

These variables are used by the ./dev.sh seed command:
VariableDescription
SEED_ANTHROPIC_API_KEYAnthropic API key or OAuth token for demo agents
SEED_GOOGLE_EMAILGoogle email for seed Google credential
SEED_GOOGLE_PASSWORDGoogle password for seed Google credential

Container Runtime

VariableDescription
DOCKER_HOSTDocker socket override (e.g., unix:///var/run/docker.sock)
The Docker provider checks DOCKER_HOST first, then auto-detects from candidate socket paths.

Devcontainer Cache GC

Crewship runs a background sweeper every 30 minutes that detects three kinds of leaks: temporary provisioning containers orphaned by a crewshipd crash (matched by the crewship.temp=provision label), unreferenced crewship-cache:* images left behind when the process is killed between docker commit and the database write that links the image to a crew, and intermediate crewship-feat:* BuildKit feature images (per-feature layers that are regenerable and never directly referenced by a crew row). Temp containers older than one hour are always removed. Cache and feature images are logged only by default; deletion must be explicitly enabled.
VariableDefaultDescription
CREWSHIP_CACHE_GC_AUTODELETE(unset)Set to true or 1 to remove unreferenced crewship-cache:* and intermediate crewship-feat:* images automatically. Default behaviour is to log the orphans only — destructive removal is opt-in because deleting a freshly-built local image is surprising in interactive environments.
A 5-minute age floor protects images that were committed in the last few minutes (closing the race between docker commit and the DB update inside Provision()), so enabling auto-delete is safe even on busy systems.
Leave CREWSHIP_CACHE_GC_AUTODELETE unset on developer machines. Enable it on long-running production hosts where reclaiming disk matters more than preserving incidental cached images. Inspect the orphan list in the logs first to verify nothing important would be removed.

CLI client

These configure the crewship CLI on a developer/operator machine (not the server). They override values in ~/.crewship/cli-config.yaml. Resolution order and parsing live in internal/cli/config.go.
VariableDefaultDescription
CREWSHIP_SERVERhttp://localhost:8080Base URL of the Crewship server the CLI talks to. Takes precedence over server: in the config file, but loses to a per-command --server flag.
CREWSHIP_CONFIG~/.crewship/cli-config.yamlPath to the CLI config file. Pin it to a per-instance path when running multiple clones on the same machine so their sessions don’t clobber each other.
CREWSHIP_WORKSPACE(unset)Default workspace ID/slug for commands that take one.
CREWSHIP_DEFAULT_AGENT(unset)Default agent the CLI targets when a command omits an explicit agent.

Installer

Read by scripts/install.sh (the curl … | bash install path), not by the running server.
VariableDefaultDescription
CREWSHIP_VERSION(latest stable release)Pin a specific release tag, e.g. v0.1.0-beta.1, instead of the latest stable.
CREWSHIP_INSTALL_DIRauto ($XDG_BIN_HOME / $HOME/.local/bin, else /usr/local/bin)Override the directory the binary is installed into.
CREWSHIP_SKIP_VERIFY0Set to 1 to skip checksum verification of the downloaded binary (not recommended).

Complete Example

# Secrets — optional: auto-generated on first boot and persisted to
# <dataDir>/secrets.env. Set these explicitly only when an external
# secret manager owns them (Vault, k8s secret, systemd EnvironmentFile).
# ENCRYPTION_KEY=a1b2c3d4e5f6...  # 64 hex chars
# NEXTAUTH_SECRET=your-jwt-secret

# Server
CREWSHIP_HOST=0.0.0.0
CREWSHIP_PORT=8080

# Container
CREWSHIP_CONTAINER_PROVIDER=docker
CREWSHIP_SIDECAR_ENABLED=true
CREWSHIP_RUNTIME_IMAGE=debian:bookworm-slim
# CREWSHIP_SIDECAR_PATH and CREWSHIP_ENTRYPOINT_PATH are normally autodetected
# from `make build:sidecar` output. Override when running from an unusual layout.
# CREWSHIP_SIDECAR_PATH=/opt/crewship/crewship-sidecar
# CREWSHIP_ENTRYPOINT_PATH=/opt/crewship/entrypoint.sh

# Auth
CREWSHIP_ALLOW_SIGNUP=true

# Keeper (optional)
KEEPER_OLLAMA_URL=http://localhost:11434
KEEPER_MODEL=claude-haiku-4-5

# Logging
CREWSHIP_LOG_LEVEL=info
CREWSHIP_LOG_FORMAT=json

Validation

The config is validated at startup (Config.Validate). These constraints are enforced:
FieldConstraint
server.port1-65535
ipc.socket_pathNon-empty
container.providerdocker, apple, or auto
storage.providerlocalfs or s3
state.providerbbolt
container.default_runtimerunc, runsc, kata-runtime, or sysbox-runc (if set)
auth.nextjs_urlNon-empty