OpenClaw Subagents: Context Isolation, Workspaces, and Security Lockdown
A deep dive into how OpenClaw handles subagents — how they get their own context windows, workspace identity files, and how to lock them down with sandboxing, tool restrictions, and network hardening.
OpenClaw has become one of the most popular open-source AI agent frameworks, with over 180,000 developers running it on their own hardware. One of its most powerful features is the multi-agent system — the ability to spin up subagents that work independently, each with their own personality, tools, and security boundaries.
But how does it actually work under the hood? How isolated are these subagents really? And how do you lock one down so it can’t do anything you didn’t explicitly authorize?
How Subagents Run
When OpenClaw spawns a subagent via sessions_spawn, it creates an entirely new session with its own unique key in the format agent:<agentId>:subagent:<uuid>. The critical thing to understand: each subagent gets its own context window and token usage. It’s a separate LLM conversation, not a branch of the parent’s context.
There are two flavors of subagents:
| Type | Context | Persistence | Use Case |
|---|---|---|---|
| Ad-hoc subagents | Minimal — only AGENTS.md + TOOLS.md injected |
Disposable, auto-archived after 60 min | Quick background tasks spawned mid-conversation |
| Configured agents | Full workspace files (SOUL.md, IDENTITY.md, etc.) |
Persistent memory, transcripts, credentials | Dedicated agents with their own personality and tools |
Ad-hoc subagents are lightweight and cheap. Configured agents are full-blown personas with their own home directory.
Communication flows through an announce mechanism — when a subagent finishes, it posts results back to the requester’s chat channel. You can also send messages to a running subagent via /subagents send <id> <message> with a 30-second timeout.
Tuning Subagent Behavior
Out of the box, subagents work with no configuration. But you have plenty of knobs:
| Setting | What It Does |
|---|---|
agents.defaults.subagents.model |
Override the LLM model (otherwise inherits from parent) |
maxSpawnDepth: 2 |
Allow subagents to spawn their own subagents |
maxConcurrent (default: 8) |
How many subagents can run simultaneously |
maxChildrenPerAgent (default: 5) |
Per-agent spawn limit |
runTimeoutSeconds |
Kill long-running subagents |
cleanup: delete \| keep |
Retention policy for finished sessions |
Every Agent Gets a Workspace
This is where it gets interesting. Each configured agent in OpenClaw gets its own workspace directory — a dedicated home that shapes its entire personality and behavior. The structure looks like this:
1
2
3
4
5
6
7
8
9
10
11
~/.openclaw/agents/<agentId>/workspace/
├── IDENTITY.md # Agent name, emoji, visual branding
├── SOUL.md # Persona, tone, ethical boundaries
├── USER.md # Who the user is, how to address them
├── AGENTS.md # Operating instructions, memory rules
├── TOOLS.md # Tool usage guidance (not enforcement)
├── HEARTBEAT.md # Periodic run checklist (optional)
├── BOOT.md # Startup sequence on gateway restart (optional)
├── MEMORY.md # Curated long-term memory
├── memory/ # Daily memory logs (YYYY-MM-DD.md)
└── skills/ # Skill bundles
All of these files get injected into the agent’s system prompt at runtime. So when you give an agent its own SOUL.md, you’re literally shaping how it thinks, speaks, and behaves — independently from every other agent.
What Each File Does
- IDENTITY.md — the agent’s name, vibe, and emoji. Created during bootstrap, updated as the agent evolves
- SOUL.md — core personality, tone, behavioral guardrails. Loaded every session
- USER.md — who the user is, communication preferences. Loaded every session
- AGENTS.md — operating rules, priorities, how to use memory
- TOOLS.md — notes about available tools. Guidance only — doesn’t control actual tool access
- HEARTBEAT.md — lightweight checklist for scheduled/periodic runs
- BOOT.md — initialization logic that runs on gateway restart
- MEMORY.md — long-term curated memory (private sessions only)
Full Isolation
Each agent also gets isolated infrastructure:
- Own session transcripts:
~/.openclaw/agents/<id>/sessions/*.jsonl - Own memory index:
~/.openclaw/agents/<id>/memory.sqlite - Own auth credentials:
~/.openclaw/agents/<id>/agent/auth-profiles.json
Sessions for different agents never collide, even when talking to the same person.
Multi-Agent Configuration
You define agents in openclaw.json under agents.list[], each pointing to its own workspace:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
{
agents: {
list: [
{
id: "main",
default: true,
workspace: "~/.openclaw/workspace"
},
{
id: "researcher",
workspace: "~/.openclaw/agents/researcher/workspace",
model: { primary: "anthropic/claude-sonnet-4-5" }
},
{
id: "coder",
workspace: "~/.openclaw/agents/coder/workspace",
model: { primary: "anthropic/claude-opus-4" },
tools: { profile: "coding" }
}
]
}
}
Identity values resolve through a fallback cascade — most specific wins:
- Per-agent config in
agents.list[](highest priority) - Workspace files (
IDENTITY.md,SOUL.md, etc.) agents.defaults(shared baseline)- Global config (lowest priority)
You can set a baseline personality for all agents and let individual ones override just the pieces they need.
Security Lockdown
Here’s the part that matters most. OpenClaw’s workspace isolation is a convention, not a security boundary by default. The workspace is “the default cwd, not a hard sandbox” — relative paths resolve within it, but absolute paths can reach anywhere on your filesystem. You need to explicitly enable sandboxing.
Sandbox Mode and Scope
1
2
3
4
5
6
7
{
sandbox: {
mode: "all",
scope: "session",
workspaceAccess: "none"
}
}
Three levels for sandbox.scope:
| Scope | Behavior |
|---|---|
"session" |
Each session gets its own isolated sandbox (strictest) |
"agent" |
One sandbox per agent, shared across sessions |
"shared" |
Single container shared by multiple agents (least secure) |
And workspaceAccess:
| Value | Behavior |
|---|---|
"none" |
Workspace completely off-limits (default when sandboxed) |
"ro" |
Read-only mount |
"rw" |
Full read/write access |
Tool Restrictions
Tool filtering is hierarchical and one-directional — once denied at any level, lower levels cannot re-grant. The evaluation order:
- Tool profiles (coding, messaging, etc.)
- Global
tools.allow/tools.deny - Agent-specific
agents.list[].tools - Sandbox policies
- Subagent restrictions
Use the built-in tool groups as shortcuts:
| Group | Covers |
|---|---|
group:runtime |
exec, bash, process |
group:fs |
read, write, edit, apply_patch |
group:ui |
browser, canvas |
group:automation |
cron, gateway |
A maximally restricted agent:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
tools: {
deny: [
"group:runtime",
"group:fs",
"group:ui",
"group:automation",
"web_search",
"web_fetch",
"sessions_spawn"
],
allow: ["whatsapp", "telegram"]
}
}
This agent can send and receive messages. Nothing else.
Network and Gateway Hardening
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
gateway: {
mode: "local",
bind: "loopback",
port: 18789,
auth: {
mode: "token",
token: "${OPENCLAW_GATEWAY_TOKEN}"
},
trustedProxies: ["127.0.0.1"]
},
discovery: {
mdns: { mode: "off" }
}
}
Never expose the gateway to 0.0.0.0. For remote access, use Tailscale Serve rather than direct LAN exposure.
DM Access Control
Four modes from most to least restrictive:
"disabled"— no inbound DMs at all"allowlist"— only pre-approved senders"pairing"— unknown senders get a time-limited code (default)"open"— anyone can talk (dangerous)
The tools.elevated Escape Hatch
This global setting runs exec on the host, bypassing the sandbox entirely. The docs are blunt: keep it tight, never enable for untrusted agents. If you don’t need it, don’t configure it.
Prompt Injection Defense
Even with perfect sandboxing, untrusted content is a risk. The recommended pattern: use a read-only summary agent to sanitize untrusted input before passing it to tool-enabled agents. Also:
- Disable
web_search,web_fetch, andbrowseron agents handling untrusted input - Use the strongest available model — smaller models are more susceptible to instruction hijacking
- Set URL allowlists:
gateway.http.endpoints.responses.files.urlAllowlist
This is not theoretical. CrowdStrike has documented indirect prompt injection attacks targeting OpenClaw in the wild, including attempts to drain crypto wallets embedded in public posts.
Complete Hardened Agent Example
Putting it all together — a maximally locked-down agent that can only do messaging:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
{
gateway: {
mode: "local",
bind: "loopback",
port: 18789,
auth: { mode: "token", token: "${OPENCLAW_GATEWAY_TOKEN}" },
trustedProxies: ["127.0.0.1"]
},
discovery: { mdns: { mode: "off" } },
logging: { redactSensitive: "tools" },
agents: {
defaults: {
subagents: {
maxConcurrent: 2,
maxSpawnDepth: 1,
runTimeoutSeconds: 60,
cleanup: "delete"
}
},
list: [{
id: "locked-bot",
workspace: "~/.openclaw/agents/locked-bot/workspace",
model: { primary: "anthropic/claude-opus-4" },
sandbox: {
mode: "all",
scope: "session",
workspaceAccess: "none"
},
tools: {
deny: [
"group:runtime", "group:fs", "group:ui",
"group:automation", "web_search", "web_fetch",
"sessions_spawn"
],
allow: ["whatsapp", "telegram"]
}
}]
},
channels: {
whatsapp: {
dmPolicy: "allowlist",
groups: { "*": { requireMention: true } }
}
}
}
Auditing Your Setup
Run the built-in security checker regularly:
1
2
openclaw security audit --deep
openclaw security audit --fix
And harden file permissions:
1
2
3
4
chmod 700 ~/.openclaw
chmod 600 ~/.openclaw/openclaw.json
chmod 600 ~/.openclaw/credentials/*.json
chmod 600 ~/.openclaw/agents/*/agent/auth-profiles.json
Key Takeaways
- Each subagent gets its own context window — separate LLM conversation, separate token usage, not a branch of the parent
- Ad-hoc subagents are lightweight (minimal context), while configured agents get the full workspace with SOUL.md, IDENTITY.md, USER.md, and persistent memory
- Workspace isolation is a convention by default — you must explicitly enable
sandbox.modeto get real security boundaries - Tool restrictions are hierarchical and one-way — denied tools can never be re-granted at lower levels
- Use
scope: "session"andworkspaceAccess: "none"for maximum isolation - Prompt injection is a real, documented threat — use read-only summary agents to sanitize untrusted content before it reaches tool-enabled agents
- Run
openclaw security audit --deepregularly to catch configuration drift
Resources
- Sub-Agents - OpenClaw Docs
- Agent Workspace - OpenClaw Docs
- Security - OpenClaw Docs
- CrowdStrike: What Security Teams Need to Know About OpenClaw
- VentureBeat: OpenClaw Agentic AI Security Risk
- Multi-Agent Sandbox & Tools Configuration
- Subagent Management - DeepWiki
- Multi-Agent Configuration - DeepWiki
Published: February 2026