#sandbox exec

10 messages Β· Page 1 of 1 (latest)

peak jacinth
#

Can tools.exec.host be set per-agent instead of globally?

We have a multi-agent setup where:

  • main (Bugg) needs host: "gateway" β€” he runs operational commands (send-broker, systemctl, curl) on the host
  • Coding team agents (architect, senior-eng, junior-eng, reviewer) need host: "sandbox" β€” they should run in Docker containers so they can do
    whatever they want without exec approvals

Currently tools.exec.host is global in openclaw.json. The per-agent config in exec-approvals.json has security/ask/allowlist but no host field.

Is there a way to set host: "sandbox" for specific agents while keeping host: "gateway" for main? Either via exec-approvals.json, per-agent config
in openclaw.json, or some other mechanism?

If not, is there a workaround β€” like having the coding team agents request host: "sandbox" in their exec params and having the platform honor that
override even when the global default is gateway?

shrewd quiverBOT
cursive bearBOT
#

To help others find answers, you can mark your question as solved via Right click solution message -> Apps -> βœ… Mark Solution

shrewd quiverBOT
thorny baneBOT
#

Yes, on current OpenClaw you can set it per agent in config.

What works:

  • tools.exec.host globally
  • agents.list[].tools.exec.host per agent
  • session-level /exec host=... overrides

What does not work:

  • ~/.openclaw/exec-approvals.json for host routing. That file is for approval policy, security, ask, allowlist, etc., not host selection.

So your setup can be:

{
  tools: {
    exec: {
#
      host: "gateway"
    }
  },
  agents: {
    list: [
      { id: "main", tools: { exec: { host: "gateway" } } },
      { id: "architect", tools: { exec: { host: "sandbox" } } },
      { id: "senior-eng", tools: { exec: { host: "sandbox" } } },
      { id: "junior-eng", tools: { exec: { host: "sandbox" } } },
      { id: "reviewer", tools: { exec: { host: "sandbox" } } }
    ]
  }
}

Important gotcha:

#
  • if an agent has tools.exec.host: "sandbox" but that agent's sandbox mode is off, exec fails closed for that agent.

On the override question, no, a pinned host: "gateway" is not something the tool can freely override to sandbox per call. Current behavior is basically:

  • session override
  • then per-agent config
  • then global config

If you want the coding agents on sandbox, set them that way in agents.list[].tools.exec.host, don't rely on tool-call overrides.

Also, if Bugg is not sandboxed, global tools.exec.host: "auto" may already do what you want, sandboxed agents use sandbox, non-sandboxed ones fall back to gateway. But for deterministic behavior, your per-agent split is cleaner.

Docs:

If your local build rejects agents.list[].tools.exec.host, paste openclaw --version, this may be a version gap.

peak jacinth
#

Can a sandboxed agent call run_workflow_step or spawn subagent sessions?

We have coding team agents (senior-eng, junior-eng, reviewer) set to tools.exec.host: "sandbox". The run_workflow_step tool checks if (ctx.sandboxed) return null and hides itself
from sandboxed agents.

We want senior-eng (Whiskeyjack) to be able to delegate tasks to junior-eng (Bottle) workers β€” essentially calling run_workflow_step from inside a sandboxed session.

Options we see:

  1. Remove the if (ctx.sandboxed) return null guard from the workflow-step plugin (is this safe?)
  2. Use a different mechanism β€” can sandboxed agents call sessions_spawn or agentToAgent?
  3. Keep delegation in the engine (sidecar dispatches Bottles on Whiskeyjack's behalf, not Whiskeyjack directly)

What's the recommended pattern for agent-to-agent delegation when the orchestrating agent is sandboxed?

thorny baneBOT
#

Yes, for built-in delegation the recommended path is sessions_spawn, not removing the sandbox guard on your custom run_workflow_step.

Short version:

  • run_workflow_step: I would not just remove if (ctx.sandboxed) return null unless that plugin also enforces the same guardrails as core subagents.
  • sessions_spawn: yes, a sandboxed agent can use it, as long as the tool is allowed. The important guard is that a sandboxed requester can only spawn sandboxed children.
  • agentToAgent: this is not a separate spawn tool. It is the policy gate for cross-agent sessions_list / sessions_history / sessions_send / session_status.

What I’d recommend for Whiskeyjack β†’ Bottle worker delegation:

  1. Keep Whiskeyjack sandboxed.
  2. Let Whiskeyjack use sessions_spawn with regular runtime: "subagent" (default).
  3. Call it with sandbox: "require" so worker spawns fail fast if the target child would be unsandboxed.
  4. Restrict targets with agents.list[].subagents.allowAgents.
  5. If Whiskeyjack itself is a spawned subagent and needs to spawn Bottle children, set agents.defaults.subagents.maxSpawnDepth: 2.

Important caveats:

#
  • If the requester session is sandboxed, sessions_spawn rejects unsandboxed targets.
  • ACP spawns are blocked from sandboxed sessions, so use normal subagents here, not runtime: "acp".
  • If you want cross-agent sessions_send from a sandboxed session, you also need:
    • tools.agentToAgent.enabled=true
    • tools.agentToAgent.allow=[...]
    • tools.sessions.visibility="all"
    • and if sandbox visibility is still clamped to spawned sessions, loosen agents.defaults.sandbox.sessionToolsVisibility

So for your options:

  1. Remove the guard? Not my recommendation.
  2. Use something else? Yes, sessions_spawn is the intended pattern.
  3. Keep delegation in the engine? Also valid, if you want deterministic orchestration and tighter control, but that is more of a custom control-plane design than the built-in agent delegation path.

If you want, the clean pattern is basically:

  • Whiskeyjack: sandboxed orchestrator