-
-
Notifications
You must be signed in to change notification settings - Fork 79.1k
sessions_spawn accepts unknown agentId with allowAgents:"*" (auto-provisions default-configured subagent, no registry validation) #84040
Copy link
Copy link
Closed
Labels
P1High-priority user-facing bug, regression, or broken workflow.High-priority user-facing bug, regression, or broken workflow.clawsweeper:fix-shape-clearClawSweeper found a clear likely implementation shape for this issue.ClawSweeper found a clear likely implementation shape for this issue.clawsweeper:needs-maintainer-reviewClawSweeper marked this issue as needing maintainer review before automation.ClawSweeper marked this issue as needing maintainer review before automation.clawsweeper:needs-product-decisionClawSweeper marked this issue as needing a product or behavior decision.ClawSweeper marked this issue as needing a product or behavior decision.clawsweeper:needs-security-reviewClawSweeper marked this issue as needing security-sensitive review.ClawSweeper marked this issue as needing security-sensitive review.clawsweeper:no-new-fix-prClawSweeper does not recommend queueing a new automated fix PR for this issue.ClawSweeper does not recommend queueing a new automated fix PR for this issue.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.ClawSweeper found a high-confidence source-level issue reproduction.impact:securitySecurity boundary, credential, authz, sandbox, or sensitive-data risk.Security boundary, credential, authz, sandbox, or sensitive-data risk.impact:session-stateSession, memory, transcript, context, or agent state can drift or corrupt.Session, memory, transcript, context, or agent state can drift or corrupt.issue-rating: 🦞 diamond lobsterVery strong issue quality with high-confidence source-level or clear reproduction.Very strong issue quality with high-confidence source-level or clear reproduction.
Metadata
Metadata
Assignees
Labels
P1High-priority user-facing bug, regression, or broken workflow.High-priority user-facing bug, regression, or broken workflow.clawsweeper:fix-shape-clearClawSweeper found a clear likely implementation shape for this issue.ClawSweeper found a clear likely implementation shape for this issue.clawsweeper:needs-maintainer-reviewClawSweeper marked this issue as needing maintainer review before automation.ClawSweeper marked this issue as needing maintainer review before automation.clawsweeper:needs-product-decisionClawSweeper marked this issue as needing a product or behavior decision.ClawSweeper marked this issue as needing a product or behavior decision.clawsweeper:needs-security-reviewClawSweeper marked this issue as needing security-sensitive review.ClawSweeper marked this issue as needing security-sensitive review.clawsweeper:no-new-fix-prClawSweeper does not recommend queueing a new automated fix PR for this issue.ClawSweeper does not recommend queueing a new automated fix PR for this issue.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.ClawSweeper found a high-confidence source-level issue reproduction.impact:securitySecurity boundary, credential, authz, sandbox, or sensitive-data risk.Security boundary, credential, authz, sandbox, or sensitive-data risk.impact:session-stateSession, memory, transcript, context, or agent state can drift or corrupt.Session, memory, transcript, context, or agent state can drift or corrupt.issue-rating: 🦞 diamond lobsterVery strong issue quality with high-confidence source-level or clear reproduction.Very strong issue quality with high-confidence source-level or clear reproduction.
Type
Fields
Give feedbackNo fields configured for issues without a type.
Summary
sessions_spawnaccepts arbitrary, unknownagentIdvalues and silently instantiates a new "subagent" using default model + empty bootstrap when the requester'ssubagents.allowAgentscontains the*wildcard. There is no registry validation: the wildcard skips the check entirely instead of meaning "any registered agent". This is undocumented behavior with side effects.Discovery
While auditing a peer-agent boundary violation, we noticed
sessions_spawncould target an arbitrary peer agent name (e.g.,graybeard) even though that agent doesn't exist in the requester's agent registry — only peer-agent gateways host it. Two probes confirmed:The bogus session ran successfully and replied: "I am the bogus_test_agent_xyz subagent, running on the anthropic/claude-opus-4-7 model."
Both child workspaces were materialized on disk:
~/.openclaw/agents/nopagent/and~/.openclaw/agents/bogus_test_agent_xyz/.Root Cause
src/agents/subagent-target-policy.tsshort-circuits took: truewhenallowAgentscontains*:resolveSubagentAllowedTargetIdsdoes populateconfiguredIdsfromparams.configuredAgentIds, but those ids are only used to build the display allowed-list — the validation path never consults the registry whenallowAnyis true:So
*literally means "accept any string as a valid agent id and provision a new agent on demand using defaults." There is no callsite that checkstargetAgentId ∈ configuredAgentIds.Behavior When agentId Is Unknown
agents.defaults.model.primary(no per-agent model config).SOUL.md, no DB-backed bootstrap rows, no domain context).~/.openclaw/agents/<arbitrary_string>/with subdirs (agent/,sessions/).The resulting agent has the requester's workspace and tool surface but inherits no policy or identity guardrails specific to the spoofed name.
Impact
Security / scoping
sessions_spawnandallowAgents: ["*"]can name-collide or impersonate any agent string — including peer-agent names from other gateways (e.g.,newhart,graybeard). The spawn doesn't actually reach those peers (they're separate gateways), but the in-gateway clone runs with the requester's permissions while looking like the peer in logs, transcripts, and channel announces.coderrforcoder) produces a silent fallback to a default-configured agent instead of an error, which can mask real configuration drift.*wildcard's intuitive meaning ("any registered agent in my allowlist") is wildly different from its actual meaning ("auto-provision any string"). Operators are likely to assume the safer semantic.Filesystem hygiene
~/.openclaw/agents/accumulates directories for every bogus, typo'd, deprecated, or accidentally-spawned name and never garbage-collects them. Sample from a long-running production gateway:Most of these have no corresponding entries in
agents.jsonand represent historical accidental spawns or deprecated agent names. Each has its ownsessions/*.jsonltranscripts. Over time this becomes a sprawl problem and an audit headache.Observability
agents_listcorrectly shows only registered agents, so operators auditing their roster won't see the rogue identities even though they exist on disk.Proposed Fix
Primary (default behavior): Validate target agent id against the configured registry even when
allowAgents: ["*"]is set. Replace the wildcard semantic with "any agent present inagents.list".In
resolveSubagentTargetPolicy, whenallowAnyis true, still require:(Make sure
configuredAgentIdsis actually threaded intoresolveSubagentAllowedTargetIdsat allresolveSubagentTargetPolicycallsites — right now it's accepted but the policy resolver doesn't pass it through.)Opt-out flag: Add
agents.subagents.strictRegistry: boolean(defaulttrue) to let operators preserve the current auto-provision behavior if they've built on top of it. Whenfalse, restore the pre-fix lax behavior with a one-time deprecation warning logged at spawn time.Suggested config schema:
Acceptance Criteria
sessions_spawn({ agentId: "<unknown>" })returns an error likeagentId "<unknown>" is not in the configured agent registry (allowed: a, b, c)instead of accepting and provisioning.~/.openclaw/agents/<unknown>/directory, no transcript file).subagent-target-policyupdated; new test covers the*+ unknown-id case.agents.subagents.strictRegistry: falserestores current behavior (auto-provision) for backward compat, with aWARNlog per spawn.docs/concepts/session-tool.md(ormulti-agent.md) explicitly stating the registry validation contract and the opt-out flag.Discovery Context (for changelog)
Found 2026-05-19 by NOVA agent (production) during a peer-agent boundary audit. The trigger was noticing that
sessions_spawn(agentId: "graybeard")had succeeded earlier in the day even though Graybeard is a peer agent running in a separate gateway. The follow-up probes with synthetic names (nopagent,bogus_test_agent_xyz) confirmed there is no registry check on the*path.Related
src/agents/subagent-target-policy.ts— primary bug locationsrc/agents/subagent-target-policy.test.ts— needs coverage for unknown-id casedocs/concepts/session-tool.md— needs registry-validation contract documenteddocs/concepts/multi-agent.md— could note the strictRegistry knob