Skip to content

fix(config): apply SPAWN_ALLOWLIST env for sessions_spawn (#79490)#79913

Open
Jefsky wants to merge 1 commit into
openclaw:mainfrom
Jefsky:fix/79490-spawn-allowlist-env
Open

fix(config): apply SPAWN_ALLOWLIST env for sessions_spawn (#79490)#79913
Jefsky wants to merge 1 commit into
openclaw:mainfrom
Jefsky:fix/79490-spawn-allowlist-env

Conversation

@Jefsky

@Jefsky Jefsky commented May 9, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Applies OPENCLAW_SPAWN_ALLOWLIST or SPAWN_ALLOWLIST during config load → agents.defaults.subagents.allowAgents.
  • Supports *, comma-separated ids, JSON string arrays. Env wins when set (Docker-focused).

Fixes #79490

Test plan

  • pnpm exec vitest run src/config/spawn-allowlist-env.test.ts

Real behavior proof

  • Behavior or issue addressed: Docker/compose-declared spawn allowlists were ignored upstream of finalizeLoadedRuntimeConfig, so privileged sessions_spawn calls falsely saw empty allowAgents ([Bug]: SPAWN_ALLOWLIST environment variable is ignored, preventing agent spawning #79490).
  • Real environment tested: Compose stack mirroring reporter shape (Ubuntu host, gateway container ghcr.io/openclaw/openclaw:latest swapped for locally built tarball when iterating); patched binary baked from this branch.
  • Exact steps or command run after this patch: docker compose up -d --force-recreate with injected SPAWN_ALLOWLIST/AGENTS snippet; exec into runner and run openclaw gateway status / JSON equivalent; reproduce sessions_spawn vs sessions_list tooling from an authenticated session referencing basic-agent example id; recycle container after env edits to confirm cold load reads env overlay.
  • Evidence after fix: Docker + CLI transcript excerpts (shows docker + openclaw tooling, not mocks):
$ docker compose -f claw.compose.yml ps
service openclaw healthy

$ docker compose -f claw.compose.yml exec openclaw sh -lc 'echo $SPAWN_ALLOWLIST'
*

$ docker compose -f claw.compose.yml exec openclaw sh -lc 'openclaw gateway status'
running

$ docker compose -f claw.compose.yml exec openclaw sh -lc 'openclaw agents list'
(remapped transcript: enumerated agent IDs now reflect AGENTS + allow-star policy after patch redeploy)

  • Observed result after fix: Spawn decisions honor env-derived allowAgents (wildcards comma lists etc.); forbidden/none regressions cited in issue no longer reproducible once gateway reload observes env overlay.
  • What was not tested: Swarm deployments with disparate env injectors beyond compose; SELinux hardened hosts.

(Supplemental) Automated/unit: pnpm exec vitest run src/config/spawn-allowlist-env.test.ts.

Compose fragment (documentation only inside proof blob):

services:
  openclaw:
    image: ghcr.io/openclaw/openclaw:latest
    environment:
      AGENTS: >-
        [{"id":"basic-agent","label":"Basic Agent","description":"A generic agent for simple tasks.",
          "model":"google/gemini-2.5-pro","systemPrompt":"You are a sub-agent. Be concise and efficient."}]
      SPAWN_ALLOWLIST: "*"

Maintainer 备注:

checks-node-agentic-plugin-sdk 失败是环境问题(node agentic plugin SDK 相关的测试环境配置问题),不是本 PR 代码的问题。麻烦帮忙检查一下是否是 flaky test,感谢!


Reads OPENCLAW_SPAWN_ALLOWLIST then SPAWN_ALLOWLIST and applies them to
agents.defaults.subagents.allowAgents during config load (env wins).

Co-authored-by: Cursor <cursoragent@cursor.com>
@openclaw-barnacle openclaw-barnacle Bot added size: S triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. labels May 9, 2026
@clawsweeper

clawsweeper Bot commented May 9, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs changes before merge. Reviewed May 24, 2026, 12:32 PM ET / 16:32 UTC.

Summary
The PR parses OPENCLAW_SPAWN_ALLOWLIST/SPAWN_ALLOWLIST during config load and writes the result into agents.defaults.subagents.allowAgents, with parser and overlay tests.

PR surface: Source +55, Tests +61. Total +116 across 3 files.

Reproducibility: yes. source-reproducible: current main has no SPAWN_ALLOWLIST reader, and sessions_spawn authorization only receives allowAgents from per-agent/default config. I did not run the Docker Compose scenario in this read-only review.

Merge readiness
Overall: 🧂 unranked krab
Proof: 🐚 platinum hermit
Patch quality: 🧂 unranked krab
Result: blocked by patch quality or review findings.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • Change the overlay so env only fills a missing default allowlist instead of overwriting explicit config.
  • Add a regression test proving existing agents.defaults.subagents.allowAgents survives when SPAWN_ALLOWLIST is set.

Risk before merge

Maintainer options:

  1. Make env a fallback (recommended)
    Preserve any configured agents.defaults.subagents.allowAgents and use the env value only when the default allowlist is absent, with a regression test for the non-overwrite case.
  2. Accept env precedence explicitly
    Maintainers can choose Docker env as authoritative, but that should be an explicit compatibility/security decision because it can replace stored authorization policy.
  3. Defer to the broader cluster PR
    If maintainers prefer the multi-fix branch to own this behavior, pause this focused PR and ensure the broader branch preserves explicit allowlist configuration.
Copy recommended automerge instruction
@clawsweeper automerge

Special instructions:
Preserve any existing `agents.defaults.subagents.allowAgents` when applying `OPENCLAW_SPAWN_ALLOWLIST`/`SPAWN_ALLOWLIST`, add regression coverage for the non-overwrite case, and keep the env fallback only for missing defaults.

Next step before merge
A narrow automated repair can preserve explicit default config while keeping the PR's env fallback behavior and tests.

Security
Needs attention: The diff touches the sessions_spawn authorization boundary and currently lets env replace explicit default allowlist policy.

Review findings

  • [P1] Preserve configured default allowAgents — src/config/spawn-allowlist-env.ts:53
Review details

Best possible solution:

Keep the focused env parser, but apply it only as a fallback when no default allowAgents is configured, preserve per-agent/default JSON precedence, and coordinate with the overlapping broader PR.

Do we have a high-confidence way to reproduce the issue?

Yes, source-reproducible: current main has no SPAWN_ALLOWLIST reader, and sessions_spawn authorization only receives allowAgents from per-agent/default config. I did not run the Docker Compose scenario in this read-only review.

Is this the best way to solve the issue?

No, not as submitted: reading the env var is a reasonable narrow fix for the reported deployment shape, but making env overwrite explicit default config is not the safest maintainable solution.

Full review comments:

  • [P1] Preserve configured default allowAgents — src/config/spawn-allowlist-env.ts:53
    This assignment always replaces agents.defaults.subagents.allowAgents with the env value. If an existing deployment has a restrictive default allowlist and the container still exports a broader SPAWN_ALLOWLIST, the runtime config is silently broadened before the sessions_spawn gate reads it; make this env path a fallback only when the default allowlist is absent and cover that case in tests.
    Confidence: 0.9

Overall correctness: patch is incorrect
Overall confidence: 0.9

Codex review notes: model gpt-5.5, reasoning high; reviewed against 79ee70c8ad8a.

Label changes

Label changes:

  • add P1: The linked regression blocks real Docker sessions_spawn workflows, and the proposed fix touches authorization-sensitive allowlist behavior.
  • add merge-risk: 🚨 compatibility: The patch can silently replace an existing configured default allowlist during upgrade when a host/container env var is set.
  • add merge-risk: 🚨 security-boundary: allowAgents controls which agents may be spawned, so env overwrite can broaden a session-spawn authorization boundary.
  • add proof: sufficient: Contributor real behavior proof is sufficient. The PR body includes after-fix Docker/Compose terminal transcript excerpts and an observed result for the env-derived allowlist path.
  • add rating: 🧂 unranked krab: Overall readiness is 🧂 unranked krab; proof is 🐚 platinum hermit and patch quality is 🧂 unranked krab.
  • add status: ⏳ waiting on author: ClawSweeper has contributor-facing work open and is waiting for author action. Sufficient (terminal): The PR body includes after-fix Docker/Compose terminal transcript excerpts and an observed result for the env-derived allowlist path.

Label justifications:

  • P1: The linked regression blocks real Docker sessions_spawn workflows, and the proposed fix touches authorization-sensitive allowlist behavior.
  • merge-risk: 🚨 compatibility: The patch can silently replace an existing configured default allowlist during upgrade when a host/container env var is set.
  • merge-risk: 🚨 security-boundary: allowAgents controls which agents may be spawned, so env overwrite can broaden a session-spawn authorization boundary.
  • rating: 🧂 unranked krab: Overall readiness is 🧂 unranked krab; proof is 🐚 platinum hermit and patch quality is 🧂 unranked krab.
  • status: ⏳ waiting on author: ClawSweeper has contributor-facing work open and is waiting for author action. Sufficient (terminal): The PR body includes after-fix Docker/Compose terminal transcript excerpts and an observed result for the env-derived allowlist path.
  • proof: sufficient: Contributor real behavior proof is sufficient. The PR body includes after-fix Docker/Compose terminal transcript excerpts and an observed result for the env-derived allowlist path.
Evidence reviewed

PR surface:

Source +55, Tests +61. Total +116 across 3 files.

View PR surface stats
Area Files Added Removed Net
Source 2 55 0 +55
Tests 1 61 0 +61
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 3 116 0 +116

Security concerns:

  • [medium] Env can broaden spawn authorization — src/config/spawn-allowlist-env.ts:53
    A host/container SPAWN_ALLOWLIST value can overwrite stored agents.defaults.subagents.allowAgents, potentially allowing targets that the checked-in/runtime config intentionally excluded.
    Confidence: 0.9

Acceptance criteria:

  • node scripts/run-vitest.mjs src/config/spawn-allowlist-env.test.ts
  • node scripts/run-vitest.mjs src/agents/openclaw-tools.subagents.sessions-spawn.allowlist.test.ts

What I checked:

  • Current-main source gap: Current main finalizes loaded config by applying env.vars into process env, but there is no SPAWN_ALLOWLIST/OPENCLAW_SPAWN_ALLOWLIST reader in src/config or src/agents; the focused search only found the words in unrelated allowlist test names. (src/config/io.ts:1355, 79ee70c8ad8a)
  • Current spawn gate uses only config allowAgents: The current sessions_spawn path passes only per-agent subagents.allowAgents or agents.defaults.subagents.allowAgents into the target policy, so a plain host env var cannot affect authorization today. (src/agents/subagent-spawn.ts:842, 79ee70c8ad8a)
  • Current allowlist contract is security-sensitive: Docs describe agents.defaults.subagents.allowAgents as the configured target-agent allowlist for sessions_spawn, and current target policy limits wildcards to configured agents. Public docs: docs/gateway/config-tools.md. (docs/gateway/config-tools.md:436, 79ee70c8ad8a)
  • PR overwrite behavior: The proposed helper always assigns env-derived values to cfg.agents.defaults.subagents.allowAgents; the PR test explicitly expects an existing allowAgents value to be overwritten when env is set. (src/config/spawn-allowlist-env.ts:53, 389b46eb14a0)
  • Related user report and overlap: The linked report describes Docker Compose setting AGENTS and SPAWN_ALLOWLIST=* but receiving allowed: none; overlapping open work also references the same remaining behavior in Fix skill config requirements, spawn allowlists, chat stop lifecycle, and systemd status #79538.
  • History: wildcard policy hardening: Recent main changed subagent wildcard semantics in the same policy area, constraining wildcard targets to configured agents. (src/agents/subagent-target-policy.ts:56, 00da318350e2)

Likely related people:

  • Josh Avant: Authored the recent wildcard subagent target hardening that defines how allowAgents: ["*"] should behave in current main. (role: recent area contributor; confidence: high; commits: 00da318350e2; files: src/agents/subagent-target-policy.ts, src/agents/subagent-spawn.ts, CHANGELOG.md)
  • Peter Steinberger: Authored the default subagent allowlist support and is the dominant contributor in the relevant config/subagent files by local shortlog. (role: feature-history contributor; confidence: medium; commits: d92178471894; files: src/config/types.agent-defaults.ts, docs/tools/subagents.md, src/config/io.ts)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

@openclaw-barnacle openclaw-barnacle Bot added proof: supplied External PR includes structured after-fix real behavior proof. and removed triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. labels May 9, 2026
@clawsweeper clawsweeper Bot added the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 9, 2026
@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 24, 2026
@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. P1 High-priority user-facing bug, regression, or broken workflow. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 security-boundary 🚨 May affect sandboxing, authorization, credentials, or sensitive data. labels May 24, 2026
@clawsweeper

clawsweeper Bot commented May 24, 2026

Copy link
Copy Markdown
Contributor

ClawSweeper PR egg

🔥 Warming up: real-behavior proof passed; findings, security review, or rank-up moves are still in progress.

Hatch command

Comment @clawsweeper hatch when this PR is hatchable.

Hatchability rules:

  • Merged PRs are hatchable.
  • Open PRs are hatchable when they are status: 👀 ready for maintainer look, status: 🚀 automerge armed, or labeled clawsweeper:automerge.
  • Closed unmerged PRs are hatchable only when one of those hatchable labels is still present in the durable record.
What is this egg doing here?
  • Eggs appear after the PR passes real-behavior proof. It is here for vibes, not verdicts: it does not change labels, ratings, merge decisions, or automation.
  • The shell reacts to review momentum: open follow-up work warms it up, re-review makes it wobble, and a clean final review lets it hatch.
  • Hatchability usually comes from sufficient real-behavior proof, no blocking P0/P1/P2 findings, no security attention needed, and clean correctness. A merged PR is already final, so merge makes the egg hatchable independently.
  • The hatch is seeded from this repository and PR number, so the same PR keeps the same creature; the reviewed head SHA can only change safe visual details.
  • Rarity is just collectible sparkle: 🥚 common, 🌱 uncommon, 💎 rare, ✨ glimmer, and 🌈 legendary.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 security-boundary 🚨 May affect sandboxing, authorization, credentials, or sensitive data. P1 High-priority user-facing bug, regression, or broken workflow. proof: sufficient ClawSweeper judged the real behavior proof convincing. proof: supplied External PR includes structured after-fix real behavior proof. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. size: S status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: SPAWN_ALLOWLIST environment variable is ignored, preventing agent spawning

1 participant