attenu

Blog · · by , Attenu

What crosses an ADK transfer, and what should not

What ADK built well. Google's Agent Development Kit has the cleanest transfer model of the frameworks we integrate: agents declare sub_agents, the model calls transfer_to_agent, and two flags — disallow_transfer_to_parent and disallow_transfer_to_peers — say who may hand work to whom. In June the team fixed a real bug (#3850): the peer flag used to shape only the prompt; since 2.7.1 _get_agent_to_run raises ValueError('Transfer to sibling agent … is disallowed.'). That is enforcement in the right place.

The one thing left open, in their code. The fix lives in flows/llm_flows/base_llm_flow.py. ADK 2.x runs a different path by default — workflow/utils/_transfer_utils.py — whose sibling case resolves the target without reading the flag. With a scripted model and no API key, an analyst that may not transfer to peers transfers to the exporter, and the exporter's export tool runs. We filed a minimal repro on #3850 alongside this recipe; a one-line check would close it. But the recipe is not about the bug.

What no flag can say. Even when a transfer is legitimate, ADK decides who may transfer. Nothing says how much of the parent's authority goes with the work. The exporter reached through a read-only analyst holds whatever the developer wired for the exporter — and the process's credentials. That is the shape of most multi-agent incidents: not an agent that was never allowed, an agent that was allowed too much.

The code. (≤40 lines: Guard.issue for the root · DelegationGuardPlugin with delegations and tools · App(plugins=[…]) · require_guard(app).)

The denial. The transfer still happens — ADK's call. The exporter's authority is meet(analyst, exporter): crm.read with no egress. The export is denied before the tool body runs; the sink the tool writes into is empty, and in the unguarded run it is not. Retries stay denied; an undeclared second export tool is denied by default; if the audit log cannot be written the call does not proceed.

The verify. AuditLog.verify on the ledger, then attenu-guard verify bundle.json on the signed bundle: integrity, child ⊆ parent, containment — with no Attenu service involved.

What remains ADK's. Routing, the flags, the plugin hooks this stands on, and the fix for the workflow path. And what this recipe cannot do: a direct Python call around ADK runs — the test proves it — so read the trust boundary before you rely on it.

Verified against google-adk 2.7.1 on 2026-08-25. Recipe: examples/integrations/google_adk/peer_transfer/.

Rafael Asor is the founder of Attenu and the maintainer of attenu-guard and attenu-derive, open-source Python libraries for AI agent permissions across sub-agent handoffs. He is the author of the IETF Internet-Draft draft-asor-wimse-agent-delegation-chain and is based in Tel Aviv.