fix(agents/subagents): read SPAWN_ALLOWLIST env var as allowlist fallback (#79490)#80709
fix(agents/subagents): read SPAWN_ALLOWLIST env var as allowlist fallback (#79490)#80709MilosM348 wants to merge 1 commit into
Conversation
…back Container deployments (Docker / Coolify) that configure agents purely through env vars previously got 'allowed: none' from sessions_spawn because subagents.allowAgents was only read from per-agent config or agents.defaults. Adds resolveSpawnAllowlistFromEnv() that parses a comma-separated SPAWN_ALLOWLIST (with '*' wildcard support) and wires it into the spawn target-policy, ACP spawn, and agents_list resolution paths as a final fallback. Per-agent config and agents.defaults still take precedence. Fixes openclaw#79490 Co-authored-by: Cursor <[email protected]>
|
Thanks for the context here. I swept through the related work, and this is now duplicate or superseded. Close as duplicate/superseded: the same So I’m closing this here and keeping the remaining discussion on the canonical linked item. Review detailsBest possible solution: Review and land one canonical env allowlist implementation with docs, tests, and real Docker proof, instead of keeping several overlapping PR branches open. Do we have a high-confidence way to reproduce the issue? Yes. Source inspection shows current main has no Is this the best way to solve the issue? No for this PR as the merge path. The fallback-only direction is plausible, but #79538 already carries the same central fix with docs and broader tests, while this PR lacks real after-fix proof. Security review: Security review cleared: No concrete supply-chain issue was found; the diff touches spawn authorization but preserves explicit config precedence, with the remaining policy review now owned by the canonical PR. What I checked:
Likely related people:
Codex review notes: model gpt-5.5, reasoning high; reviewed against 2a6dfbd0342a. |
Real Behavior Proof
Issue: #79490 —
subagents.allowAgentsis the only documented way to allowsessions_spawnin non-default agents, but Docker / Coolify deployments configure agents purely through env vars (AGENTS=[…], no per-agent JSON). With nosubagents.allowAgentsinagents.defaultsand no per-agent override,resolveSubagentTargetPolicyfalls through toallowed: none, and everysessions_spawnreturnsnot in allowlisteven though the operator clearly intended to opt in.Reproduction (current
main, before this PR):agents.defaults.subagents.allowAgents.AGENTS=["primary","reviewer"]and (try to) opt in viaSPAWN_ALLOWLIST=*.primarycallsessions_spawn { agent: "reviewer" }.subagent-target-policy.tsresolves:Both lookups are
undefined, soeffectiveAllowAgentscollapses to[]and the call rejects withtarget 'reviewer' not in allowlist (allowed: none)— even though the operator setSPAWN_ALLOWLIST=*on the host.Fix: add
resolveSpawnAllowlistFromEnv(env)(insubagent-target-policy.ts) that parses a comma-separatedSPAWN_ALLOWLIST(with*for wildcard, whitespace-trimmed, empty entries dropped, returnsundefinedwhen unset/blank), and use it as a final fallback after the per-agent andagents.defaultslookups in:src/agents/subagent-target-policy.ts— exports the helper + env constant.src/agents/acp-spawn.ts— wires it into the ACPsessions_spawnpath.src/agents/subagent-spawn.ts— wires it into the generic spawn path.src/agents/tools/agents-list-tool.ts— wires it intoagents_listso the listing matches whatsessions_spawnwill actually accept.Per-agent
subagents.allowAgentsandagents.defaults.subagents.allowAgentsstill take precedence; the env fallback only fires when neither is set.Tests (
src/agents/subagent-target-policy.test.ts):resolveSpawnAllowlistFromEnvreturnsundefinedfor unset / blank / comma-only strings.*.resolveSubagentTargetPolicyaccepts an unknown target and rejects withnot in allowlistwhen allowlist is provided only viaSPAWN_ALLOWLISTenv.Local:
npx vitest run src/agents/subagent-target-policy.test.ts src/agents/subagent-spawn.test.ts src/agents/openclaw-tools.subagents.sessions-spawn.allowlist.test.ts src/agents/openclaw-tools.subagents.sessions-spawn.lifecycle.test.ts→7 files passed (7), 72 tests passed (72).Backwards compatibility: purely additive. The env var is read only when
subagents.allowAgentsis unset at both the per-agent andagents.defaultslevel, so existing JSON configs are untouched.Out of scope: documenting
SPAWN_ALLOWLISTin the deployment docs — happy to follow up in a docs-only PR if maintainers prefer that path.Fixes #79490.