# When AI Subagents Call MCP Tools, Who Owns the Permission Decision?

## Table of Contents

Over the last day, teams debugging Claude Code subagent behavior hit the same uncomfortable question: if the parent can call an MCP tool, who actually owns the permission decision when a child process makes the call? The real-world reports in [issue #46228](https://github.com/anthropics/claude-code/issues/46228) and [issue #61315](https://github.com/anthropics/claude-code/issues/61315) show why this is not an edge case. Once work moves into background subagents, token context, approval surfaces, and runtime authority can drift apart fast.

That is why subagents should be treated as delegated actors, not permission clones. Parent access to Gmail, GitHub, or a database over MCP is not a blanket grant for every spawned worker. Permission ownership has to stay explicit at runtime: who asked, for which tool, with what scope, under whose consent, and for how long.

## Why delegation changes the security model

A parent agent usually operates inside a parent session that already has user context, OAuth token state, and a configured list of authorized MCP servers. A subagent, however, is a new execution principal with different instructions, narrower task context, and often different risk profile. Treating it as identical to the parent collapses your trust boundary.

A more effective model is runtime authorization rather than static inheritance. Runtime authorization asks: this specific child agent, for this exact tool call, now, should it be allowed? That decision must incorporate user consent, policy, and risk signals, then produce an auditable decision artifact.

## The core actors and where permission ownership lives

The minimum control surface has these actors:

- Parent agent: orchestrator in the parent session.
- Subagent: delegated worker with its own identity and task envelope.
- MCP server: tool endpoint that can trigger external side effects.
- OAuth token: credential material, which is scoped at issuance based on granted permissions.
- Permission gate: runtime decision point before each MCP tool execution.
- `mcpServers` allowlist: configuration boundary, not full authorization logic.

Permission enforcement should be influenced by the permission gate policy decision, ensuring explicit runtime authorization in conjunction with other factors such as policy, context, and user roles.

## Three failure modes that break delegated permission safety

When teams report "it worked in parent, failed in subagent" or "subagent hung waiting," they are usually seeing boundary confusion, not random bugs. The behavior discussed in [this issue](https://github.com/anthropics/claude-code/issues/46228), [this issue](https://github.com/anthropics/claude-code/issues/61315), and the official subagent model in [the subagents documentation](https://code.claude.com/docs/en/subagents.md) point to three recurring failure modes.

### Failure mode 1: Silent token inheritance across principal boundaries

Concrete example: the parent agent has an OAuth token for a cloud MCP server with write scope. A reporting subagent is spawned to read status, but because token inheritance is implicit, it can also perform write operations it was never intended to run. The child did not request delegated access and the user did not re-consent for that child context. This is privilege carryover, not least privilege.

Why it happens: teams conflate "same workflow" with "same principal."

Fix pattern: no inheritance by default, child-specific token binding, and short TTL per delegated decision.

### Failure mode 2: Allowlist-only trust that skips runtime intent checks

Concrete example: `mcpServers` includes `payments-prod`, so the subagent can invoke `refund.create` even though its task prompt was "draft customer response." The server was allowlisted, but tool intent, argument shape, and scope were never checked at runtime. The result is technically authorized by config, but operationally unauthorized by intent.

Why it happens: `mcpServers` allowlist is treated as full authorization.

Fix pattern: split tool scoping from runtime authorization. Allowlist defines possible connectivity; permission gate decides each call.

### Failure mode 3: Approval deadlocks and silent stalls in delegated flows

Concrete example: a subagent requests a sensitive tool that requires user consent. The platform does not route an explicit escalation event and the child waits indefinitely, producing no clear deny or retry signal. Parent orchestration appears stuck, operators cannot tell if this was denied or never reviewed, and users lose trust.

Why it happens: no anti-silent-stall behavior and weak timeout semantics.

Fix pattern: explicit escalation channel, timeout with fail-closed, deterministic denial reason, and parent-visible recovery path.

## Parent vs subagent, inheritance vs brokering, and scoping vs runtime authorization

Security architects should make these distinctions explicit in design docs and code:

- Parent vs subagent

Parent is orchestrator identity. Subagent is delegated identity. They may share user context, but they do not share authority by default.

- Token inheritance vs token broker

Inheritance passes existing OAuth token material downward. A token broker mints child-bound, scope-minimized, time-bounded credentials tied to a delegated approval event.

- Tool scoping vs runtime authorization

Tool scoping answers "what could ever be called." Runtime authorization answers "what is allowed right now for this child, this action, these args, this consent state."

## Policy patterns for safe delegated MCP authorization

Use policy patterns that assume delegation is risky unless proven safe:

- No inheritance by default.
- Trust ceilings per child agent type.
- Scoped MCP servers per task class.
- Explicit escalation for high risk tools.
- Timeout and fail-closed on missing approval.
- Revocation propagation from parent and user session state.
- Anti-silent-stall behavior with deterministic terminal states.

An effective process involves: child proposes tool call, permission gate evaluates policy plus consent state, broker issues bound token if approved, execution occurs with bounded credential, and both decision and outcome are logged.

## Enforcement and control plane implementation

At this point, teams need an implementation layer that can evaluate policy consistently across parent and child calls. This is where a control plane such as Permit.io can enforce delegated rules, attach environment and identity context, and return explicit allow or deny decisions that your runtime can execute without ambiguity. The important architecture point is not vendor lock-in, but central decisioning plus local enforcement hooks at every MCP call boundary.

## Delegated approval event schema and audit contract

To keep decisions portable and auditable, define a delegated approval event with fixed fields:

```json
{
  "parent_session_id": "ps_123",
  "child_agent_id": "ca_987",
  "child_agent_type": "research_subagent",
  "user_id": "u_456",
  "mcp_server": "payments-prod",
  "tool_name": "refund.create",
  "normalized_args_hash": "sha256:...",
  "requested_scope": "refund:write",
  "decision": "approve",
  "decision_reason": "user-confirmed-ticket-ownership",
  "approval_channel": "in_app_prompt",
  "approver_id": "u_456",
  "token_binding_id": "tb_001",
  "effective_ttl": "300s",
  "policy_version": "2026-06-24.1",
  "outcome": "executed_success"
}
```

This schema forces three properties that matter in incident response: who approved, what exactly was approved, and what actually happened.

For audit completeness, store two record classes:

- Decision-time records: policy inputs, consent state, decision, reason, approver, TTL, policy version.
- Execution-time records: token binding used, tool invocation metadata, result status, side effect identifiers, retry or rollback actions.

Both are required. Decision logs without execution logs cannot prove impact. Execution logs without decision logs cannot prove legitimacy.

## Concise implementation blueprint

Start with a brokered authorization path and keep inheritance disabled:

01. Assign immutable identities to parent and each subagent.
02. Keep `mcpServers` allowlist narrow and environment-specific.
03. Intercept every MCP tool call at a permission gate.
04. Compute `normalized_args_hash` before policy evaluation.
05. Evaluate policy with child identity, requested scope, consent, risk context.
06. If approved, mint child-bound OAuth token via broker with short `effective_ttl`.
07. Execute tool call with bound token, never with raw parent token.
08. Emit delegated approval event and execution event.
09. Enforce timeout fail-closed and explicit escalation for missing consent.
10. Propagate revocation instantly across parent session and active subagents.

## Frequently asked questions

### Should subagents ever inherit parent MCP permissions directly?

Default answer is no. Direct inheritance should be treated as an exception path for low-risk, read-only operations with strict ceilings and very short-lived credentials. Even then, log it as an explicit delegated approval, not an implicit shortcut.

### Is an mcpServers allowlist enough to secure subagent tool usage?

No. An allowlist only narrows reachable servers. It does not validate runtime intent, argument risk, consent freshness, or child role appropriateness. You still need runtime authorization per call.

### How is delegated access different from normal OAuth reuse?

Normal reuse assumes one principal continuing work. Delegated access introduces a second principal, the subagent, so token rights must be rebound to that child identity and scoped to the approved action window.

### What should happen if user consent is unavailable during a subagent request?

Use timeout plus fail-closed behavior. Return a deterministic denial or escalation-required outcome to the parent agent. Do not let the child hang silently and do not auto-upgrade privileges.

### How do trust ceilings work in practice?

Set maximum scopes per child_agent_type, independent of parent privileges. For example, a summarizer child can read ticket metadata but can never execute financial write tools, even if the parent can.

### What is the minimum audit payload for incident response readiness?

At minimum: parent_session_id, child_agent_id, user_id, mcp_server, tool_name, requested_scope, decision, decision_reason, approver_id, token_binding_id, effective_ttl, policy_version, and final outcome. Without these, root cause and blast radius analysis will be slow or incomplete.

### How do I roll this out without breaking existing agent flows?

Introduce the permission gate in shadow mode first, compare inherited vs brokered decisions, then enforce on high-risk MCP servers before broad rollout. Keep explicit escalation paths and operator visibility from day one so teams can resolve denies quickly without bypassing controls.

## Written by

### Or Weis

Co-Founder / CEO at Permit.io

## Related Tags

- [Model Context Protocol (MCP)](/content/tags/model-context-protocol-mcp/index.html)
- [Oauth](/content/tags/oauth/index.html)
- [Agent Security](/content/tags/agent-security/index.html)
- [AI Identity](/content/tags/ai-identity/index.html)
- [Best Practices](/content/tags/best-practices/index.html)
