マルチエージェント サンドボックスとツール設定

概要

マルチエージェント構成では、各エージェントが独自の設定を持てます:

  • サンドボックス設定agents.list[].sandboxagents.defaults.sandboxをオーバーライド)
  • ツール制限tools.allow / tools.deny、およびagents.list[].tools

これにより、異なるセキュリティプロファイルで複数のエージェントを運用できます:

  • フルアクセスのパーソナルアシスタント
  • ツールを制限した家族/仕事用エージェント
  • サンドボックスで動作する公開エージェント

setupCommandsandbox.docker(グローバルまたはエージェント単位)の配下に置き、コンテナ作成時に一度実行されます。

認証はエージェント単位です。各エージェントは自身のagentDir認証ストアから読み取ります:

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

認証情報はエージェント間で共有されませんagentDirを複数エージェントで使い回さないでください。 認証情報を共有したい場合は、auth-profiles.jsonを対象エージェントのagentDirにコピーしてください。

サンドボックスのランタイム動作についてはサンドボックス化を参照。 「なぜブロックされるのか」のデバッグにはサンドボックス vs ツールポリシー vs Elevatedおよびopenclaw sandbox explainを参照してください。


設定例

例1: パーソナル+制限付きファミリーエージェント

{
  "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]"
        }
      }
    }
  ]
}

結果:

  • mainエージェント: ホスト上で動作、フルツールアクセス
  • familyエージェント: Docker内で動作(エージェントごとに1コンテナ)、readツールのみ

例2: 共有サンドボックスの仕事用エージェント

{
  "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"]
        }
      }
    ]
  }
}

例2b: グローバルcodingプロファイル+メッセージング専用エージェント

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

結果:

  • デフォルトのエージェントはcodingツールを取得
  • supportエージェントはメッセージング専用(+Slackツール)

例3: エージェントごとに異なるサンドボックスモード

{
  "agents": {
    "defaults": {
      "sandbox": {
        "mode": "non-main", // グローバルデフォルト
        "scope": "session"
      }
    },
    "list": [
      {
        "id": "main",
        "workspace": "~/.openclaw/workspace",
        "sandbox": {
          "mode": "off" // オーバーライド: mainは常にサンドボックス化しない
        }
      },
      {
        "id": "public",
        "workspace": "~/.openclaw/workspace-public",
        "sandbox": {
          "mode": "all", // オーバーライド: publicは常にサンドボックス化
          "scope": "agent"
        },
        "tools": {
          "allow": ["read"],
          "deny": ["exec", "write", "edit", "apply_patch"]
        }
      }
    ]
  }
}

設定の優先順位

グローバル(agents.defaults.*)とエージェント固有(agents.list[].*)の両方が存在する場合:

サンドボックス設定

エージェント固有の設定がグローバルをオーバーライド:

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.*

注意事項:

  • agents.list[].sandbox.{docker,browser,prune}.*は、そのエージェントのagents.defaults.sandbox.{docker,browser,prune}.*をオーバーライドします(サンドボックススコープが"shared"に解決される場合は無視)。

ツール制限

フィルタリング順序:

  1. ツールプロファイルtools.profileまたはagents.list[].tools.profile
  2. プロバイダーツールプロファイルtools.byProvider[provider].profileまたはagents.list[].tools.byProvider[provider].profile
  3. グローバルツールポリシーtools.allow / tools.deny
  4. プロバイダーツールポリシーtools.byProvider[provider].allow/deny
  5. エージェント固有のツールポリシーagents.list[].tools.allow/deny
  6. エージェントプロバイダーポリシーagents.list[].tools.byProvider[provider].allow/deny
  7. サンドボックスツールポリシーtools.sandbox.toolsまたはagents.list[].tools.sandbox.tools
  8. サブエージェントツールポリシーtools.subagents.tools、該当する場合)

各レベルはツールをさらに制限できますが、前のレベルで拒否されたツールを復活させることはできません。 agents.list[].tools.sandbox.toolsが設定されている場合、そのエージェントのtools.sandbox.toolsを置き換えます。 agents.list[].tools.profileが設定されている場合、そのエージェントのtools.profileをオーバーライドします。 プロバイダーツールキーはprovider(例: google-antigravity)またはprovider/model(例: openai/gpt-5.2)の形式を受け付けます。

ツールグループ(ショートハンド)

ツールポリシー(グローバル、エージェント、サンドボックス)は、複数の具体的なツールに展開されるgroup:*エントリに対応:

  • group:runtime: execbashprocess
  • group:fs: readwriteeditapply_patch
  • group:sessions: sessions_listsessions_historysessions_sendsessions_spawnsession_status
  • group:memory: memory_searchmemory_get
  • group:ui: browsercanvas
  • group:automation: crongateway
  • group:messaging: message
  • group:nodes: nodes
  • group:openclaw: OpenClaw組み込みツール全体(プロバイダープラグインは除外)

Elevatedモード

tools.elevatedはグローバルベースライン(送信者ベースの許可リスト)です。agents.list[].tools.elevatedは特定のエージェントのelevatedをさらに制限できます(両方が許可する必要あり)。

緩和パターン:

  • 信頼されないエージェントにはexecを拒否(agents.list[].tools.deny: ["exec"]
  • 制限付きエージェントにルーティングされる送信者の許可リスト登録を避ける
  • サンドボックス実行のみ必要な場合はelevatedをグローバルに無効化(tools.elevated.enabled: false
  • 機密プロファイルではエージェント単位でelevatedを無効化(agents.list[].tools.elevated.enabled: false

シングルエージェントからの移行

移行前(シングルエージェント):

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

移行後(異なるプロファイルのマルチエージェント):

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

レガシーのagent.*設定はopenclaw doctorで移行されます。今後はagents.defaults + agents.listの使用を推奨します。


ツール制限の例

読み取り専用エージェント

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

安全な実行エージェント(ファイル変更なし)

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

通信専用エージェント

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

よくある落とし穴: “non-main”

agents.defaults.sandbox.mode: "non-main"session.mainKey(デフォルト"main")に基づいており、エージェントIDではありません。グループ/チャンネルセッションは常に独自のキーを持つため、non-mainとして扱われ、サンドボックス化されます。エージェントを常にサンドボックス化しないようにするには、agents.list[].sandbox.mode: "off"を設定してください。


テスト

マルチエージェント サンドボックスとツールを設定した後:

  1. エージェント解決の確認:

    openclaw agents list --bindings
  2. サンドボックスコンテナの確認:

    docker ps --filter "name=openclaw-sbx-"
  3. ツール制限のテスト:

    • 制限されたツールが必要なメッセージを送信
    • エージェントが拒否されたツールを使用できないことを確認
  4. ログの監視:

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

トラブルシューティング

mode: "all"なのにサンドボックス化されない

  • グローバルのagents.defaults.sandbox.modeがオーバーライドしていないか確認
  • エージェント固有の設定が優先されるため、agents.list[].sandbox.mode: "all"を設定

denyリストがあるのにツールが利用可能

  • ツールフィルタリング順序を確認: グローバル → エージェント → サンドボックス → サブエージェント
  • 各レベルはさらなる制限のみ可能で、復活させることはできない
  • ログで確認: [tools] filtering tools for agent:${agentId}

エージェントごとにコンテナが分離されない

  • エージェント固有のサンドボックス設定でscope: "agent"を設定
  • デフォルトは"session"で、セッションごとに1コンテナを作成

関連ドキュメント