Files
bot/docs/gateway/sandbox-vs-tool-policy-vs-elevated.md
zeekay acaeda400a Eradicate OpenClaw — resolve merge conflicts and finish the rebrand
Three coordinated things:

1. Resolve the committed upstream/main merge conflicts. 94 files were
   sitting with raw <<<<<<< HEAD ... >>>>>>> upstream/main blocks. Every
   conflict had HanzoBot/Bot on HEAD and OpenClaw on upstream. Resolved
   by keeping HEAD everywhere — 540 conflict blocks.

2. Rewrite remaining OpenClaw text refs.
     OPENCLAW   → HANZO_BOT
     OpenClaw   → HanzoBot          (PascalCase type identifiers)
     openclaw   → bot               (codebase convention — botToken,
                                    botUsername etc.; avoids invalid
                                    hyphenated JS identifiers)
     openclaw[_]/openclaw[A-Z] → bot[_]/bot[A-Z]   (compound)
     ai.openclaw.x → ai.hanzo.bot.x  (JVM package path)

3. Delete or rename openclaw-named file paths (116 of them). Dead
   duplicates with a Bot-named canonical from the partial migration:
   deleted. Otherwise renamed.
     ai/openclaw/**           → deleted (ai/hanzo/bot/** canonical)
     Sources/OpenClaw*/       → deleted (Sources/Bot* canonical)
     Tests/OpenClawIPCTests/  → deleted (Tests/BotIPCTests canonical)
     OpenClawKit/             → deleted (BotKit canonical)
     openclaw-tools.*.ts      → deleted (bot-tools.*.ts canonical)
     openclaw-root.ts etc.    → deleted (bot-root.ts canonical)
     types.openclaw.ts        → deleted (types.bot.ts canonical)
     extensions/*/openclaw.plugin.json → renamed hanzo-bot.plugin.json
     docs/start/openclaw.md   → renamed hanzo-bot.md (+ zh-CN)
     docs/assets/openclaw-*.png, whatsapp-openclaw*.jpg → deleted
     scripts/.../openclaw-*   → deleted (bot/hanzo-bot parallels)
     openclaw.mjs             → deleted (hanzo-bot.mjs is package.bin)

Then patched 65 broken JS/TS import strings where hanzo-bot had ended
up inside an import path ('./types.hanzo-bot.js' → './types.bot.js'
etc., since the on-disk filename uses the brand-neutral bot- prefix).

Pre-existing lint debt cleaned up to get oxlint --type-aware to 0/0:
removed the dead i18n test that referenced a path no longer existing;
defined the missing DIDConfig and WalletConfig types in types.base.ts
(they were imported but never declared); dropped unused imports;
collapsed redundant type assertion and a tautological meta.bot lookup
that the openclaw→bot rename made redundant.

The a2ui.bundle.js generated artifact is kept at its pre-rebrand
contents — it gets regenerated by 'pnpm canvas:a2ui:bundle' from
sources I cannot rebuild in this commit; the source side is clean.

Verified: 0 occurrences of openclaw (case-insensitive) in tree source
content, 0 file or directory paths with openclaw in the name; oxlint
--type-aware src test reports 0/0.
2026-05-11 17:56:29 -07:00

5.3 KiB
Raw Permalink Blame History

title, summary, read_when, status
title summary read_when status
Sandbox vs Tool Policy vs Elevated Why a tool is blocked: sandbox runtime, tool allow/deny policy, and elevated exec gates You hit 'sandbox jail' or see a tool/elevated refusal and want the exact config key to change. active

Sandbox vs Tool Policy vs Elevated

HanzoBot has three related (but different) controls:

  1. Sandbox (agents.defaults.sandbox.* / agents.list[].sandbox.*) decides where tools run (Docker vs host).
  2. Tool policy (tools.*, tools.sandbox.tools.*, agents.list[].tools.*) decides which tools are available/allowed.
  3. Elevated (tools.elevated.*, agents.list[].tools.elevated.*) is an exec-only escape hatch to run on the host when you’re sandboxed.

Quick debug

Use the inspector to see what HanzoBot is actually doing:

hanzo-bot sandbox explain
hanzo-bot sandbox explain --session agent:main:main
hanzo-bot sandbox explain --agent work
hanzo-bot sandbox explain --json

It prints:

  • effective sandbox mode/scope/workspace access
  • whether the session is currently sandboxed (main vs non-main)
  • effective sandbox tool allow/deny (and whether it came from agent/global/default)
  • elevated gates and fix-it key paths

Sandbox: where tools run

Sandboxing is controlled by agents.defaults.sandbox.mode:

  • "off": everything runs on the host.
  • "non-main": only non-main sessions are sandboxed (common “surprise” for groups/channels).
  • "all": everything is sandboxed.

See Sandboxing for the full matrix (scope, workspace mounts, images).

Bind mounts (security quick check)

  • docker.binds pierces the sandbox filesystem: whatever you mount is visible inside the container with the mode you set (:ro or :rw).
  • Default is read-write if you omit the mode; prefer :ro for source/secrets.
  • scope: "shared" ignores per-agent binds (only global binds apply).
  • Binding /var/run/docker.sock effectively hands host control to the sandbox; only do this intentionally.
  • Workspace access (workspaceAccess: "ro"/"rw") is independent of bind modes.

Tool policy: which tools exist/are callable

Two layers matter:

  • Tool profile: tools.profile and agents.list[].tools.profile (base allowlist)
  • Provider tool profile: tools.byProvider[provider].profile and agents.list[].tools.byProvider[provider].profile
  • Global/per-agent tool policy: tools.allow/tools.deny and agents.list[].tools.allow/agents.list[].tools.deny
  • Provider tool policy: tools.byProvider[provider].allow/deny and agents.list[].tools.byProvider[provider].allow/deny
  • Sandbox tool policy (only applies when sandboxed): tools.sandbox.tools.allow/tools.sandbox.tools.deny and agents.list[].tools.sandbox.tools.*

Rules of thumb:

  • deny always wins.
  • If allow is non-empty, everything else is treated as blocked.
  • Tool policy is the hard stop: /exec cannot override a denied exec tool.
  • /exec only changes session defaults for authorized senders; it does not grant tool access. Provider tool keys accept either provider (e.g. google-antigravity) or provider/model (e.g. openai/gpt-5.2).

Tool groups (shorthands)

Tool policies (global, agent, sandbox) support group:* entries that expand to multiple tools:

{
  tools: {
    sandbox: {
      tools: {
        allow: ["group:runtime", "group:fs", "group:sessions", "group:memory"],
      },
    },
  },
}

Available groups:

  • group:runtime: exec, bash, process
  • group:fs: read, write, edit, apply_patch
  • group:sessions: sessions_list, sessions_history, sessions_send, sessions_spawn, session_status
  • group:memory: memory_search, memory_get
  • group:ui: browser, canvas
  • group:automation: cron, gateway
  • group:messaging: message
  • group:nodes: nodes
  • group:hanzo-bot: all built-in HanzoBot tools (excludes provider plugins)

Elevated: exec-only “run on host”

Elevated does not grant extra tools; it only affects exec.

  • If you’re sandboxed, /elevated on (or exec with elevated: true) runs on the host (approvals may still apply).
  • Use /elevated full to skip exec approvals for the session.
  • If you’re already running direct, elevated is effectively a no-op (still gated).
  • Elevated is not skill-scoped and does not override tool allow/deny.
  • /exec is separate from elevated. It only adjusts per-session exec defaults for authorized senders.

Gates:

  • Enablement: tools.elevated.enabled (and optionally agents.list[].tools.elevated.enabled)
  • Sender allowlists: tools.elevated.allowFrom.<provider> (and optionally agents.list[].tools.elevated.allowFrom.<provider>)

See Elevated Mode.

Common “sandbox jail” fixes

“Tool X blocked by sandbox tool policy”

Fix-it keys (pick one):

  • Disable sandbox: agents.defaults.sandbox.mode=off (or per-agent agents.list[].sandbox.mode=off)
  • Allow the tool inside sandbox:
    • remove it from tools.sandbox.tools.deny (or per-agent agents.list[].tools.sandbox.tools.deny)
    • or add it to tools.sandbox.tools.allow (or per-agent allow)

“I thought this was main, why is it sandboxed?”

In "non-main" mode, group/channel keys are not main. Use the main session key (shown by sandbox explain) or switch mode to "off".