#Enabling elevated mode with "non-main" sandbox on discord

1 messages · Page 1 of 1 (latest)

wooden rose
#

How do I properly configure elevated mode for non-main sandboxed agents enabled by a DM user? Additionally, webchat says it requires allowFrom entry.

Openclaw version

~$ openclaw --version
OpenClaw 2026.5.7 (eeef486)

openclaw.json elevated block

"elevated": {
            "enabled": true,
            "allowFrom": {
              "discord": [
                "123456"
              ],
              "webchat": [
                      "123456"
              ]
            }
          }

supple cedarBOT
#

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

crystal yewBOT
#

KennyD — the main thing: that block is in the wrong place. Elevated config lives under tools.elevated, not top-level elevated.

Use something like:

{
  agents: {
    defaults: {
      sandbox: {
        mode: "non-main", // non-main sessions run sandboxed
        // backend/scope/workspaceAccess as desired
      },
      // optional: default elevated state for new sessions
      elevatedDefault: "off", // off | on | full
    },
  },
#

  tools: {
    elevated: {
      enabled: true,
      allowFrom: {
        // Discord user ID of the human allowed to use /elevated
        discord: ["123456"],

        // WebChat/Control UI currently has no stable sender identity in chat.send,
        // so a numeric id will not match. If you need /elevated from WebChat,
        // this is the entry that satisfies the gate:
        webchat: ["*"],
      },
    },
#
    // Important: elevated does not override tool policy. If sandbox policy denies exec,
    // /elevated cannot make exec available.
    sandbox: {
      tools: {
        allow: ["exec", "process"],
      },
    },
  },
}

A few gotchas:

  • discord: ["123456"] must be the Discord user ID, not a channel/thread/server ID.
  • /elevated on runs exec outside the sandbox but still uses approvals.
  • /elevated full skips exec approvals, so keep that tightly restricted.
  • webchat: ["*"] looks scary because it is a wildcard; only use it if your Gateway auth is locked down. WebChat is gated by Gateway auth/scopes, not a Discord-style sender ID.
wooden rose
#

Here is output from agent:main:main

{
  "docsUrl": "https://docs.openclaw.ai/sandbox",
  "agentId": "main",
  "sessionKey": "agent:main:main",
  "mainSessionKey": "agent:main:main",
  "sandbox": {
    "mode": "non-main",
    "scope": "agent",
    "workspaceAccess": "none",
    "workspaceRoot": "/home/<redacted>/.openclaw/sandboxes",
    "sessionIsSandboxed": false,
    "tools": {
      "allow": [
        "exec",
        "session_status"
      ],
      "deny": [
        "whatsapp"
      ],
      "sources": {
        "allow": {
          "source": "default",
          "key": "tools.sandbox.tools.allow"
        },
        "deny": {
          "source": "default",
          "key": "tools.sandbox.tools.deny"
        }
      }
    }
  },
  "elevated": {
    "enabled": true,
    "channel": "webchat",
    "allowedByConfig": false,
    "alwaysAllowedByConfig": false,
    "allowFrom": {
      "global": [],
      "agent": [
        "*"
      ]
    },
    "failures": [
      {
        "gate": "allowFrom",
        "key": "tools.elevated.allowFrom.webchat"
      }
    ]
  },
  "fixIt": [
    "agents.defaults.sandbox.mode=off",
    "agents.list[].sandbox.mode=off",
    "tools.sandbox.tools.allow",
    "tools.sandbox.tools.alsoAllow",
    "tools.sandbox.tools.deny",
    "agents.list[].tools.sandbox.tools.allow",
    "agents.list[].tools.sandbox.tools.alsoAllow",
    "agents.list[].tools.sandbox.tools.deny",
    "tools.elevated.enabled",
    "tools.elevated.allowFrom.webchat"
  ]
}

Explain the "allowedByConfig" and similar properties and help me continue to debug why elevated mode is not available. For now I'm working on agent:main:main. Also note the block in my first message just didn't have the full path but it was what you said it should be, and that I redacted some of the tools.allow and tools.deny in this included json to make it shorter.

crystal yewBOT
#

Good catch — and thanks for clarifying the config path. I was too quick there.

For this output, the key lines are:

