#17921: feat: add spawnableBy bidirectional sub-agent spawn authorization
agents
stale
size: M
Cluster:
Model Management Enhancements
## Summary
Adds a `subagents.spawnableBy` config key on the target agent, enabling bidirectional spawn authorization. Currently only the spawning agent controls who it can target (`allowAgents`). This adds the inverse — the target agent can restrict who is allowed to spawn it.
## Config
```json5
{
agents: {
list: [
{
id: "worker-coding",
subagents: {
spawnableBy: ["orchestrator"] // only orchestrator can spawn me
}
}
]
}
}
```
## Behavior
- `spawnableBy` **not set** → any agent can spawn (backwards compatible)
- `spawnableBy: ["agent-a"]` → only `agent-a` can spawn this agent
- `spawnableBy: ["*"]` → explicitly allow any spawner
- Both `allowAgents` (sender) and `spawnableBy` (target) must pass for cross-agent spawns
## Changes
- `src/config/types.agents.ts` — Added `spawnableBy?: string[]` to subagents type
- `src/config/zod-schema.agent-runtime.ts` — Added zod validation
- `src/agents/tools/sessions-spawn-tool.ts` — Added spawnableBy check after existing allowAgents check
- `src/agents/openclaw-tools.subagents.sessions-spawn.spawnable-by.e2e.test.ts` — E2E tests mirroring allowAgents test patterns
## Tests
6 e2e tests covering:
- Allows any spawner when spawnableBy not set (backwards compat)
- Forbids when spawnableBy excludes requester
- Allows when spawnableBy includes requester
- Allows any with wildcard `["*"]`
- Normalizes agent ids (case-insensitive)
- Skips check for same-agent spawns
## Error
When rejected: `Target agent "X" does not allow being spawned by "Y"`
<!-- greptile_comment -->
<h3>Greptile Summary</h3>
Adds a `subagents.spawnableBy` config key to enable bidirectional spawn authorization. Previously, only the spawning agent controlled targeting via `allowAgents`; now the target agent can also restrict who can spawn it via `spawnableBy`. The implementation is clean and mirrors the existing `allowAgents` patterns across types, schema validation, runtime checks, and tests.
- Adds `spawnableBy?: string[]` to the `AgentConfig` type and Zod schema, matching the `allowAgents` pattern
- Runtime check in `sessions-spawn-tool.ts` runs after the `allowAgents` check, correctly handling wildcards (`["*"]`), case-insensitive matching, same-agent bypass, and backwards compatibility (no `spawnableBy` = allow all)
- 6 E2E tests cover all documented behaviors using the shared test harness
- Minor style note: `resolveAgentConfig(cfg, targetAgentId)` is called twice in `sessions-spawn-tool.ts` (once in the new `spawnableBy` block, once in the pre-existing model resolution block) and could be consolidated
<h3>Confidence Score: 4/5</h3>
- This PR is safe to merge — the authorization logic is correct, backwards compatible, and well-tested.
- The changes are focused and well-structured: type, schema, runtime check, and tests all align. The new spawnableBy check correctly handles all edge cases (wildcard, missing config, same-agent, case normalization). The only minor concern is a redundant resolveAgentConfig call that has no functional impact.
- No files require special attention. The minor redundancy in `src/agents/tools/sessions-spawn-tool.ts` is a style concern, not a correctness issue.
<sub>Last reviewed commit: 0c8a3f1</sub>
<!-- greptile_other_comments_section -->
<sub>(2/5) Greptile learns from your feedback when you react with thumbs up/down!</sub>
<!-- /greptile_comment -->
Most Similar PRs
#10197: fix: add missing allowAgents to agent defaults subagents schema
by Yida-Dev · 2026-02-06
79.3%
#10748: feat: Add sessions.spawn gateway method for direct subagent spawning
by fox-openclaw · 2026-02-06
78.6%
#16247: feat(agents): declarative agent definitions for sessions_spawn
by zerone0x · 2026-02-14
77.7%
#21556: fix(agents): graceful fallback when spawned model is not in allowlist
by irchelper · 2026-02-20
77.4%
#19833: feat: contextScripts pre-spawn hook for sub-agent sessions (rebased...
by geilt · 2026-02-18
77.4%
#13303: feat(subagents): replace silent boolean with announce enum ('user'|...
by ivalsaraj · 2026-02-10
77.1%
#13331: feat(sessions_spawn): add sessionKey param to reuse sub-agent sessions
by Be1Human · 2026-02-10
76.7%
#23506: feat(spawn): per-spawn tool permissions for sessions_spawn
by dissaozw · 2026-02-22
75.9%
#20072: feat(sessions_spawn): add sessionKey param to reuse sub-agent sessions
by Be1Human · 2026-02-18
75.8%
#20712: fix(subagents): prioritize agent runtime default model over global ...
by sourcesavant · 2026-02-19
73.6%