Adithyan Arun Kumar demonstrated a flaw where a single human approval can be redirected to authorize a completely different action. His Loopjacking test targeted an A2A implementation built on LangGraph Agent Server.
In the controlled scenario, the approval role read a human-in-the-loop interrupt for mock_wire_transfer(20, approved-vendor) and later submitted approve for that view. Between view and decision, a separate maker sent another message through the server’s A2A route that replaced the pending call with mock_wire_transfer(2000, attacker-sink). The mock ledger then recorded 2,000 units moved under the approver’s authority.
The Task ID stayed the same.
That is the core confusion Kumar isolates. An A2A Task answers which work a message belongs to, not which exact tool call a human authorized. The specification before section 7.6.4 treated TASK_STATE_AUTH_REQUIRED as a nonterminal pause where clients could send messages to negotiate or correct a request, and where a credential could arrive out of band. It left open who defines the approval scope, what canonical operation was shown, and what must be checked before use. An implementation that checks only “this Task was approved” can spend decision D_A on operation B. An implementation that compares the current executable operation to the one bound to D_A rejects B or asks again.
The timeline makes the gap visible. Issue #2080 raised the ambiguity. PR #2081, merged into main, added section 7.6.4. It states TASK_STATE_AUTH_REQUIRED signals a need for authorization, not a grant, that scope is defined by the implementation, credential issuer or extension, and that later Task messages are not implicitly covered. When checked , the A2A releases page still listed v1.0.1 as the latest tag, so a tagged release should not be assumed to include the clarification.
