Skip to main content

Cross-Agent Isolation Policy

The cross-agent-isolation policy category prevents one agent from reading another agent's memory, scratchpad, tool state, or context -- even when they share the same tenant runtime. A finance-bot must not silently pull a support-bot's session context, and a sub-agent must not exfiltrate its parent's working memory unless explicitly authorized.

This is the agent-level analogue of multi-tenancy. Required for the Atlassian / IBM enterprise pitch. Maps to NIST AI RMF MS-2.7 (segmentation between AI systems), ISO 42001 A.8.3 (information access restriction), and OWASP LLM01 lineage gap.

Rules

RuleTypeDefaultDescription
isolation_scopesstring[]["memory", "context", "tool_state", "scratchpad"]Surfaces to isolate
allow_cross_agent_readsobject[][]Allowlist entries: {source, target} pairs OR {trust_group} names
block_cross_tenantbooleantrueHard-block any cross-tenant read regardless of allowlist
tool_patterns_cross_agentstring[]["memory.read_other_*", "scratchpad.read", "agent_handoff.*"]fnmatch patterns for cross-agent tool calls
action_on_violationstringblockblock, warn, or redact

How It Works

Runs at before_workflow and mid_execution. after_workflow is a no-op (isolation is enforced before the surface is touched).

Three checks in order:

1. Cross-tenant short-circuit (hard ceiling)

If block_cross_tenant: true and the context carries a cross_tenant_read marker whose tenant differs from the calling agent's tenant -> BLOCK, bypassing the allowlist. No allowlist entry can override this.

2. Explicit cross-agent reads

Reads context.read_from_agent -- the runtime emits this when memory.read(agent=...), handoff(...), or similar primitives are invoked. Normalizes to (source, target) pairs and checks against allow_cross_agent_reads.

3. Pending tool calls on cross-agent surfaces

Scans context.pending_actions for tool calls whose name matches any of tool_patterns_cross_agent (fnmatch). Tries to extract target_agent from args (args.agent, args.target_agent, args.source_agent, args.from). If the target is set and not allowlisted -> violation.

Allowlist Resolution

Entries can be:

  • {"source": "*", "target": "shared-memory"} -- any agent may read shared-memory
  • {"source": "finance-bot", "target": "audit-logger"} -- specific pair
  • {"trust_group": "loan-underwriting"} -- both agents must carry membership in context.agent_trust_groups

Star wildcards (*) match any source/target. fnmatch patterns are supported.

Context Attributes Read

AttributePhasePurpose
context.tenant_id / context.tenantallCalling agent's tenant for cross-tenant check
context.cross_tenant_readallExplicit cross-tenant handoff marker
context.read_from_agentallExplicit cross-agent read signal
context.agent_nameallSource agent for pair resolution
context.pending_actionsallPending tool calls to scan
context.agent_trust_groups / context.trust_groupsallDeclared trust-group memberships

Example Policy

Strict isolation with declared trust groups

{
"name": "Strict cross-agent isolation",
"category": "cross-agent-isolation",
"rules": {
"isolation_scopes": ["memory", "context", "tool_state", "scratchpad"],
"allow_cross_agent_reads": [
{"source": "*", "target": "shared-memory"},
{"trust_group": "loan-underwriting"}
],
"block_cross_tenant": true,
"tool_patterns_cross_agent": [
"memory.read_other_*",
"scratchpad.read",
"agent_handoff.*"
],
"action_on_violation": "block"
},
"scope": {
"agents": ["*"]
},
"enabled": true
}

SDK Integration

import waxell_observe as waxell
waxell.init()

@waxell.observe(
agent_name="finance-bot",
enforce_policy=True,
metadata={"agent_trust_groups": ["loan-underwriting"]},
)
async def finance(query: str) -> str:
return await analyze(query)

For multi-agent workflows that need to legitimately share state, declare both agents in the same agent_trust_groups AND add a {"trust_group": "<name>"} entry to allow_cross_agent_reads.

Observability

FieldExample (BLOCK)
Categorycross-agent-isolation
Actionblock
ReasonAgent 'finance-bot' attempted to read state from 'support-bot'; no allowlist entry permits this cross-agent read.
Metadata{"source_agent": "finance-bot", "target_agent": "support-bot", "nist_ai_rmf": "MS-2.7", "iso_42001": "A.8.3"}

Common Gotchas

  • Cross-tenant is a hard ceiling. No allowlist can override block_cross_tenant: true. To allow cross-tenant reads (rare), explicitly disable the flag.
  • Allowlist entries are dicts, not strings. {"source": "...", "target": "..."} or {"trust_group": "..."}. Plain strings are silently ignored.
  • Trust groups require BOTH agents to declare membership. If only the source agent carries the group, the entry doesn't apply.
  • fnmatch patterns, not regex. memory.read_other_* matches memory.read_other_agent but not memory.readOther. Patterns are also case-insensitive (the handler matches both raw and lowercased).
  • Reads same-tenant cross-agent -- not cross-tenant. This category is for isolating agents within ONE tenant. Cross-tenant is handled as a hard ceiling.
  • Pending tool calls need args populated with the target. If your runtime doesn't pass agent / target_agent in tool args, the policy can't extract a target and reports unknown.
  • redact action is supported in addition to block / warn -- useful when you want the run to continue but the cross-agent read to be stripped from the response.

Next Steps