Last updated: 2026-04-06

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.

Quick commands

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

KeyIn OpenClaw?Purpose
agentsYes (same)Model config, skills list, workspace, heartbeat
channelsYes (stricter)Channel integrations — dmPolicy: "open" rejected
sessionYes (same)Conversation scope and reset behaviour
gatewayYes (same)Port, bind address, auth token, reload mode
cronYes (same)Scheduled job settings
envYes (stricter)Environment variables — wildcard grants rejected
securityIronClaw onlySandbox mode, audit log, injection defense, auto-suspend
allowlistIronClaw onlyGlobal 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: true but no allowFrom array — 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