IronClaw Configuration Reference
IronClaw's config file lives at ~/.ironclaw/ironclaw.json in JSON5 format. It shares most of its top-level structure with OpenClaw's config — the major additions are the security block and stricter validation rules on existing fields. This page documents the IronClaw-specific fields; for shared fields like session, cron, and gateway see the OpenClaw Configuration Reference.
ironclaw onboard — first-time wizard, creates the initial config
ironclaw config get <key> — read a specific value
ironclaw config set <key> <value> — update and reload
ironclaw config schema — full JSON Schema including security block
ironclaw doctor — validate config and diagnose issues
ironclaw doctor --fix — auto-repair common config problems
Top-Level Structure
| Key | In OpenClaw? | Purpose |
|---|---|---|
agents | Yes (same) | Model config, skills list, workspace, heartbeat |
channels | Yes (stricter) | Channel integrations — dmPolicy: "open" rejected |
session | Yes (same) | Conversation scope and reset behaviour |
gateway | Yes (same) | Port, bind address, auth token, reload mode |
cron | Yes (same) | Scheduled job settings |
env | Yes (stricter) | Environment variables — wildcard grants rejected |
security | IronClaw only | Sandbox mode, audit log, injection defense, auto-suspend |
allowlist | IronClaw only | Global allowlist settings (path, validation mode) |
security — The IronClaw-Specific Block
The security block is the main addition over OpenClaw. All fields have safe defaults — the onboarding wizard configures them correctly, but you can tune them here.
{
security: {
// Sandbox enforcement mode
sandbox: {
mode: "strict", // strict | standard | audit-only
// strict: syscall-level enforcement (default, recommended)
// standard: application-level enforcement only (faster, less isolation)
// audit-only: no blocking, logging only — NEVER use in production
},
// Mandatory audit log — cannot be disabled
auditLog: {
path: "~/.ironclaw/audit.log",
maxSizeMb: 100, // rotate when log exceeds this size
keepDays: 90, // delete rotated logs older than this
compress: true, // gzip rotated log files
logContent: false // if true, logs full message content (privacy risk)
},
// Prompt injection detection
injectionDefense: {
mode: "flag", // flag | block | off
// flag: detect and mark in context, let model handle it (default)
// block: refuse to process flagged content, return error to agent
// off: no detection (not recommended)
logDetections: true, // write INJECTION_DETECTED events to audit log
},
// Auto-suspend skills that repeatedly violate their grants
autoSuspend: {
enabled: true,
violationsPerWindow: 5, // violations before suspension
windowMinutes: 10, // time window for violation count
suspendDurationMinutes: 60 // how long to suspend (0 = until manual resume)
},
// Channel-level rate limiting (applies to all channels)
rateLimit: {
enabled: true,
messagesPerHour: 30, // per-user per-channel
burstLimit: 5 // max messages in any 60-second window
}
}
}
allowlist — Global Allowlist Settings
The allowlist config block controls where the allowlist file is stored and how it behaves. This is separate from the allowlist file itself (~/.ironclaw/allowlist.json).
{
allowlist: {
path: "~/.ironclaw/allowlist.json", // where the allowlist file lives
// What to do when a skill is called but not authorised
onDeny: "error", // error | silent | alert
// error: agent receives an error explaining the skill isn't authorised (default)
// silent: call is blocked without error — agent doesn't know
// alert: send a Telegram/channel message to allowedFrom users
// Whether skill installs auto-create a (not-authorised) allowlist entry
autoRegisterOnInstall: true, // adds skill to allowlist.json as authorised: false
// Makes 'ironclaw allowlist list' show installed-but-not-authorised skills
}
}
agents — Differences from OpenClaw
The agents block is almost identical to OpenClaw's. IronClaw adds one field: skillIsolation, which controls whether skills share a workspace or get their own subdirectory.
{
agents: {
defaults: {
workspace: "~/.ironclaw/workspace",
model: {
primary: "anthropic/claude-haiku-4-5",
fallbacks: ["anthropic/claude-sonnet-4-6"]
},
skills: [], // do NOT pre-populate — add to allowlist via CLI instead
// IronClaw addition: per-skill workspace isolation
skillIsolation: "per-skill",
// per-skill: each skill gets its own subdirectory (default, recommended)
// shared: all skills share the workspace (like OpenClaw)
heartbeat: {
every: "30m",
target: "last"
},
sandbox: {
mode: "strict", // inherits from security.sandbox.mode by default
scope: "agent"
}
}
}
}
channels — Stricter Rules
IronClaw rejects the following channel configurations at validation time — the gateway will not start if these are present:
dmPolicy: "open"— rejected. Use"allowlist".allowFrom: ["*"]— rejected. Specify numeric user IDs.- A channel with
enabled: truebut noallowFromarray — rejected.
{
channels: {
telegram: {
enabled: true,
botToken: "${TELEGRAM_BOT_TOKEN}",
dmPolicy: "allowlist", // only valid option in IronClaw
allowFrom: ["8734062810"], // required — no wildcards
// IronClaw addition: rate limiting per channel (overrides security.rateLimit)
rateLimit: {
messagesPerHour: 50,
burstLimit: 10
},
groups: {
"-1001234567890": {
requireMention: true,
allowFrom: ["8734062810"] // group-level allowFrom also required
}
}
}
}
}
env — Stricter Variable Rules
IronClaw rejects wildcard env var grants like "*" or "*_KEY" in the global env block. All environment variables accessible to the runtime must be named explicitly. API keys should live in the .env file and be referenced by env var name in the allowlist, not listed in ironclaw.json.
{
env: {
// Import from shell environment (recommended — keeps secrets out of config)
shellEnv: {
enabled: true,
timeoutMs: 15000
},
// IronClaw: wildcard grants in vars{} are rejected
// This is INVALID in IronClaw (valid in OpenClaw):
// vars: { "*_API_KEY": "..." }
// This is VALID — named vars only:
vars: {
HOME: "", // empty string = read from shell env
LANG: "",
TZ: ""
}
}
}
Complete Minimal Config Example
// ~/.ironclaw/ironclaw.json — minimal production config
{
agents: {
defaults: {
workspace: "~/.ironclaw/workspace",
skillIsolation: "per-skill",
model: {
primary: "anthropic/claude-haiku-4-5",
fallbacks: ["anthropic/claude-sonnet-4-6"]
},
heartbeat: { every: "1h", target: "last" }
}
},
channels: {
telegram: {
enabled: true,
botToken: "${TELEGRAM_BOT_TOKEN}",
dmPolicy: "allowlist",
allowFrom: ["YOUR_TELEGRAM_USER_ID"]
}
},
security: {
sandbox: { mode: "strict" },
auditLog: { path: "~/.ironclaw/audit.log", keepDays: 90 },
injectionDefense: { mode: "flag" },
autoSuspend: { enabled: true, violationsPerWindow: 5, windowMinutes: 10 },
rateLimit: { enabled: true, messagesPerHour: 30 }
},
allowlist: {
path: "~/.ironclaw/allowlist.json",
onDeny: "error"
},
gateway: {
port: 18790,
bind: "127.0.0.1",
auth: { token: "${IRONCLAW_GATEWAY_TOKEN}" }
},
env: {
shellEnv: { enabled: true }
}
}
Config Validation
IronClaw validates the config on every gateway start and on every ironclaw config set. Invalid configs prevent the gateway from starting — there's no "warn and continue" mode. Run the validator manually:
ironclaw config validate
# Example output for a common mistake:
# ERROR: channels.telegram.dmPolicy = "open" is not permitted in IronClaw.
# Use "allowlist" and specify numeric user IDs in allowFrom.
# See: https://openclawdatabase.com/ironclaw/configuration/#channels
ironclaw doctor --fix
# Auto-corrects: dmPolicy "open" → "allowlist"
# Prompts for allowFrom user IDs if missing
← Back to IronClaw hub · See also: OpenClaw Configuration Reference (shared fields) · Security Architecture · Skill Allowlisting