mirror of
https://github.com/nearai/ironclaw.git
synced 2026-09-03 08:06:01 +08:00
* feat(agent-loop): add opt-in parallel tool batches * fix(agent-loop): address parallel batch review * fix(agent-loop): close parallel batch review gaps (#7416) * fix(agent-loop): preserve sibling exit state (#7416) * fix(agent-loop): preserve terminal batch sibling state * fix(agent-loop): drain bounded parallel terminal outcomes * fix(turn-runner): seal parallel batch configuration * style(turn-runner): format merged imports * test(agent-loop): pause parallel ordering clock * test(agent-loop): bound paused launch wait * fix(deps): update lru past unsound advisory * fix(agent-loop): preserve hooked batch semantics * fix(loop): address CodeRabbit review — fail closed batch ordering (#7416) * fix(ci): rebaseline loop contracts size ratchet (#7416)
553 lines
28 KiB
Plaintext
553 lines
28 KiB
Plaintext
# Database Configuration
|
||
DATABASE_URL=postgres://localhost/ironclaw
|
||
DATABASE_POOL_SIZE=30 # multi-tenant default; reduce to 5-10 for single-user or low-resource deployments
|
||
|
||
# LLM Provider
|
||
# LLM_BACKEND=nearai # default
|
||
# Possible values: nearai, ollama, openai_compatible, openai, anthropic, github_copilot, tinfoil, openai_codex, gemini_oauth
|
||
# LLM_REQUEST_TIMEOUT_SECS=120 # Increase for local LLMs (Ollama, vLLM, LM Studio)
|
||
|
||
# === Anthropic Direct ===
|
||
# Two auth modes:
|
||
# 1. API key: Set ANTHROPIC_API_KEY (from console.anthropic.com/settings/keys)
|
||
# 2. OAuth token: Set ANTHROPIC_OAUTH_TOKEN (from `claude login`)
|
||
# OAuth tokens use Authorization: Bearer instead of x-api-key header.
|
||
# ANTHROPIC_API_KEY=sk-ant-...
|
||
# ANTHROPIC_OAUTH_TOKEN=sk-ant-oat01-... # from `claude login` credentials
|
||
# ANTHROPIC_MODEL=claude-sonnet-4-20250514
|
||
|
||
# === OpenAI Direct ===
|
||
# OPENAI_API_KEY=sk-...
|
||
# Reuse Codex CLI auth.json instead of setting OPENAI_API_KEY manually.
|
||
# Works with both OpenAI API-key mode and Codex ChatGPT OAuth mode.
|
||
# In ChatGPT mode this uses the private `chatgpt.com/backend-api/codex` endpoint.
|
||
# LLM_USE_CODEX_AUTH=true
|
||
# CODEX_AUTH_PATH=~/.codex/auth.json
|
||
|
||
# === GitHub Copilot ===
|
||
# Uses the OAuth token from your Copilot IDE sign-in (for example
|
||
# ~/.config/github-copilot/apps.json on Linux/macOS), or run `ironclaw onboard`
|
||
# and choose the GitHub device login flow.
|
||
# LLM_BACKEND=github_copilot
|
||
# GITHUB_COPILOT_TOKEN=gho_...
|
||
# GITHUB_COPILOT_MODEL=gpt-4o
|
||
# IronClaw injects standard VS Code Copilot headers automatically.
|
||
# Optional advanced headers for custom overrides:
|
||
# GITHUB_COPILOT_EXTRA_HEADERS=Copilot-Integration-Id:vscode-chat
|
||
|
||
# === NEAR AI (Chat Completions API) ===
|
||
# Two auth modes:
|
||
# 1. Session token (default): Uses browser OAuth (GitHub/Google) on first run.
|
||
# Session token stored in ~/.ironclaw/session.json automatically.
|
||
# Base URL defaults to https://private.near.ai
|
||
# 2. API key: Set NEARAI_API_KEY to use API key auth from cloud.near.ai.
|
||
# Base URL defaults to https://cloud-api.near.ai
|
||
# When NEARAI_API_KEY is set at startup, IronClaw bootstraps the
|
||
# `nearai` MCP integration automatically, using the default endpoint
|
||
# unless NEARAI_BASE_URL is also set:
|
||
# legacy startup persists a `nearai` MCP server, and Reborn local-dev
|
||
# seeds product-auth and activates the bundled NEAR AI MCP extension.
|
||
# Leave NEARAI_MODEL / NEARAI_BASE_URL unset to use the built-in defaults
|
||
# (model `deepseek-ai/DeepSeek-V4-Flash`; base URL chosen by auth mode:
|
||
# cloud-api.near.ai with an API key, private.near.ai for session tokens) and
|
||
# to let the WebUI onboarding selection take effect. Set them only for a pure
|
||
# env-configured deployment — they apply process-wide. Precedence: an explicit
|
||
# WebUI/config.toml selection wins over these env vars, which in turn win over
|
||
# the built-in defaults.
|
||
# NEARAI_MODEL=deepseek-ai/DeepSeek-V4-Flash
|
||
# NEARAI_BASE_URL=https://private.near.ai
|
||
# NEARAI_AUTH_URL=https://private.near.ai
|
||
# NEARAI_SESSION_TOKEN=sess_... # hosting providers: set this
|
||
# NEARAI_SESSION_PATH=~/.ironclaw/session.json # optional, default shown
|
||
# NEARAI_API_KEY=... # API key from cloud.near.ai
|
||
|
||
# Local LLM Providers (Ollama, LM Studio, vLLM, LiteLLM)
|
||
|
||
# === Ollama ===
|
||
# OLLAMA_MODEL=llama3.2
|
||
# LLM_BACKEND=ollama
|
||
# OLLAMA_BASE_URL=http://localhost:11434 # default
|
||
|
||
# === OpenAI-compatible (LM Studio, vLLM, Anything-LLM) ===
|
||
# LLM_MODEL=llama-3.2-3b-instruct-q4_K_M
|
||
# LLM_BACKEND=openai_compatible
|
||
# LLM_BASE_URL=http://localhost:1234/v1
|
||
# LLM_API_KEY=sk-... # optional for local servers
|
||
# Custom HTTP headers for OpenAI-compatible providers
|
||
# Format: comma-separated key:value pairs
|
||
# LLM_EXTRA_HEADERS=HTTP-Referer:https://github.com/nearai/ironclaw,X-Title:ironclaw
|
||
|
||
# === OpenRouter (300+ models via OpenAI-compatible) ===
|
||
# LLM_MODEL=anthropic/claude-sonnet-4 # see openrouter.ai/models for IDs
|
||
# LLM_BACKEND=openai_compatible
|
||
# LLM_BASE_URL=https://openrouter.ai/api/v1
|
||
# LLM_API_KEY=sk-or-...
|
||
|
||
# LLM_EXTRA_HEADERS=HTTP-Referer:https://myapp.com,X-Title:MyApp
|
||
|
||
|
||
# === Together AI (via OpenAI-compatible) ===
|
||
# LLM_MODEL=meta-llama/Llama-3.3-70B-Instruct-Turbo
|
||
# LLM_BACKEND=openai_compatible
|
||
# LLM_BASE_URL=https://api.together.xyz/v1
|
||
# LLM_API_KEY=...
|
||
|
||
# === Fireworks AI (via OpenAI-compatible) ===
|
||
# LLM_MODEL=accounts/fireworks/models/llama4-maverick-instruct-basic
|
||
# LLM_BACKEND=openai_compatible
|
||
# LLM_BASE_URL=https://api.fireworks.ai/inference/v1
|
||
# LLM_API_KEY=fw_...
|
||
|
||
# === MiniMax ===
|
||
# LLM_BACKEND=minimax
|
||
# MINIMAX_API_KEY=...
|
||
# MINIMAX_MODEL=MiniMax-M2.7
|
||
# MINIMAX_BASE_URL=https://api.minimax.io/v1 # default (global); use https://api.minimaxi.com/v1 for China
|
||
|
||
# === Anthropic Direct ===
|
||
# LLM_BACKEND=anthropic
|
||
# ANTHROPIC_MODEL=claude-sonnet-4-6
|
||
# ANTHROPIC_API_KEY=sk-ant-...
|
||
# ANTHROPIC_BASE_URL=https://api.anthropic.com # default
|
||
# Prompt cache retention — controls Anthropic server-side prompt caching:
|
||
# none = disabled (no cache_control injected)
|
||
# short = 5-minute TTL, 1.25× (125%) write surcharge (default)
|
||
# long = 1-hour TTL, 2.0× (200%) write surcharge
|
||
# ANTHROPIC_CACHE_RETENTION=short
|
||
|
||
# === OpenAI Codex (ChatGPT subscription, OAuth) ===
|
||
# LLM_BACKEND=openai_codex
|
||
# OPENAI_CODEX_MODEL=gpt-5.5 # default (must be entitled to your ChatGPT plan)
|
||
# OPENAI_CODEX_CLIENT_ID=app_EMoamEEZ73f0CkXaXp7hrann # override (rare)
|
||
# OPENAI_CODEX_AUTH_URL=https://auth.openai.com # override (rare)
|
||
# OPENAI_CODEX_API_URL=https://chatgpt.com/backend-api/codex # override (rare)
|
||
|
||
# === Google Gemini (OAuth, Gemini CLI compatible) ===
|
||
# LLM_BACKEND=gemini_oauth
|
||
# GEMINI_MODEL=gemini-2.5-flash # default
|
||
# GEMINI_CREDENTIALS_PATH=~/.gemini/oauth_creds.json # default
|
||
# GEMINI_API_KEY=... # optional: use API key instead of OAuth
|
||
# GEMINI_API_KEY_AUTH_MECHANISM=query # "query" (default) or "header"
|
||
# GEMINI_SAFETY_BLOCK_NONE=true # disable safety filters (default: false)
|
||
# GEMINI_CLI_CUSTOM_HEADERS=Key:Value,Key2:Value2
|
||
# GEMINI_TOP_P=0.95
|
||
# GEMINI_TOP_K=40
|
||
# GEMINI_SEED=42
|
||
# GEMINI_PRESENCE_PENALTY=0.0
|
||
# GEMINI_FREQUENCY_PENALTY=0.0
|
||
# GEMINI_RESPONSE_MIME_TYPE=application/json
|
||
# GEMINI_RESPONSE_JSON_SCHEMA={"type":"object"}
|
||
# GEMINI_CACHED_CONTENT=cachedContents/abc123
|
||
|
||
# For full provider setup guide see docs/LLM_PROVIDERS.md
|
||
|
||
# Progressive tool disclosure. The default is `namespaces`; set `off` for the
|
||
# rollback path. `bridged` additionally enables reviewed per-profile pins.
|
||
# REBORN_TOOL_DISCLOSURE=namespaces
|
||
# JSON map from validated capability-surface profile ids to capability ids.
|
||
# Invalid JSON/ids reject startup; unset means no pins. Pins affect visibility
|
||
# only and never bypass authorization.
|
||
# REBORN_TOOL_DISCLOSURE_PROFILE_PINS={"interactive_tools":["github.search_code"]}
|
||
|
||
# Channel Configuration
|
||
# CLI is always enabled
|
||
|
||
# Slack Bot (optional)
|
||
SLACK_BOT_TOKEN=xoxb-...
|
||
SLACK_APP_TOKEN=xapp-...
|
||
SLACK_SIGNING_SECRET=...
|
||
|
||
# Telegram Bot (optional)
|
||
TELEGRAM_BOT_TOKEN=...
|
||
|
||
# Reborn Telegram WASM v2 ProductAdapter (issue #3285) — DEFAULT OFF.
|
||
# When true, the v2 ProductAdapter path takes mutually-exclusive ownership
|
||
# of the telegram webhook installation. Legacy v1 Telegram MUST NOT be
|
||
# configured for the same installation while this flag is true; the host
|
||
# fails closed on startup if both are active.
|
||
# REBORN_TELEGRAM_V2_ENABLED=false
|
||
|
||
# HTTP Webhook Server (optional)
|
||
HTTP_HOST=0.0.0.0
|
||
HTTP_PORT=8080
|
||
HTTP_WEBHOOK_SECRET=your-webhook-secret
|
||
# Webhook authentication uses HMAC-SHA256 signature verification.
|
||
# Callers must send an X-IronClaw-Signature header with format: sha256=<hex_digest>
|
||
# where the digest is HMAC-SHA256(HTTP_WEBHOOK_SECRET, raw_request_body) in lowercase hex.
|
||
#
|
||
# Example (bash):
|
||
# BODY='{"content":"hello"}'
|
||
# SIG=$(echo -n "$BODY" | openssl dgst -sha256 -hmac "$HTTP_WEBHOOK_SECRET" | cut -d' ' -f2)
|
||
# curl -X POST http://localhost:8080/webhook \
|
||
# -H "Content-Type: application/json" \
|
||
# -H "X-IronClaw-Signature: sha256=$SIG" \
|
||
# -d "$BODY"
|
||
#
|
||
# DEPRECATED: Passing "secret" in the JSON body still works but will be removed in a future release.
|
||
|
||
# Signal Channel (optional, requires signal-cli daemon --http)
|
||
# SIGNAL_HTTP_URL=http://127.0.0.1:8080
|
||
# SIGNAL_ACCOUNT=+1234567890
|
||
# SIGNAL_ALLOW_FROM=+1234567890,uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx # comma-separated, * for all, empty = deny/require pairing
|
||
# SIGNAL_ALLOW_FROM_GROUPS= # comma-separated group IDs, * for all, empty = deny all groups
|
||
# SIGNAL_DM_POLICY=pairing # open | allowlist | pairing
|
||
# SIGNAL_GROUP_POLICY=allowlist # allowlist | open | disabled
|
||
# SIGNAL_GROUP_ALLOW_FROM= # comma-separated, empty = inherit from ALLOW_FROM
|
||
# SIGNAL_IGNORE_ATTACHMENTS=false
|
||
# SIGNAL_IGNORE_STORIES=true
|
||
|
||
# Agent Settings
|
||
AGENT_NAME=ironclaw
|
||
AGENT_MAX_PARALLEL_JOBS=5
|
||
AGENT_JOB_TIMEOUT_SECS=3600
|
||
AGENT_STUCK_THRESHOLD_SECS=300
|
||
# Maximum tokens per job (0 = unlimited, also settable via settings.json agent.max_tokens_per_job)
|
||
# AGENT_MAX_TOKENS_PER_JOB=0
|
||
# Enable planning phase before tool execution (default: true)
|
||
AGENT_USE_PLANNING=true
|
||
|
||
# Self-repair settings
|
||
SELF_REPAIR_CHECK_INTERVAL_SECS=60
|
||
SELF_REPAIR_MAX_ATTEMPTS=3
|
||
|
||
# Heartbeat settings (proactive periodic execution)
|
||
# When enabled, reads HEARTBEAT.md checklist and reports findings
|
||
HEARTBEAT_ENABLED=false
|
||
HEARTBEAT_INTERVAL_SECS=1800
|
||
HEARTBEAT_NOTIFY_CHANNEL=cli
|
||
HEARTBEAT_NOTIFY_USER=default
|
||
|
||
# Memory hygiene settings (automatic cleanup of stale workspace documents)
|
||
# Runs on each heartbeat tick; discovers cleanup targets from .config metadata
|
||
# MEMORY_HYGIENE_ENABLED=true
|
||
# MEMORY_HYGIENE_VERSION_KEEP_COUNT=50 # max versions to keep per document
|
||
# MEMORY_HYGIENE_CADENCE_HOURS=12 # minimum hours between cleanup passes
|
||
|
||
# Trigger poller (scheduled / cron trigger firing)
|
||
# OFF by default. Enable to allow the host background poller to scan due trigger
|
||
# records and auto-fire scheduled (cron) triggers. Without this, triggers can be
|
||
# created and listed but will never fire automatically.
|
||
# IRONCLAW_TRIGGER_POLLER_ENABLED=true # accepts 1/true to enable, 0/false to disable (default: false; any other value is a fatal startup error)
|
||
# IRONCLAW_TRIGGER_POLLER_INTERVAL_SECS=60 # how often the poller checks for due triggers (integer seconds, 1..=3600)
|
||
# IRONCLAW_CREDENTIAL_REFRESH_ENABLED=true # accepts 1/true to enable, 0/false to disable (default: false; any other value is a fatal startup error)
|
||
|
||
# Turn-runner concurrency (overrides the config-file [runner] section)
|
||
# Highest-precedence layer; a set-but-blank value is a fatal startup error.
|
||
# For every knob below, 0 means "unlimited". Use 0 to stress-test the DB
|
||
# backend (e.g. libSQL) with no concurrency throttle.
|
||
# IRONCLAW_REBORN_RUNNER_WORKER_COUNT=16 # global scheduler slots; 0 = unlimited; positive = that many, verbatim; default 16
|
||
# IRONCLAW_REBORN_RUNNER_MAX_CONCURRENT_RUNS_PER_USER=3 # per (tenant, owner) cap; 0 = unlimited; default 3
|
||
# IRONCLAW_REBORN_RUNNER_MAX_CONCURRENT_TRIGGER_RUNS=8 # scheduled-trigger cap; 0 = unlimited; default 8
|
||
# IRONCLAW_REBORN_RUNNER_MAX_CONCURRENT_CONVERSATION_RUNS=0 # inbound/web cap; 0 = unlimited (default)
|
||
|
||
# Execute capability batches already classified safe for parallelism with a
|
||
# fixed fan-out of four. Default/off keeps the legacy sequential batch path.
|
||
# Accepted opt-in values: on, 1, true. Unknown values fail closed to off.
|
||
# REBORN_PARALLEL_TOOL_BATCH=off
|
||
|
||
# Railway Sandboxes preview. Preferred IronClaw-scoped identifiers fall back
|
||
# to RAILWAY_PROJECT_ID / RAILWAY_ENVIRONMENT_ID used by the Railway CLI.
|
||
# Set exactly one of RAILWAY_TOKEN or RAILWAY_API_TOKEN in the deployment.
|
||
# IRONCLAW_REBORN_RAILWAY_PROJECT_ID=
|
||
# IRONCLAW_REBORN_RAILWAY_ENVIRONMENT_ID=
|
||
# IRONCLAW_REBORN_RAILWAY_CLI_PATH=railway
|
||
# IRONCLAW_REBORN_RAILWAY_IDLE_TIMEOUT_MINUTES=30
|
||
# IRONCLAW_REBORN_RAILWAY_WORKER_IMAGE=python:3.12-slim@sha256:57cd7c3a7a273101a6485ba99423ee568157882804b1124b4dd04266317710de
|
||
# RAILWAY_TOKEN=
|
||
# RAILWAY_API_TOKEN=
|
||
|
||
# Reborn skill prompt injection: "listing" (default) advertises non-activated
|
||
# skills as a one-line "- name: description" listing and loads a skill's full
|
||
# instructions only on explicit $name mention or builtin.skill_activate;
|
||
# "full" restores the legacy inject-bodies-by-keyword-score behavior.
|
||
# IRONCLAW_REBORN_SKILL_INJECTION=listing
|
||
|
||
# Docker Sandbox
|
||
# SANDBOX_ENABLED=true
|
||
# SANDBOX_POLICY=readonly # readonly, workspace_write, or full_access
|
||
# SANDBOX_ALLOW_FULL_ACCESS=false # REQUIRED second opt-in for full_access policy.
|
||
# # FullAccess bypasses Docker entirely and runs
|
||
# # commands directly on the host. Without this
|
||
# # set to "true", full_access is downgraded to
|
||
# # workspace_write.
|
||
# SANDBOX_IMAGE=ironclaw-worker:latest
|
||
# SANDBOX_TIMEOUT_SECS=120
|
||
# SANDBOX_MEMORY_LIMIT_MB=2048
|
||
|
||
# Reborn sandbox container transport
|
||
# Overrides Docker daemon discovery for the Reborn sandbox transport. Accepts a
|
||
# unix socket path (optionally "unix://"-prefixed) or an http://host:port /
|
||
# tcp://host:port address. Unset means "probe local defaults, then the
|
||
# well-known unix sockets".
|
||
#
|
||
# SECURITY: the http(s)/tcp form is plaintext and unauthenticated; the Docker
|
||
# Engine API it reaches can create containers and mount host paths, so it is
|
||
# restricted to a unix socket or a loopback address ("localhost"/127.0.0.1/::1)
|
||
# by default. A non-loopback value (e.g. a remote daemon, or a DinD/CI sidecar
|
||
# reachable at a container-network IP) additionally requires
|
||
# IRONCLAW_REBORN_DOCKER_HOST_ALLOW_REMOTE=1 as an explicit second opt-in.
|
||
# IRONCLAW_REBORN_DOCKER_HOST=unix:///var/run/docker.sock
|
||
# IRONCLAW_REBORN_DOCKER_HOST_ALLOW_REMOTE=false # required to use a non-loopback IRONCLAW_REBORN_DOCKER_HOST
|
||
#
|
||
# Extra domains appended to the sandboxed shell's default egress allowlist
|
||
# (crates.io, npm, PyPI, the Go proxy, GitHub). Comma-separated hostnames;
|
||
# a leading "*." wildcard is allowed. A bare "*" is rejected (would allow
|
||
# every host). These add to the defaults, never replace them.
|
||
# IRONCLAW_SANDBOX_EXTRA_ALLOWED_DOMAINS=example.com,*.internal.example.com
|
||
#
|
||
# Per-request egress volume cap (bytes) for the sandboxed shell's network
|
||
# policy. Default 2147483648 (2 GiB) — generous enough for ordinary
|
||
# cargo/npm/pip/git workflows while still bounding a single request well
|
||
# short of a bulk-exfiltration attempt. Must be a positive integer; 0 or
|
||
# non-numeric values fail to start.
|
||
# IRONCLAW_SANDBOX_MAX_EGRESS_BYTES=2147483648
|
||
|
||
# ACP (Agent Client Protocol) agents
|
||
# ACP_ENABLED=false # Enable ACP agent sandbox mode
|
||
# ACP_MEMORY_LIMIT_MB=4096 # Memory limit for ACP containers
|
||
# ACP_TIMEOUT_SECS=1800 # Maximum session timeout
|
||
# Configure agents via CLI: ironclaw acp add goose --command goose --arg "--stdio"
|
||
|
||
# Safety settings
|
||
SAFETY_MAX_OUTPUT_LENGTH=100000
|
||
SAFETY_INJECTION_CHECK_ENABLED=true
|
||
|
||
# Restart Feature (Docker containers only)
|
||
# Set IRONCLAW_IN_DOCKER=true in the container entrypoint to enable the restart feature.
|
||
# Without this, the restart tool and /restart command will be disabled.
|
||
# IRONCLAW_IN_DOCKER=false
|
||
# IRONCLAW_RESTART_DELAY=5 # default wait before exit (seconds, range: 1-30)
|
||
# IRONCLAW_MAX_FAILURES=10 # max consecutive failures before container exits
|
||
|
||
# ─── OAuth / Social Login ────────────────────────────────────────────────
|
||
# Enable direct OAuth login (Google, GitHub). Disabled by default.
|
||
# OAUTH_ENABLED=true
|
||
|
||
# Base URL for OAuth callback URLs. Defaults to http://localhost:{GATEWAY_PORT}.
|
||
# Set this to your public URL in production (e.g., https://myapp.example.com).
|
||
# OAUTH_BASE_URL=https://myapp.example.com
|
||
|
||
# Restrict OAuth login to specific email domains (comma-separated).
|
||
# When set, only users with verified emails from these domains can log in.
|
||
# Applies to all OAuth providers and OIDC. Leave unset to allow all domains.
|
||
# OAUTH_ALLOWED_DOMAINS=company.com,partner.org
|
||
|
||
# Google OAuth — Create credentials at https://console.cloud.google.com/apis/credentials
|
||
# 1. Create an OAuth 2.0 Client ID (Web application type)
|
||
# 2. Add authorized redirect URI: {OAUTH_BASE_URL}/auth/callback/google
|
||
# 3. Copy Client ID and Client Secret below
|
||
# GOOGLE_CLIENT_ID=
|
||
# GOOGLE_CLIENT_SECRET=
|
||
# GOOGLE_OAUTH_REDIRECT_URI=https://myapp.example.com/auth/callback/google
|
||
|
||
# Reborn Product Auth Google OAuth setup recovery.
|
||
# Prefer these Reborn-specific vars when configuring the WebChat v2 setup flow.
|
||
# IRONCLAW_REBORN_GOOGLE_CLIENT_ID=
|
||
# IRONCLAW_REBORN_GOOGLE_CLIENT_SECRET=
|
||
# IRONCLAW_REBORN_GOOGLE_OAUTH_REDIRECT_URI=https://myapp.example.com/api/reborn/product-auth/oauth/google/callback
|
||
# Optional Reborn setup hint. CURRENTLY INERT (measured 2026-08-05): the value
|
||
# is resolved and stored but nothing reads it, because the auth engine builds
|
||
# its authorization parameters from the vendor recipe's manifest
|
||
# `extra_authorize_params` and the Google recipes declare no `hd`. Setting it
|
||
# adds nothing. For real Google-Workspace restriction of WebChat *login*, use
|
||
# IRONCLAW_REBORN_WEBUI_GOOGLE_ALLOWED_HD below instead.
|
||
# IRONCLAW_REBORN_GOOGLE_HOSTED_DOMAIN_HINT=company.com
|
||
|
||
# Restrict Google login to a specific Workspace (G Suite) domain.
|
||
# Adds the `hd` parameter to the authorization URL and validates server-side.
|
||
# GOOGLE_ALLOWED_HD=company.com
|
||
|
||
# Apple Sign In — Configure in https://developer.apple.com/account/resources/identifiers
|
||
# 1. Register a Services ID (e.g. com.example.myapp) under Identifiers
|
||
# 2. Enable "Sign In with Apple" and configure the return URL: {OAUTH_BASE_URL}/auth/callback/apple
|
||
# 3. Create a key (Keys section), enable "Sign In with Apple", download the .p8 file
|
||
# 4. Note your Team ID (top right of developer portal) and Key ID
|
||
# APPLE_CLIENT_ID=com.example.myapp
|
||
# APPLE_TEAM_ID=XXXXXXXXXX
|
||
# APPLE_KEY_ID=YYYYYYYYYY
|
||
# APPLE_PRIVATE_KEY_PATH=/path/to/AuthKey_YYYYYYYYYY.p8
|
||
# Or inline: APPLE_PRIVATE_KEY_PEM="-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----"
|
||
|
||
# GitHub OAuth — Create an OAuth App at https://github.com/settings/developers
|
||
# 1. Create a new OAuth App
|
||
# 2. Set Authorization callback URL to: {OAUTH_BASE_URL}/auth/callback/github
|
||
# 3. Copy Client ID and generate a Client Secret below
|
||
# GITHUB_CLIENT_ID=
|
||
# GITHUB_CLIENT_SECRET=
|
||
|
||
# NEAR Wallet — No external setup needed. Users sign in with any NEAR wallet
|
||
# (HOT, Meteor, MyNearWallet, etc.) via the near-connect SDK.
|
||
# NEAR_AUTH_ENABLED=true
|
||
# NEAR_AUTH_NETWORK=mainnet # or testnet
|
||
# NEAR_AUTH_RPC_URL=https://rpc.mainnet.near.org # auto-detected from network
|
||
|
||
# ─── OIDC / SSO (Okta, Cognito, etc.) ──────────────────────────────────
|
||
# For reverse-proxy SSO (e.g., AWS ALB + Okta). The gateway validates JWTs
|
||
# from the configured header. See also OAUTH_ALLOWED_DOMAINS above, which
|
||
# applies to OIDC logins too.
|
||
# GATEWAY_OIDC_ENABLED=true
|
||
# GATEWAY_OIDC_JWKS_URL=https://your-idp.example.com/.well-known/jwks.json
|
||
# GATEWAY_OIDC_HEADER=x-amzn-oidc-data
|
||
# GATEWAY_OIDC_ISSUER=https://your-idp.example.com
|
||
# GATEWAY_OIDC_AUDIENCE=your-client-id
|
||
|
||
# ─── Reborn WebUI v2 (`ironclaw serve`) ─────────────────────────
|
||
# The Reborn binary is separate from v1 and does not share auth/middleware
|
||
# with the v1 channels/web stack. These variables configure the v2 native
|
||
# HTTP surface owned by `crates/product/ironclaw_webui`. They have
|
||
# no effect on the v1 binary.
|
||
#
|
||
# Bearer token consulted by `EnvBearerAuthenticator`. Keep this in the
|
||
# environment ONLY — operators must NOT put the token value into
|
||
# `config.toml`. The token is compared with `subtle::ConstantTimeEq` so
|
||
# leading/trailing whitespace counts.
|
||
# IRONCLAW_REBORN_WEBUI_TOKEN=replace-with-strong-random-token
|
||
#
|
||
# UserId stamped onto the `WebUiAuthenticatedCaller` when the bearer
|
||
# token matches. Pair this with the tenant_id resolved from
|
||
# `[identity].installation_tenant` in `config.toml`.
|
||
# IRONCLAW_REBORN_WEBUI_USER_ID=reborn-cli-operator
|
||
#
|
||
# Optional path under /opt/ironclaw to the default TOML copied into
|
||
# `$IRONCLAW_REBORN_HOME/config.toml` by the Reborn Docker entrypoint on first
|
||
# start. Existing home configs are preserved.
|
||
# IRONCLAW_REBORN_DEFAULT_CONFIG=/opt/ironclaw/reborn/config.toml
|
||
#
|
||
# Show the WebChat v2 Projects surface (the conversations-panel "Projects"
|
||
# entry + the /projects route). Hidden by default while the surface is still
|
||
# being finished. The flag is read at serve composition and delivered to the
|
||
# browser via `GET /api/webchat/v2/session` (`features.reborn_projects`).
|
||
# IRONCLAW_REBORN_PROJECTS=true
|
||
#
|
||
# Enable QA-only scrubbed run and full-thread regression artifact downloads.
|
||
# Disabled by default: production users receive no download affordance and the
|
||
# artifact HTTP routes are not mounted. Enable only on trusted QA deployments.
|
||
# IRONCLAW_REBORN_REGRESSION_ARTIFACT_EXPORT=true
|
||
#
|
||
# Enable the admin thread-scraping panel (cross-user transcript artifact
|
||
# collection for debugging/optimization). Disabled by default and gated
|
||
# independently of the QA-only regression export flag: enabling QA self-export
|
||
# must never silently mount tenant-wide admin transcript access.
|
||
# IRONCLAW_REBORN_ADMIN_THREAD_SCRAPE=true
|
||
#
|
||
# Tenant-shared tool credentials (#5459). Any variable matching
|
||
# `IRONCLAW_REBORN_DEV_SECRET__<handle>=<value>` is read once at `serve`
|
||
# startup and stored under `<handle>` at the tenant-shared, admin-managed
|
||
# secret scope, so a keyed WASM tool (network + `use_secret`) resolves its
|
||
# credential for EVERY user of the tenant from one operator-set key. The
|
||
# credential resolver checks the caller's own scope first and falls back to
|
||
# the tenant-shared scope; if neither has the key the tool gates with
|
||
# AuthRequired. The `<handle>` suffix must match the `handle` declared in the
|
||
# tool manifest's `runtime_credentials` (e.g. `market_data_api_key`).
|
||
# Ops/dev provisioning path; inert unless set.
|
||
# IRONCLAW_REBORN_DEV_SECRET__market_data_api_key=replace-with-shared-api-key
|
||
#
|
||
# Reborn Docker deployment/runtime knobs. Keep the local serve host loopback
|
||
# unless a platform such as Railway is fronting the container and requires
|
||
# 0.0.0.0. `IRONCLAW_REBORN_CONFIRM_HOST_ACCESS` is only for
|
||
# local-dev-yolo-style trusted host access and should stay unset for public
|
||
# container deployments.
|
||
#
|
||
# The Reborn Docker image defaults to local-dev so local `docker run` does not
|
||
# require Postgres. Set IRONCLAW_REBORN_PROFILE=production on Railway to seed
|
||
# the production/Postgres config and keep user extension install/activation
|
||
# state durable across image redeploys. If you keep local-dev/local-dev-yolo on
|
||
# Railway, attach a persistent volume at /data or set IRONCLAW_REBORN_HOME under
|
||
# RAILWAY_VOLUME_MOUNT_PATH; otherwise local-dev extension state under
|
||
# `$IRONCLAW_REBORN_HOME/local-dev/system/extensions` is container-local. The
|
||
# entrypoint fails closed for Railway local-dev profiles without a volume unless
|
||
# IRONCLAW_REBORN_ALLOW_EPHEMERAL_RAILWAY=true is set for disposable tests.
|
||
# IRONCLAW_REBORN_HOME=/data/ironclaw-reborn
|
||
# IRONCLAW_REBORN_PROFILE=local-dev
|
||
# IRONCLAW_REBORN_LOG=info
|
||
# IRONCLAW_REBORN_POSTGRES_URL=postgres://user:password@db.example.com/ironclaw?sslmode=require
|
||
# IRONCLAW_REBORN_SECRET_MASTER_KEY=replace-with-independent-secret-key-material
|
||
# IRONCLAW_REBORN_SERVE_HOST=127.0.0.1
|
||
# IRONCLAW_REBORN_SERVE_PORT=3000
|
||
# IRONCLAW_REBORN_CONFIRM_HOST_ACCESS=false
|
||
#
|
||
# There is no Slack or Telegram enablement variable. Channel webhook routes are
|
||
# always mounted; a channel goes live when its extension is installed and set up
|
||
# in the WebUI at /extensions.
|
||
#
|
||
# WebChat v2 SSO login (Google / GitHub). Setting either CLIENT_ID
|
||
# surfaces that provider's login button on the `serve` listener; the
|
||
# matching CLIENT_SECRET is required for the real code exchange. Each
|
||
# distinct OAuth identity maps to its own persisted user (looked up by
|
||
# provider + subject, linked across providers by a verified email), so
|
||
# different people who log in become different users with isolated
|
||
# threads. Every session is a stateless signed token (keyed off
|
||
# IRONCLAW_REBORN_WEBUI_TOKEN + the host tenant), accepted alongside the
|
||
# env bearer above.
|
||
#
|
||
# Admission is fail-closed: when a provider is configured you MUST set
|
||
# IRONCLAW_REBORN_WEBUI_ALLOWED_EMAIL_DOMAINS (below) — otherwise `serve`
|
||
# refuses to start. GitHub has no org allowlist and Google's `hd` check is
|
||
# optional, so without an email-domain allowlist any Google/GitHub account
|
||
# could log in (open registration).
|
||
#
|
||
# These deliberately live in the IRONCLAW_REBORN_WEBUI_* namespace,
|
||
# SEPARATE from the bare GOOGLE_CLIENT_ID / IRONCLAW_REBORN_GOOGLE_* vars
|
||
# in the OAuth section above:
|
||
# - bare GOOGLE_CLIENT_ID / GITHUB_CLIENT_ID → v1 gateway SSO login.
|
||
# - IRONCLAW_REBORN_GOOGLE_* → Reborn product-auth
|
||
# (connect a Google *credential* for the agent; requires a redirect
|
||
# URI). Setting these without the redirect URI makes every
|
||
# ironclaw command fail at startup — keep them unset unless
|
||
# you are configuring product-auth.
|
||
# - IRONCLAW_REBORN_WEBUI_GOOGLE_* (here) → Reborn WebChat *login*.
|
||
# Register {base}/auth/callback/{provider} as the authorized redirect URI,
|
||
# where {base} is IRONCLAW_REBORN_WEBUI_BASE_URL below (or the bound
|
||
# listener address in local dev).
|
||
# IRONCLAW_REBORN_WEBUI_GOOGLE_CLIENT_ID=
|
||
# IRONCLAW_REBORN_WEBUI_GOOGLE_CLIENT_SECRET=
|
||
# Optional: additionally restrict Google login to one Workspace domain
|
||
# (server-side `hd` claim) — narrower than the email-domain allowlist below.
|
||
# IRONCLAW_REBORN_WEBUI_GOOGLE_ALLOWED_HD=example.com
|
||
# IRONCLAW_REBORN_WEBUI_GITHUB_CLIENT_ID=
|
||
# IRONCLAW_REBORN_WEBUI_GITHUB_CLIENT_SECRET=
|
||
#
|
||
# REQUIRED when any provider above is configured: comma-separated list of
|
||
# verified-email domains allowed to log in. A login is admitted only when
|
||
# the provider asserts a VERIFIED email whose domain is in this list;
|
||
# everyone else is rejected and no session is minted. Set it to your own
|
||
# domain(s).
|
||
# IRONCLAW_REBORN_WEBUI_ALLOWED_EMAIL_DOMAINS=example.com,team.example.com
|
||
#
|
||
# Public base URL used to build the OAuth callback URLs for Reborn WebUI
|
||
# login and product-auth flows, including Notion MCP. Reborn-scoped only —
|
||
# it does NOT fall back to the v1 gateway's OAUTH_BASE_URL, so a legacy v1
|
||
# setting cannot rewrite Reborn callback URLs. Absent this var, Reborn uses
|
||
# the bound listener address. Set it to your public URL in production. Google
|
||
# product-auth still uses IRONCLAW_REBORN_GOOGLE_OAUTH_REDIRECT_URI explicitly.
|
||
# IRONCLAW_REBORN_WEBUI_BASE_URL=https://myapp.example.com
|
||
#
|
||
# Optional per-call HTTP timeout (whole seconds) for the OAuth provider
|
||
# token/userinfo requests, applied to every configured provider. Defaults
|
||
# to 20s. Raise it on a slow or cross-border path to the provider (e.g.
|
||
# `github.com`) where the exchange times out. If the provider host is
|
||
# actually blocked/throttled, route through a proxy instead — the OAuth
|
||
# client honors the standard HTTPS_PROXY / ALL_PROXY env vars.
|
||
# IRONCLAW_REBORN_WEBUI_OAUTH_HTTP_TIMEOUT_SECS=30
|
||
|
||
# ─── Skills ────────────────────────────────────────────────────────────
|
||
# Regex-pattern skill auto-activation is a config-file setting, not an env
|
||
# var: set `regex_activation_enabled = false` under `[skills]` in the
|
||
# ironclaw config file to make only keyword/tag activation and explicit
|
||
# `/skill` mentions select a skill (see
|
||
# crates/app/ironclaw_config/src/config_file.rs, SkillsSection). The former
|
||
# SKILLS_REGEX_ACTIVATION_ENABLED env var is not read by anything.
|
||
|
||
# ─── Test / CI: OS keychain ────────────────────────────────────────────
|
||
# Set to "1" to stop the secrets master-key lookup from touching the real OS
|
||
# keychain (macOS Keychain / Linux Secret Service). Without it, a test or
|
||
# tool run that resolves the master key while SECRETS_MASTER_KEY is unset
|
||
# pops a macOS Keychain authorization dialog (or blocks on a locked Secret
|
||
# Service). Crate unit tests are already covered by cfg!(test); set this for
|
||
# integration/e2e runs (the CI workflows set it automatically). Leave UNSET in
|
||
# production so the real keychain fallback works.
|
||
# IRONCLAW_DISABLE_OS_KEYCHAIN=1
|
||
|
||
# Logging
|
||
RUST_LOG=ironclaw=debug,tower_http=debug
|