"sessionKey": "agent:main:main",
"sandbox": {
  "mode": "non-main",
  "sessionIsSandboxed": false
},
"elevated": {
  "channel": "webchat",
  "allowedByConfig": false,
  "allowFrom": {
    "global": [],
    "agent": ["*"]
#
  },
  "failures": [
    { "gate": "allowFrom", "key": "tools.elevated.allowFrom.webchat" }
  ]
}

What the elevated fields mean:

  • enabled: true = both global tools.elevated.enabled and any per-agent agents.list[].tools.elevated.enabled allow elevated mode.
  • channel: "webchat" = OpenClaw is evaluating elevated permissions for a WebChat/Control UI-originated turn, not Discord.
  • allowFrom.global: [] = there is no effective tools.elevated.allowFrom.webchat entry.
  • allowFrom.agent: ["*"] = your per-agent allowlist has WebChat wildcard.
  • allowedByConfig: false = the structural gates do not pass. Specifically, global allowFrom is empty.
  • alwaysAllowedByConfig: false = not all relevant allowlists are wildcard "*".
  • failures tells you the exact blocking key: tools.elevated.allowFrom.webchat.
#

Important bit: per-agent elevated config can only further restrict. It cannot grant elevated if the global gate fails. So this:

agents: {
  list: [{
    id: "main",
    tools: { elevated: { allowFrom: { webchat: ["*"] } } }
  }]
}

still needs the global allowlist too:

tools: {
  elevated: {
#
    enabled: true,
    allowFrom: {
      webchat: ["*"],
      discord: ["270536261851152384"] // your Discord user id, if using /elevated from Discord
    }
  }
}

For agent:main:main specifically: sessionIsSandboxed: false, because mode: "non-main" only sandboxes sessions whose key is not the main key. Elevated mode only matters when the session is sandboxed; on agent:main:main, exec is already on-host, so /elevated is effectively not the thing that gives you host access.

To debug the actual non-main Discord thread/channel case, run explain against that session key, not agent:main:main. It’ll be something like:

openclaw sandbox explain --session 'agent:main:discord:channel:1502773297555832952' --json
#

or use the exact session key shown in /status / the UI. In that output you want:

"sessionIsSandboxed": true,
"elevated": {
  "channel": "discord",
  "allowedByConfig": true
}

If channel shows webchat, configure/check tools.elevated.allowFrom.webchat. If it shows discord, configure/check tools.elevated.allowFrom.discord. 🦞

Docs: https://docs.openclaw.ai/tools/elevated

wooden rose
#

I see, I was missing the global tools.elevated.allowFrom. So if I have global tools.elevated.allowFrom set to allow my user, and I have agents.default.tools.allowFrom set the same, but all other agents do not have agents.list[].tools.enabled, the elevated will not be enabled for those agents? Or do I have to explicitly set agents.list[].tools.enabled to false?

crystal yewBOT
#

Yep — you’ve got it, with one important correction:

There is no broad agents.defaults.tools.elevated.allowFrom gate for elevated mode in the current config shape. The gates are:

  1. Global:
tools: {
  elevated: {
    enabled: true,
    allowFrom: {
      discord: ["270536261851152384"],
      webchat: ["*"],
    },
  },
}
#
  1. Optional per-agent restriction:
agents: {
  list: [
    {
      id: "main",
      tools: {
        elevated: {
          enabled: true,
          allowFrom: { discord: ["270536261851152384"] },
        },
      },
    },
  ],
}
#

If an agent has no agents.list[].tools.elevated.enabled, it defaults to allowed as long as the global gate passes.

So: global tools.elevated.allowFrom by itself can make elevated available to that sender across agents. Per-agent config is only an additional restriction; it does not default other agents off.

If you want elevated available only on selected agents, explicitly disable it on the others:

agents: {
  list: [
    {
      id: "main",
      tools: {
        elevated: {
          enabled: true,
          allowFrom: { discord: ["270536261851152384"] },
        },
#
      },
    },
    {
      id: "public",
      tools: {
        elevated: { enabled: false },
      },
    },
  ],
}

Mental model:

  • tools.elevated.enabled !== false must pass globally.
  • tools.elevated.allowFrom.<channel> must match globally.
#
  • If the agent has tools.elevated.enabled: false, it blocks.
  • If the agent has tools.elevated.allowFrom, that must also match.
  • If the agent has no elevated block, it does not block.

So yes: explicitly set agents.list[].tools.elevated.enabled: false for agents where you don’t want elevated. 🦞