Multi-Agent Sandbox & Tool-Konfiguration

Überblick

Jeder Agent in einem Multi-Agent-Setup kann jetzt seine eigene Konfiguration haben:

  • Sandbox-Konfiguration (agents.list[].sandbox überschreibt agents.defaults.sandbox)
  • Tool-Einschränkungen (tools.allow / tools.deny, plus agents.list[].tools)

Damit kannst du mehrere Agents mit unterschiedlichen Sicherheitsprofilen betreiben:

  • Persönlicher Assistent mit vollem Zugriff
  • Familien-/Arbeits-Agents mit eingeschränkten Tools
  • Öffentlich zugängliche Agents in Sandboxes

setupCommand gehört unter sandbox.docker (global oder pro Agent) und wird einmalig bei der Container-Erstellung ausgeführt.

Auth ist pro Agent: Jeder Agent liest aus seinem eigenen agentDir-Auth-Store unter:

~/.openclaw/agents/<agentId>/agent/auth-profiles.json

Credentials werden nicht zwischen Agents geteilt. Verwende agentDir niemals für mehrere Agents. Wenn du Credentials teilen willst, kopiere auth-profiles.json in das agentDir des anderen Agents.

Wie Sandboxing zur Laufzeit funktioniert, findest du unter Sandboxing. Zum Debuggen von “warum wird das blockiert?” siehe Sandbox vs Tool Policy vs Elevated und openclaw sandbox explain.


Konfigurationsbeispiele

Beispiel 1: Persönlicher + eingeschränkter Familien-Agent

{
  "agents": {
    "list": [
      {
        "id": "main",
        "default": true,
        "name": "Personal Assistant",
        "workspace": "~/.openclaw/workspace",
        "sandbox": { "mode": "off" }
      },
      {
        "id": "family",
        "name": "Family Bot",
        "workspace": "~/.openclaw/workspace-family",
        "sandbox": {
          "mode": "all",
          "scope": "agent"
        },
        "tools": {
          "allow": ["read"],
          "deny": ["exec", "write", "edit", "apply_patch", "process", "browser"]
        }
      }
    ]
  },
  "bindings": [
    {
      "agentId": "family",
      "match": {
        "provider": "whatsapp",
        "accountId": "*",
        "peer": {
          "kind": "group",
          "id": "[email protected]"
        }
      }
    }
  ]
}

Ergebnis:

  • main-Agent: Läuft auf dem Host, voller Tool-Zugriff
  • family-Agent: Läuft in Docker (ein Container pro Agent), nur read-Tool

Beispiel 2: Arbeits-Agent mit geteilter Sandbox

{
  "agents": {
    "list": [
      {
        "id": "personal",
        "workspace": "~/.openclaw/workspace-personal",
        "sandbox": { "mode": "off" }
      },
      {
        "id": "work",
        "workspace": "~/.openclaw/workspace-work",
        "sandbox": {
          "mode": "all",
          "scope": "shared",
          "workspaceRoot": "/tmp/work-sandboxes"
        },
        "tools": {
          "allow": ["read", "write", "apply_patch", "exec"],
          "deny": ["browser", "gateway", "discord"]
        }
      }
    ]
  }
}

Beispiel 2b: Globales Coding-Profil + Messaging-only Agent

{
  "tools": { "profile": "coding" },
  "agents": {
    "list": [
      {
        "id": "support",
        "tools": { "profile": "messaging", "allow": ["slack"] }
      }
    ]
  }
}

Ergebnis:

  • Standard-Agents bekommen Coding-Tools
  • support-Agent ist Messaging-only (+ Slack-Tool)

Beispiel 3: Unterschiedliche Sandbox-Modi pro Agent

{
  "agents": {
    "defaults": {
      "sandbox": {
        "mode": "non-main", // Globaler Standard
        "scope": "session"
      }
    },
    "list": [
      {
        "id": "main",
        "workspace": "~/.openclaw/workspace",
        "sandbox": {
          "mode": "off" // Override: main wird nie gesandboxt
        }
      },
      {
        "id": "public",
        "workspace": "~/.openclaw/workspace-public",
        "sandbox": {
          "mode": "all", // Override: public wird immer gesandboxt
          "scope": "agent"
        },
        "tools": {
          "allow": ["read"],
          "deny": ["exec", "write", "edit", "apply_patch"]
        }
      }
    ]
  }
}

Konfigurationsrangfolge

Wenn sowohl globale (agents.defaults.*) als auch agent-spezifische (agents.list[].*) Konfigurationen existieren:

Sandbox-Konfiguration

Agent-spezifische Einstellungen überschreiben globale:

agents.list[].sandbox.mode > agents.defaults.sandbox.mode
agents.list[].sandbox.scope > agents.defaults.sandbox.scope
agents.list[].sandbox.workspaceRoot > agents.defaults.sandbox.workspaceRoot
agents.list[].sandbox.workspaceAccess > agents.defaults.sandbox.workspaceAccess
agents.list[].sandbox.docker.* > agents.defaults.sandbox.docker.*
agents.list[].sandbox.browser.* > agents.defaults.sandbox.browser.*
agents.list[].sandbox.prune.* > agents.defaults.sandbox.prune.*

Hinweise:

  • agents.list[].sandbox.{docker,browser,prune}.* überschreibt agents.defaults.sandbox.{docker,browser,prune}.* für diesen Agent (wird ignoriert, wenn der Sandbox-Scope zu "shared" aufgelöst wird).

Tool-Einschränkungen

