Skip to content

feat: enforce dependency-scoped context (default-deny) for agents to prevent context leakage#87

Merged
JackChen-me merged 1 commit into
open-multi-agent:mainfrom
ibrahimkzmv:feat.dependency-scoped-agent-context
Apr 9, 2026
Merged

feat: enforce dependency-scoped context (default-deny) for agents to prevent context leakage#87
JackChen-me merged 1 commit into
open-multi-agent:mainfrom
ibrahimkzmv:feat.dependency-scoped-agent-context

Conversation

@ibrahimkzmv

@ibrahimkzmv ibrahimkzmv commented Apr 9, 2026

Copy link
Copy Markdown
Member

What

Switches agent context injection from a global SharedMemory model to a dependency-scoped (default-deny) model. Agents now only receive results from explicitly declared task dependencies, making them pure functions of (task + dependency results).

Main change: Agents now only see direct dep results instead of everything. You can still set memoryScope to 'all' for full shared memory visibility

Why

The current SharedMemory-based approach leaks all prior task outputs into every agent prompt, causing:

  • Context pollution from unrelated tasks
  • Increased token usage
  • Harder debugging due to hidden context influence

This change enforces isolation by default, ensuring agents only see what the orchestrator explicitly provides. It eliminates inter-agent context leakage by design rather than relying on filtering.

Closes #73

Checklist

  • npm run lint passes
  • npm test passes
  • Added/updated tests for changed behavior
  • No new runtime dependencies (or justified in the PR description)

@JackChen-me

Copy link
Copy Markdown
Member

Looks good. The queue-based dep resolution is cleaner than filtering SharedMemory keys, nice choice.

Two notes (both non-blocking, can be follow-up):

  • getSummary(filter) in shared.ts isn't called with a filter anywhere in production right now. Not harmful, but if it's meant as public API worth a quick comment, otherwise can drop it later.
  • This changes default runTeam() behavior (agents now only see direct dep results instead of everything). Might be worth a line in the PR description so existing users know about memoryScope: 'all'.

@JackChen-me
JackChen-me merged commit aa5fab5 into open-multi-agent:main Apr 9, 2026
3 checks passed
JackChen-me added a commit that referenced this pull request Jun 7, 2026
A no-tools agent received every registered built-in, including an unsandboxed
bash, on the default path (runAgent, runTeam/runTasks, and the runTeam
short-circuit). Tool output flows back to the model provider, so under prompt
injection this was a remotely triggerable exec + exfiltration primitive. #83
added the allowlist/preset mechanism but kept default-allow; #264 sandboxed the
filesystem tools but left bash unsandboxed; together they opened this.

Built-in tools now require a positive grant via tools or toolPreset; with
neither, an agent resolves to zero. resolveTools() is the chokepoint and the
runner gates execution on the granted set, so a registered-but-ungranted call
returns a "not granted" error instead of running. Custom/runtime tools
(customTools/addTool) stay available since registration is the grant, and still
honor disallowedTools. delegate_to_agent follows the same rule. Same default-deny
model #87 enforces for cross-agent context.

OrchestratorConfig.defaultToolPreset restores the old allow-all in one line;
per-agent tools/toolPreset override it.

BREAKING CHANGE: agents relying on implicit built-in tools get none until
granted. Restore with defaultToolPreset: 'full', or grant per agent via
tools/toolPreset.
JackChen-me added a commit that referenced this pull request Jun 7, 2026
* fix(tools)!: make built-in tools opt-in (default-deny)

A no-tools agent received every registered built-in, including an unsandboxed
bash, on the default path (runAgent, runTeam/runTasks, and the runTeam
short-circuit). Tool output flows back to the model provider, so under prompt
injection this was a remotely triggerable exec + exfiltration primitive. #83
added the allowlist/preset mechanism but kept default-allow; #264 sandboxed the
filesystem tools but left bash unsandboxed; together they opened this.

Built-in tools now require a positive grant via tools or toolPreset; with
neither, an agent resolves to zero. resolveTools() is the chokepoint and the
runner gates execution on the granted set, so a registered-but-ungranted call
returns a "not granted" error instead of running. Custom/runtime tools
(customTools/addTool) stay available since registration is the grant, and still
honor disallowedTools. delegate_to_agent follows the same rule. Same default-deny
model #87 enforces for cross-agent context.

OrchestratorConfig.defaultToolPreset restores the old allow-all in one line;
per-agent tools/toolPreset override it.

BREAKING CHANGE: agents relying on implicit built-in tools get none until
granted. Restore with defaultToolPreset: 'full', or grant per agent via
tools/toolPreset.

* docs: clarify defaultToolPreset excludes coordinator, synthesis, and consensus agents
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[P1] SharedMemory Context Isolation -- scope reads by task dependency graph

2 participants