-
Notifications
You must be signed in to change notification settings - Fork 4.4k
04.2 Environment Variables
Relevant source files
The following files were used as context for generating this wiki page:
This page documents all environment variables recognized by ZeroClaw and how they override values in config.toml. Environment variables provide a deployment-friendly way to configure the agent without editing configuration files, making them ideal for containerized deployments, CI/CD pipelines, and multi-environment setups.
For information about the configuration file structure, see Configuration File Reference. For secret encryption, see Secret Management. For workspace directory resolution, see Workspace Management.
ZeroClaw uses a three-tier configuration priority system where environment variables take precedence over configuration file values, which in turn take precedence over built-in defaults.
flowchart LR
A["Environment Variables"]
B["config.toml"]
C["Built-in Defaults"]
A -->|"Highest Priority"| D["Final Config"]
B -->|"Medium Priority"| D
C -->|"Lowest Priority"| D
D --> E["Config::load_or_init"]
E --> F["Runtime Subsystems"]
Configuration Resolution Flow
Sources: src/config/schema.rs:46-144, src/onboard/wizard.rs:300-367
These environment variables control core agent behavior and override top-level configuration fields.
| Environment Variable | Config Field | Type | Description | Default |
|---|---|---|---|---|
ZEROCLAW_WORKSPACE |
workspace_dir |
Path | Workspace directory path | ~/.zeroclaw/workspace |
API_KEY |
api_key |
String | Primary provider API key | None |
ZEROCLAW_API_KEY |
api_key |
String | Alternative API key variable (lower priority than API_KEY) |
None |
PROVIDER |
default_provider |
String | Default LLM provider name | "openrouter" |
ZEROCLAW_MODEL |
default_model |
String | Default model identifier | Provider-specific |
ZEROCLAW_TEMPERATURE |
default_temperature |
Float | Sampling temperature (0.0-2.0) | 0.7 |
ZEROCLAW_GATEWAY_PORT |
gateway.port |
u16 | Gateway HTTP port | 3000 |
ZEROCLAW_GATEWAY_HOST |
gateway.host |
String | Gateway bind address | "127.0.0.1" |
ZEROCLAW_ALLOW_PUBLIC_BIND |
gateway.allow_public_bind |
Boolean | Allow binding to non-localhost addresses | false |
ZEROCLAW_AUTOSTART_CHANNELS |
N/A | Boolean | Internal flag set by wizard to auto-launch channels | false |
Docker Environment Precedence
graph TD
A["Docker Container Start"]
B["Read ENV from Dockerfile"]
C["Override with docker-compose.yml ENV"]
D["Override with docker run -e flags"]
E["Apply to Config::load_or_init"]
A --> B
B --> C
C --> D
D --> E
E --> F["Provider Initialization"]
E --> G["Gateway Binding"]
E --> H["Channel Startup"]
Sources: Dockerfile:74-107, docker-compose.yml:18-33, src/onboard/wizard.rs:191-192,250-251
Provider-specific environment variables take precedence over the generic API_KEY variable. ZeroClaw checks provider-specific variables first, then falls back to API_KEY, then to config.toml.
| Provider | Environment Variable | Fallback Chain |
|---|---|---|
| OpenRouter | OPENROUTER_API_KEY |
→ API_KEY → config.toml
|
| Anthropic | ANTHROPIC_API_KEY |
→ API_KEY → config.toml
|
| OpenAI | OPENAI_API_KEY |
→ API_KEY → config.toml
|
| Gemini | GEMINI_API_KEY |
→ API_KEY → config.toml
|
| Ollama | N/A (unauthenticated) | Uses api_url only |
| Groq | GROQ_API_KEY |
→ API_KEY → config.toml
|
| Mistral | MISTRAL_API_KEY |
→ API_KEY → config.toml
|
| DeepSeek | DEEPSEEK_API_KEY |
→ API_KEY → config.toml
|
| Venice | VENICE_API_KEY |
→ API_KEY → config.toml
|
| XAI/Grok | XAI_API_KEY |
→ API_KEY → config.toml
|
| Perplexity | PERPLEXITY_API_KEY |
→ API_KEY → config.toml
|
| Cohere | COHERE_API_KEY |
→ API_KEY → config.toml
|
| Together AI | TOGETHER_API_KEY |
→ API_KEY → config.toml
|
| Fireworks | FIREWORKS_API_KEY |
→ API_KEY → config.toml
|
| Moonshot | MOONSHOT_API_KEY |
→ API_KEY → config.toml
|
| GLM/ZAI |
GLM_API_KEY or ZAI_API_KEY
|
→ API_KEY → config.toml
|
| MiniMax | MINIMAX_API_KEY |
→ API_KEY → config.toml
|
| Qwen | QWEN_API_KEY |
→ API_KEY → config.toml
|
Provider API Key Resolution Flow
flowchart TD
A["Provider Initialization"]
B["Check provider-specific env var<br/>(e.g., OPENROUTER_API_KEY)"]
C["Check generic API_KEY env var"]
D["Check config.toml api_key field"]
E["Error: No API key found"]
F["Provider Ready"]
A --> B
B -->|Found| F
B -->|Not found| C
C -->|Found| F
C -->|Not found| D
D -->|Found| F
D -->|Not found| E
Sources: src/config/schema.rs:56-61, src/onboard/wizard.rs:450-451, docker-compose.yml:19-22
Channel implementations may check environment variables for tokens and secrets. These are typically set when using the wizard or editing config.toml.
| Channel | Environment Variables | Purpose |
|---|---|---|
| Telegram | TELEGRAM_BOT_TOKEN |
Bot authentication token |
| Discord | DISCORD_BOT_TOKEN |
Bot authentication token |
| Slack |
SLACK_BOT_TOKEN, SLACK_APP_TOKEN
|
Bot token and app-level token for Socket Mode |
| Matrix | MATRIX_ACCESS_TOKEN |
Matrix homeserver access token |
WHATSAPP_ACCESS_TOKEN, WHATSAPP_PHONE_NUMBER_ID, WHATSAPP_VERIFY_TOKEN
|
Meta Business API credentials | |
EMAIL_USERNAME, EMAIL_PASSWORD
|
IMAP/SMTP credentials | |
| Lark/Feishu |
LARK_APP_ID, LARK_APP_SECRET
|
Lark application credentials |
| DingTalk |
DINGTALK_APP_KEY, DINGTALK_APP_SECRET
|
DingTalk application credentials |
QQ_APP_ID, QQ_APP_SECRET
|
QQ Bot credentials | |
| Mattermost |
MATTERMOST_URL, MATTERMOST_TOKEN
|
Mattermost server URL and personal access token |
Channel Credential Loading
sequenceDiagram
participant CLI as zeroclaw daemon
participant Config as Config::load_or_init
participant Env as Environment Variables
participant TOML as config.toml
participant Channel as Channel Implementation
CLI->>Config: Load configuration
Config->>Env: Check TELEGRAM_BOT_TOKEN
alt Env var found
Env-->>Config: Return token
else Env var not found
Config->>TOML: Read channels_config.telegram.bot_token
TOML-->>Config: Return token or None
end
Config->>Channel: Instantiate with credentials
Channel->>Channel: Validate and connect
Sources: src/config/schema.rs:1278-1520, src/channels/mod.rs:1-31
ZeroClaw supports standard proxy environment variables for routing HTTP/HTTPS requests through proxies. The proxy system respects the configuration priority: environment variables override config.toml proxy settings.
| Variable | Scope | Description |
|---|---|---|
HTTP_PROXY |
HTTP requests | Proxy URL for HTTP connections (supports http://, https://, socks5://, socks5h://) |
HTTPS_PROXY |
HTTPS requests | Proxy URL for HTTPS connections (supports http://, https://, socks5://, socks5h://) |
ALL_PROXY |
All connections | Fallback proxy URL for all request types |
NO_PROXY |
Bypass list | Comma-separated list of domains/IPs to bypass proxy (e.g., localhost,127.0.0.1,.internal) |
Case Sensitivity: Both uppercase (HTTP_PROXY) and lowercase (http_proxy) variants are supported on Unix-like systems. Windows is case-insensitive.
Proxy Scope Configuration
The proxy.scope setting in config.toml controls when proxy settings apply:
-
environment: Only use proxy env vars, ignore ZeroClaw config -
zeroclaw(default): Use ZeroClaw proxy config for all internal HTTP clients -
services: Apply proxy only to specified services (e.g.,provider.openai,channel.telegram)
flowchart TD
A["HTTP Request Initiated"]
B["Check proxy.enabled in config.toml"]
C["Check proxy.scope"]
D["Read environment variables:<br/>HTTP_PROXY, HTTPS_PROXY, ALL_PROXY, NO_PROXY"]
E["Apply to reqwest::ClientBuilder"]
F["Check NO_PROXY bypass list"]
G["Execute request via proxy"]
H["Execute request directly"]
A --> B
B -->|"enabled = true"| C
B -->|"enabled = false"| H
C -->|"scope = environment"| D
C -->|"scope = zeroclaw"| E
C -->|"scope = services"| E
D --> E
E --> F
F -->|"Domain not in NO_PROXY"| G
F -->|"Domain in NO_PROXY"| H
Sources: src/config/schema.rs:813-1029
These environment variables control execution isolation, observability, and performance tuning.
| Variable | Config Field | Type | Description | Default |
|---|---|---|---|---|
ZEROCLAW_RUNTIME |
runtime.adapter |
String | Runtime adapter: "native" or "docker"
|
"native" |
ZEROCLAW_OBSERVABILITY |
observability.enabled |
Boolean | Enable telemetry and logging | false |
ZEROCLAW_LOG_LEVEL |
N/A | String | Rust log level filter (trace, debug, info, warn, error) |
"info" |
RUST_LOG |
N/A | String | Low-level Rust logging filter (used by tracing crate) |
None |
ZEROCLAW_MAX_TOOL_ITERATIONS |
agent.max_tool_iterations |
usize | Maximum tool call loop iterations | 10 |
ZEROCLAW_COMPACT_CONTEXT |
agent.compact_context |
Boolean | Use reduced context window for smaller models | false |
Runtime Adapter Selection
graph LR
A["Tool Execution Request"]
B["Read ZEROCLAW_RUNTIME env"]
C["runtime.adapter in config.toml"]
D["NativeRuntimeAdapter"]
E["DockerRuntimeAdapter"]
F["Execute in subprocess"]
G["Execute in Docker container<br/>(network=none, read_only_rootfs)"]
A --> B
B -->|"Set to 'docker'"| E
B -->|"Not set"| C
C -->|"adapter = 'native'"| D
C -->|"adapter = 'docker'"| E
D --> F
E --> G
Sources: src/config/schema.rs:63-78,243-280, Dockerfile:74-107
# Minimal setup with local Ollama
export PROVIDER=ollama
export ZEROCLAW_MODEL=llama3.2
export ZEROCLAW_WORKSPACE=$HOME/zeroclaw-dev
zeroclaw agent -m "Hello!"# docker-compose.yml
services:
zeroclaw:
image: ghcr.io/zeroclaw-labs/zeroclaw:latest
environment:
- API_KEY=${OPENROUTER_API_KEY}
- PROVIDER=openrouter
- ZEROCLAW_MODEL=anthropic/claude-sonnet-4-20250514
- ZEROCLAW_ALLOW_PUBLIC_BIND=true
- HTTP_PROXY=http://proxy.internal:3128
- NO_PROXY=localhost,127.0.0.1
volumes:
- zeroclaw-data:/zeroclaw-data
ports:
- "3000:3000"Docker Environment Injection
sequenceDiagram
participant Docker as docker-compose up
participant Container as ZeroClaw Container
participant Env as Environment Variables
participant Config as Config::load_or_init
participant Provider as Provider Factory
Docker->>Container: Start container with ENV
Container->>Env: Read PROVIDER, API_KEY, etc.
Container->>Config: Initialize configuration
Config->>Env: Check PROVIDER env var
Env-->>Config: "openrouter"
Config->>Env: Check API_KEY env var
Env-->>Config: "sk-or-v1-..."
Config->>Provider: create_resilient_provider("openrouter", api_key)
Provider-->>Config: Provider instance
Sources: docker-compose.yml:1-63, Dockerfile:41-56
# k8s-deployment.yaml
apiVersion: v1
kind: Secret
metadata:
name: zeroclaw-secrets
type: Opaque
stringData:
api-key: sk-or-v1-xxxxx
telegram-bot-token: 1234567890:ABCdefGHIjklMNOpqrSTUvwxYZ
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: zeroclaw
spec:
replicas: 1
template:
spec:
containers:
- name: zeroclaw
image: ghcr.io/zeroclaw-labs/zeroclaw:latest
env:
- name: API_KEY
valueFrom:
secretKeyRef:
name: zeroclaw-secrets
key: api-key
- name: TELEGRAM_BOT_TOKEN
valueFrom:
secretKeyRef:
name: zeroclaw-secrets
key: telegram-bot-token
- name: PROVIDER
value: "openrouter"
- name: ZEROCLAW_ALLOW_PUBLIC_BIND
value: "true"# .github/workflows/test-agent.yml
- name: Test Agent
env:
API_KEY: ${{ secrets.OPENROUTER_API_KEY }}
PROVIDER: openrouter
ZEROCLAW_WORKSPACE: /tmp/zeroclaw-ci
ZEROCLAW_COMPACT_CONTEXT: true
run: |
zeroclaw agent -m "Run test suite" --non-interactiveSources: .github/workflows/pub-docker-img.yml:39-107, docker-compose.yml:18-33
To debug which environment variables are being used, ZeroClaw logs configuration sources at startup with RUST_LOG=zeroclaw=debug:
export RUST_LOG=zeroclaw=debug
export PROVIDER=openrouter
export API_KEY=sk-or-test
zeroclaw agent -m "test"Expected log output:
[DEBUG zeroclaw::config] Loading config from ~/.zeroclaw/config.toml
[DEBUG zeroclaw::config] Applying environment variable overrides
[DEBUG zeroclaw::config] PROVIDER env var found: openrouter
[DEBUG zeroclaw::config] API_KEY env var found: sk-or-*** (masked)
[INFO zeroclaw] Provider: openrouter, Model: anthropic/claude-sonnet-4-20250514
Configuration Loading with Environment Overrides
flowchart TD
A["Config::load_or_init()"]
B["Parse config.toml"]
C["Apply environment variable overrides"]
D["Check API_KEY env"]
E["Check PROVIDER env"]
F["Check ZEROCLAW_MODEL env"]
G["Check ZEROCLAW_GATEWAY_PORT env"]
H["Validate merged config"]
I["Return Config"]
A --> B
B --> C
C --> D
C --> E
C --> F
C --> G
D --> H
E --> H
F --> H
G --> H
H --> I
Sources: src/config/schema.rs:46-144, src/channels/mod.rs:888-1035
-
Use provider-specific variables: Prefer
OPENROUTER_API_KEYover genericAPI_KEYto avoid conflicts in multi-provider setups. -
Secure sensitive variables: Store API keys in secret management systems (Kubernetes Secrets, AWS Secrets Manager, Docker secrets) rather than plaintext environment variables.
-
Validate before deployment: Run
zeroclaw statusto verify environment variables are correctly applied. -
Use
ZEROCLAW_prefix for clarity: When setting multiple variables, prefix custom overrides withZEROCLAW_to distinguish them from system-wide environment variables. -
Test with
.envfiles locally: Use a.envfile withdocker compose --env-file .env upfor reproducible local testing. -
Document deployment requirements: Include an
.env.examplefile in your deployment repository showing all required variables.
Sources: docker-compose.yml:1-63, src/onboard/wizard.rs:300-463