Die Filterreihenfolge ist:

  1. Tool-Profil (tools.profile oder agents.list[].tools.profile)
  2. Provider-Tool-Profil (tools.byProvider[provider].profile oder agents.list[].tools.byProvider[provider].profile)
  3. Globale Tool-Policy (tools.allow / tools.deny)
  4. Provider-Tool-Policy (tools.byProvider[provider].allow/deny)
  5. Agent-spezifische Tool-Policy (agents.list[].tools.allow/deny)
  6. Agent-Provider-Policy (agents.list[].tools.byProvider[provider].allow/deny)
  7. Sandbox-Tool-Policy (tools.sandbox.tools oder agents.list[].tools.sandbox.tools)
  8. Subagent-Tool-Policy (tools.subagents.tools, falls zutreffend)

Jede Ebene kann Tools weiter einschränken, aber keine auf einer früheren Ebene gesperrten Tools zurückgeben. Wenn agents.list[].tools.sandbox.tools gesetzt ist, ersetzt es tools.sandbox.tools für diesen Agent. Wenn agents.list[].tools.profile gesetzt ist, überschreibt es tools.profile für diesen Agent. Provider-Tool-Keys akzeptieren entweder provider (z.B. google-antigravity) oder provider/model (z.B. openai/gpt-5.2).

Tool-Gruppen (Kurzformen)

Tool-Policies (global, Agent, Sandbox) unterstützen group:*-Einträge, die sich zu mehreren konkreten Tools auflösen:

  • 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:openclaw: alle eingebauten OpenClaw-Tools (ohne Provider-Plugins)

Elevated-Modus

tools.elevated ist die globale Baseline (Sender-basierte Allowlist). agents.list[].tools.elevated kann Elevated für bestimmte Agents weiter einschränken (beide müssen erlauben).

Mitigationsmuster:

  • exec für nicht vertrauenswürdige Agents sperren (agents.list[].tools.deny: ["exec"])
  • Vermeide es, Sender in die Allowlist aufzunehmen, die an eingeschränkte Agents routen
  • Elevated global deaktivieren (tools.elevated.enabled: false), wenn du nur gesandboxte Ausführung willst
  • Elevated pro Agent deaktivieren (agents.list[].tools.elevated.enabled: false) für sensible Profile

Migration von einem einzelnen Agent

Vorher (einzelner Agent):

{
  "agents": {
    "defaults": {
      "workspace": "~/.openclaw/workspace",
      "sandbox": {
        "mode": "non-main"
      }
    }
  },
  "tools": {
    "sandbox": {
      "tools": {
        "allow": ["read", "write", "apply_patch", "exec"],
        "deny": []
      }
    }
  }
}

Nachher (Multi-Agent mit verschiedenen Profilen):

{
  "agents": {
    "list": [
      {
        "id": "main",
        "default": true,
        "workspace": "~/.openclaw/workspace",
        "sandbox": { "mode": "off" }
      }
    ]
  }
}

Legacy agent.*-Konfigurationen werden von openclaw doctor migriert; bevorzuge agents.defaults + agents.list in Zukunft.


Beispiele für Tool-Einschränkungen

Read-only Agent

{
  "tools": {
    "allow": ["read"],
    "deny": ["exec", "write", "edit", "apply_patch", "process"]
  }
}

Agent mit sicherer Ausführung (keine Dateiänderungen)

{
  "tools": {
    "allow": ["read", "exec", "process"],
    "deny": ["write", "edit", "apply_patch", "browser", "gateway"]
  }
}

Kommunikations-only Agent

{
  "tools": {
    "sessions": { "visibility": "tree" },
    "allow": ["sessions_list", "sessions_send", "sessions_history", "session_status"],
    "deny": ["exec", "write", "edit", "apply_patch", "read", "browser"]
  }
}

Häufige Falle: “non-main”

agents.defaults.sandbox.mode: "non-main" basiert auf session.mainKey (Standard "main"), nicht auf der Agent-ID. Gruppen-/Kanal-Sessions bekommen immer eigene Keys, werden also als nicht-main behandelt und gesandboxt. Wenn du willst, dass ein Agent nie gesandboxt wird, setze agents.list[].sandbox.mode: "off".


Testen

Nach der Konfiguration von Multi-Agent-Sandbox und Tools:

  1. Agent-Auflösung prüfen:

    openclaw agents list --bindings
  2. Sandbox-Container überprüfen:

    docker ps --filter "name=openclaw-sbx-"
  3. Tool-Einschränkungen testen:

    • Sende eine Nachricht, die eingeschränkte Tools erfordert
    • Überprüfe, dass der Agent gesperrte Tools nicht verwenden kann
  4. Logs überwachen:

    tail -f "${OPENCLAW_STATE_DIR:-$HOME/.openclaw}/logs/gateway.log" | grep -E "routing|sandbox|tools"

Fehlerbehebung

Agent trotz mode: "all" nicht gesandboxt

  • Prüfe, ob ein globales agents.defaults.sandbox.mode es überschreibt
  • Agent-spezifische Konfiguration hat Vorrang, also setze agents.list[].sandbox.mode: "all"

Tools trotz Deny-Liste weiterhin verfügbar

  • Prüfe die Tool-Filterreihenfolge: global → Agent → Sandbox → Subagent
  • Jede Ebene kann nur weiter einschränken, nicht zurückgeben
  • Überprüfe mit Logs: [tools] filtering tools for agent:${agentId}

Container nicht pro Agent isoliert

  • Setze scope: "agent" in der agent-spezifischen Sandbox-Konfiguration
  • Standard ist "session", was einen Container pro Session erstellt

Siehe auch