Files
Peter Steinberger 7f7448e96d feat(gateway): identity-conditional forced sandboxing for operator roles (#129926)
One shared agent could not give different people different execution
isolation: sandbox selection saw only the agent's mode and the session key,
never who created the session. Teams that share an agent had to choose
between sandboxing everyone or no one.

Add a closed, optional role axis sandbox?: "inherit" | "required"
(default "inherit", so existing deployments are unchanged). The Gateway
resolves it from the authenticated session creator and stamps it write-once
onto genuinely new session entries; the agents layer reads that immutable
fact and forces a sandbox even when the agent config says mode: "off".

Anchoring on the creator keeps a session's isolation stable for its lifetime:
a maintainer replying inside a guest session cannot un-sandbox it, and a
caller whose role requires a sandbox is refused inside an unstamped session
rather than silently inheriting host execution. Reset, rewind, rollover and
fast-path all carry the requirement forward so a session cannot be reset out
of its sandbox.

Because exec injects the agent's managed GitHub identity only for gateway-host
execution and blanks GH_TOKEN/GITHUB_TOKEN otherwise, a forced-sandbox session
also loses access to the shared agent's credentials — the property that makes
one shared agent safe for untrusted guests.

Session entries are JSON; no SQLite schema, schema-version, or protocol change.
Docs also correct the sandbox backend list, which omitted the first-class
podman backend.
2026-08-26 00:18:50 -07:00

129 lines
5.9 KiB
Markdown

---
summary: "Elevated exec mode: run commands outside the sandbox from a sandboxed agent"
read_when:
- Adjusting elevated mode defaults, allowlists, or slash command behavior
- Understanding how sandboxed agents can access the host
title: "Elevated mode"
---
When an agent runs inside a sandbox, its `exec` commands are confined to the sandbox environment. **Elevated mode** lets the agent break out of ordinary agent-configured sandboxing and run commands outside the sandbox instead, with configurable approval gates. Sessions whose creator role requires sandboxing cannot use elevated mode to escape.
<Info>
Elevated mode only changes behavior when the agent is **sandboxed**. For unsandboxed agents, exec already runs on the host.
</Info>
## Directives
Control elevated mode per-session with slash commands:
| Directive | What it does |
| ---------------- | ------------------------------------------------------------------------------------------------------------------------------- |
| `/elevated on` | Run outside the sandbox on the configured host path, keep approvals |
| `/elevated ask` | Same as `on` (alias) |
| `/elevated full` | Run outside the sandbox on the configured host path and skip approvals when the mode/host approval policy is already permissive |
| `/elevated off` | Return to sandbox-confined execution |
Also available as `/elev on|off|ask|full`.
Send `/elevated` with no argument to see the current level.
## How it works
<Steps>
<Step title="Check availability">
Elevated must be enabled in config and the sender must be on the allowlist:
```json5
{
tools: {
elevated: {
enabled: true,
allowFrom: {
discord: ["user-id-123"],
whatsapp: ["+15555550123"],
},
},
},
}
```
</Step>
<Step title="Set the level">
Send a directive-only message to set the session default:
```
/elevated full
```
Or use it inline (applies to that message only):
```
/elevated on run the deployment script
```
</Step>
<Step title="Commands run outside the sandbox">
With elevated active, `exec` calls leave the sandbox. The effective host is
`gateway` by default, or `node` when the configured/session exec target is
`node`. In `full` mode, exec approvals are skipped when the resolved exec
mode/host approval policy is already fully permissive (security `full`,
ask `off`); otherwise the normal approval policy still applies. In
`on`/`ask` mode, configured approval rules always apply.
</Step>
</Steps>
## Resolution order
1. **Inline directive** on the message (applies only to that message)
2. **Session override** (set by sending a directive-only message)
3. **Global default** (`agents.defaults.elevatedDefault` in config)
## Availability and allowlists
- **Global gate**: `tools.elevated.enabled` (must be `true`)
- **Sender allowlist**: `tools.elevated.allowFrom` with per-channel lists
- **Per-agent gate**: `agents.entries.*.tools.elevated.enabled` (can only further restrict; both the global and per-agent gate must be `true`)
- **Per-agent allowlist**: `agents.entries.*.tools.elevated.allowFrom` (sender must match both global + per-agent)
- **Channel-provided fallback allowlist**: channel plugins can optionally supply a fallback allowlist through an SDK adapter hook, used when `tools.elevated.allowFrom.<provider>` is not configured. No bundled channel currently implements this hook, so in practice every provider needs an explicit `tools.elevated.allowFrom.<provider>` entry today.
- **All gates must pass**; otherwise elevated is treated as unavailable
Allowlist entry formats:
| Prefix | Matches |
| ----------------------- | ------------------------------- |
| (none) | Sender ID, E.164, or From field |
| `name:` | Sender display name |
| `username:` | Sender username |
| `tag:` | Sender tag |
| `id:`, `from:`, `e164:` | Explicit identity targeting |
## What elevated does not control
- **Tool policy**: if `exec` is denied by tool policy, elevated cannot override it.
- **Required role sandboxing**: if the authenticated session creator's operator role required a sandbox, elevated mode cannot run commands on the Gateway or a node.
- **Host selection policy**: elevated does not turn `auto` into a free cross-host override. It uses the configured/session exec target rules, choosing `node` only when the target is already `node`.
- **Separate from `/exec`**: the `/exec` directive adjusts per-session exec defaults (host, security, ask, node) for authorized senders and does not require elevated mode.
<Note>
The bash chat command (`!` prefix; `/bash` alias) is a separate gate that requires `tools.elevated` to be enabled in addition to its own `tools.bash.enabled` flag. Disabling elevated locks `!` shell commands out as well.
</Note>
## Related
<CardGroup cols={2}>
<Card title="Exec tool" href="/tools/exec" icon="terminal">
Shell command execution from the agent.
</Card>
<Card title="Exec approvals" href="/tools/exec-approvals" icon="shield">
Approval and allowlist system for `exec`.
</Card>
<Card title="Sandboxing" href="/gateway/sandboxing" icon="box">
Gateway-level sandbox configuration.
</Card>
<Card title="Sandbox vs Tool Policy vs Elevated" href="/gateway/sandbox-vs-tool-policy-vs-elevated" icon="scale-balanced">
How the three gates compose during a tool call.
</Card>
</CardGroup>