Multi-Agent
X-Agent Policies
Control which agents can invoke, read, or list other agents in the workspace using per-target allow, review, and block policies.
Operations
Three operations are policy-controlled, plus one special case:
| Operation | What it gates | Target |
|---|---|---|
| list | Calling list_agents to discover other agents | None (workspace-wide) |
| read | Calling get_agent_sessions or get_agent_session_transcript to browse another agent's history | A specific target agent |
| invoke | Calling invoke_agent to send a message to another agent | A specific target agent |
| create | Calling create_agent to create a new agent | N/A (always prompts) |
Each operation is evaluated independently: allowing invoke does not allow read, and vice versa. This supports write-only access (an agent can trigger another but not browse its history) and read-only access (an agent can monitor another's sessions but not message it).
Two exceptions:
- When
invoke_agentruns withsync=true, the target's final response is returned inline as part of the invoke result. This needs no separatereadpolicy; it is part of the invoke contract. create_agentalways requires manual approval. No policy is ever stored for it, so there is no "always allow" option.
Decisions
Each policy resolves to one of three decisions:
- Allow: The operation proceeds without prompting.
- Review: The user is prompted to approve or deny the operation.
- Block: The operation is denied immediately, without prompting.
Policy precedence
Policies are evaluated most-specific-first:
- Per-target policy: A policy for this specific caller, operation, and target agent wins.
- Global policy: Otherwise, the caller's global policy for the operation (target = all agents) applies.
- Default: With no policy at all, the operation falls back to
review.
For example, if Agent A has a global invoke policy of allow but a per-target invoke policy of block for Agent B, Agent A can invoke any agent except Agent B.
The review flow
When a policy evaluates to review, an approval prompt appears in the caller agent's session as an orange-themed card showing:
- Which agent is requesting the action.
- The operation (list, read, invoke, or create).
- The target agent, for read and invoke.
- A preview of the message being sent, for invoke.
Deny
Rejects this request. The calling agent receives an error saying the operation was denied.
Allow Once
Approves this request without saving a policy, so the next identical operation prompts again.
Always Allow (remembered policies)
Available for list, read, and invoke (not create). Approves the request and saves a policy so future identical operations proceed automatically. The options vary by operation:
- list: "Always allow listing agents" saves a global
listpolicy. - read: "Always allow reading " saves a per-target policy; "Always allow reading all agents" saves a global one.
- invoke: "Always allow messaging " saves a per-target policy; "Always allow messaging all agents" saves a global one.
When a global "always allow" is saved, other pending review prompts for the same operation resolve automatically, since the new policy covers them.
Review timeout
After 5 minutes without a decision, the review times out and the operation is denied. The calling agent receives a timeout error.
Managing policies in settings
View and edit policies in the agent's settings dialog, under the X-Agent Policies tab (labeled "Cross-agent permissions" in the UI).
Global permissions
Three toggles set workspace-wide defaults for this agent:
- List Agents: Whether the agent can call
list_agents. Allow, Review, or Block. - Read sessions of all agents: The default read policy for any agent without a per-agent setting.
- Send messages to all agents: The default invoke policy for any agent without a per-agent setting.
Per-agent permissions
A table lists every other agent in the workspace with two toggles per row: Read sessions and Send messages. Per-agent settings override the global defaults. The Review state (shown as "default") means no policy is stored. Filter the list by name or slug with the search box.
Policy storage
Policies live in the x_agent_policies database table:
| Column | Description |
|---|---|
caller_agent_slug | The agent these policies apply to (the one making the call) |
target_agent_slug | The target agent, or null for global policies |
operation | list, read, or invoke |
decision | allow or block (review is not stored; it is the implicit default) |
Each (caller, target, operation) combination is unique. When an agent is deleted, all policy rows referencing it, as caller or target, are cleaned up automatically.
Auth mode considerations
In auth mode, X-Agent Policies work alongside the role-based access control (ACL) system:
- list_agents results are filtered to agents the calling agent's owner has access to.
- get_agent_sessions and get_agent_session_transcript require the caller's owner to have at least
viewerrole on the target agent. - invoke_agent requires the caller's owner to have at least
userrole on the target agent. - create_agent copies the caller's owner ACL to the new agent, so the owner automatically has access.
ACL checks run first: if the caller's owner lacks access to the target, the request is rejected before the X-Agent Policy is evaluated. The settings tab respects the same visibility, hiding policies that target agents the viewer cannot see.
Audit trail
Cross-agent operations that go through review are tracked in the proxy audit log alongside other reviewed actions like API scope and MCP tool approvals. Each entry records the caller agent, the operation, the target, and the outcome (allow, block, denied by user, or review timeout).
View the log in the agent's settings under the Audit Log tab. See Audit Logging for audit logging across Gamut.