Skip to content

04.2 Environment Variables

Nikolay Vyahhi edited this page Feb 19, 2026 · 4 revisions

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.


Configuration Priority System

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"]
Loading

Configuration Resolution Flow

Sources: src/config/schema.rs:46-144, src/onboard/wizard.rs:300-367


General Configuration Variables

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"]
Loading

Sources: Dockerfile:74-107, docker-compose.yml:18-33, src/onboard/wizard.rs:191-192,250-251


Provider API Keys

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-Specific Variables

Provider Environment Variable Fallback Chain
OpenRouter OPENROUTER_API_KEY API_KEYconfig.toml
Anthropic ANTHROPIC_API_KEY API_KEYconfig.toml
OpenAI OPENAI_API_KEY API_KEYconfig.toml
Gemini GEMINI_API_KEY API_KEYconfig.toml
Ollama N/A (unauthenticated) Uses api_url only
Groq GROQ_API_KEY API_KEYconfig.toml
Mistral MISTRAL_API_KEY API_KEYconfig.toml
DeepSeek DEEPSEEK_API_KEY API_KEYconfig.toml
Venice VENICE_API_KEY API_KEYconfig.toml
XAI/Grok XAI_API_KEY API_KEYconfig.toml
Perplexity PERPLEXITY_API_KEY API_KEYconfig.toml
Cohere COHERE_API_KEY API_KEYconfig.toml
Together AI TOGETHER_API_KEY API_KEYconfig.toml
Fireworks FIREWORKS_API_KEY API_KEYconfig.toml
Moonshot MOONSHOT_API_KEY API_KEYconfig.toml
GLM/ZAI GLM_API_KEY or ZAI_API_KEY API_KEYconfig.toml
MiniMax MINIMAX_API_KEY API_KEYconfig.toml
Qwen QWEN_API_KEY API_KEYconfig.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
Loading

Sources: src/config/schema.rs:56-61, src/onboard/wizard.rs:450-451, docker-compose.yml:19-22


Channel Configuration Variables

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 WHATSAPP_ACCESS_TOKEN, WHATSAPP_PHONE_NUMBER_ID, WHATSAPP_VERIFY_TOKEN Meta Business API credentials
Email 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 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
Loading

Sources: src/config/schema.rs:1278-1520, src/channels/mod.rs:1-31


Proxy Configuration Variables

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.

Proxy Environment Variables

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
Loading

Sources: src/config/schema.rs:813-1029


Runtime Settings

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
Loading

Sources: src/config/schema.rs:63-78,243-280, Dockerfile:74-107


Deployment Scenarios

Local Development

# 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 Production

# 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
Loading

Sources: docker-compose.yml:1-63, Dockerfile:41-56

Kubernetes Deployment

# 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"

CI/CD Pipeline

# .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-interactive

Sources: .github/workflows/pub-docker-img.yml:39-107, docker-compose.yml:18-33


Environment Variable Inspection

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
Loading

Sources: src/config/schema.rs:46-144, src/channels/mod.rs:888-1035


Best Practices

  1. Use provider-specific variables: Prefer OPENROUTER_API_KEY over generic API_KEY to avoid conflicts in multi-provider setups.

  2. Secure sensitive variables: Store API keys in secret management systems (Kubernetes Secrets, AWS Secrets Manager, Docker secrets) rather than plaintext environment variables.

  3. Validate before deployment: Run zeroclaw status to verify environment variables are correctly applied.

  4. Use ZEROCLAW_ prefix for clarity: When setting multiple variables, prefix custom overrides with ZEROCLAW_ to distinguish them from system-wide environment variables.

  5. Test with .env files locally: Use a .env file with docker compose --env-file .env up for reproducible local testing.

  6. Document deployment requirements: Include an .env.example file in your deployment repository showing all required variables.

Sources: docker-compose.yml:1-63, src/onboard/wizard.rs:300-463


Clone this wiki locally