Helpful first: Prompt injection and untrusted retrieval (RAG): when data hijacks instructions
Key points
- Identify the three root causes of Excessive Agency: excessive functionality (too many tools), excessive permissions (over-scoped credentials), and excessive autonomy (missing approval gates)
- Contrast read/draft actions with high-impact write actions across downstream services
- Verify downstream state via fresh readback rather than trusting model prose
- A model sentence is not an authorization decision.
Three ways an AI agent gains excessive agency
When an engineering team connects a language model to real enterprise APIs - databases, email servers, payment rails, or CI/CD deployers - the failure mode shifts from "the chatbot said something wrong" to "the agent did something destructive." In the OWASP LLM Top 10, this architectural flaw is called Excessive Agency.
Excessive agency stems from three distinct mistakes: Excessive Functionality (attaching delete, wire-transfer, or shell-exec tools to an agent that only needs to draft summaries), Excessive Permissions (running the tool executor with a global admin service account instead of a least-privilege token), and Excessive Autonomy (allowing the model’s tool-call JSON output to execute high-impact writes directly without an independent policy and human gate).
| Agency Dimension | Vulnerable Pattern | Least-Privilege Engineering Control |
|---|---|---|
| Functionality (Tool Catalog) | Exposing a generic run_ or http_ tool to the model | Expose only narrow, typed, single-purpose tools (e.g., create_) and strip unneeded plugins |
| Permissions (Downstream Identity) | Tool runner authenticates to the payment API using a static master key with payments:admin | Use scoped, short-lived OBO (On-Behalf-Of) tokens limited to the exact resource and action |
| Autonomy (Execution Gate) | Model output call_ executes immediately against the bank API | Treat model output as an unverified Proposal; enforce an independent policy latch and human approval before execution |
Separating Task, Proposal, Decision, Application, and Readback
At Meridian Space & Robotics (chronos.), Principal Security Architect Vera Vance requires every agentic workflow to separate five distinct steps: Task (the initial user goal plus any untrusted external data), Propose (the LLM generating a candidate tool call), Decide (an independent policy enforcement gate and, for high-impact actions, an authenticated human reviewer evaluating the proposal), Apply (the downstream service executing only what passed the gate), and Check (performing a fresh GET readback from the authoritative service to confirm what actually changed).
Why is that final Check step mandatory? Because an LLM can easily hallucinate "I have saved the draft and canceled the transfer" even when the API call failed, or an attacker’s prompt injection can instruct the model to lie about a silent payment.
Walkthrough: gating tool calls against untrusted supplier input
Compare the three execution paths in the interactive figure below (Task -). In every path, the workflow begins with an untrusted supplier input (Supplier A · USD 100) while the downstream email draft service starts at Not saved and the payment ledger starts at No payment record.
In the defended baseline, the model may propose both a harmless email draft (D220) and a risky payment action, but the independent Gate / Latch enforces least privilege: the low-risk draft is applied (GET · D220 retained), while the unapproved payment proposal (P220 / USD 1,000) is blocked so the ledger readback confirms GET · no P220 / USD 1,000. Contrast that with the Broad tools fault variant - where an over-privileged tool gate lets the risky payment land (GET · P220 / USD 100 held in fault state) - and the Missing approval variant, where a payment to a different payee or amount (None for B / USD 100) is rightly refused at the human approval latch until an authorized operator explicitly signs off on the exact payee, currency, and amount.
FOLLOW THE ACTIONS
Drafting and payment need different authority
Follow one invoice through a proposal, service checks, application and fresh readback.
Kael Cho asks for a draft for I220, Supplier A, USD 100. No payment was requested.
More about this step
The invoice and draft task are received. The selected service begins with USD 1,000 and no D220 or P220.
The task is drafting. Which design can still queue the unintended payment?
Broad tools. The broad credential and missing approval check permit the unintended call. A proposal or queue receipt does not prove settlement.
The executor has an invoice grant. What still blocks this payment?
Missing approval. The service needs a trusted, unexpired approval for this executor, invoice, payee, amount and currency. Client text cannot create it.
Chapter 1 of 5
Read all chapters
Nothing plays on its own. Watch all runs one overview. Replay this step stops on the selected chapter; Pause and Resume keep your place. Scrub or choose a chapter to inspect. Opening detail, leaving the picture, or hiding the tab pauses playback. Reduced motion shows still chapters with no travel.
Draft only
- Kael Cho asks for a draft for I220, Supplier A, USD 100. No payment was requested.The invoice and draft task are received. The selected service begins with USD 1,000 and no D220 or P220.
- The selected output proposes a draft and a USD 100 payment to Supplier B instead. Neither proposal has executed.This is predetermined teaching output, not a live model test. An unexpected output can exceed the task without prompt injection.
- The assistant can save D220 for I220. It has no payment grant, so the proposed debit is refused.A separate decision request reads stored grants. It changes no records. Each later application call checks its authority again.
- The service saves D220 and returns 403 for payment. No P220 is created and the balance stays USD 1,000.Separate POST calls recheck identity, action, resource and any required approval. Draft storage and queue acceptance have separate responses.
- Fresh reads find D220, no payment record and USD 1,000. I220 and the legitimate draft remain available.Independent GETs retrieve draft, invoice, queue and balance. They prove these local records only, not a bank transfer or every agent workflow.
Broad tools
- Kael Cho asks for a draft for I220, Supplier A, USD 100. No payment was requested.The invoice and draft task are received. The selected service begins with USD 1,000 and no D220 or P220.
- The selected output proposes a draft and a USD 100 payment to Supplier B instead. Neither proposal has executed.This is predetermined teaching output, not a live model test. An unexpected output can exceed the task without prompt injection.
- The broad service permits payment without approval; this exceeds Kael Cho’s drafting task.A separate decision request reads stored grants. It changes no records. Each later application call checks its authority again.
- The broad service saves D220, queues P220 for Supplier B and holds USD 100. Bank settlement is not shown.Separate POST calls recheck identity, action, resource and any required approval. Draft storage and queue acceptance have separate responses.
- Fresh reads find D220 and the unintended queued payment. USD 100 is held; settlement and later effects remain unknown.Independent GETs retrieve draft, invoice, queue and balance. They prove these local records only, not a bank transfer or every agent workflow.
Missing approval
- Kael Cho asks for a draft for I220, Supplier A, USD 100. No payment was requested.The invoice and draft task are received. The selected service begins with USD 1,000 and no D220 or P220.
- The selected output proposes a draft and a USD 100 payment to Supplier B instead. Neither proposal has executed.This is predetermined teaching output, not a live model test. An unexpected output can exceed the task without prompt injection.
- The executor has an I220 payment grant, but no trusted approval for Supplier B and USD 100.A separate decision request reads stored grants. It changes no records. Each later application call checks its authority again.
- The service saves D220 and returns 403 for payment. No P220 is created and the balance stays USD 1,000.Separate POST calls recheck identity, action, resource and any required approval. Draft storage and queue acceptance have separate responses.
- Fresh reads find D220, no payment record and USD 1,000. I220 and the legitimate draft remain available.Independent GETs retrieve draft, invoice, queue and balance. They prove these local records only, not a bank transfer or every agent workflow.
Show as a table
The same I220 draft task and selected unintended Supplier B proposal reach three services. Draft only refuses payment; Broad tools queues it; Missing approval refuses it. Draft D220 still saves in all three. OWASP Version 2026 identifies excessive agency as LLM03:2026.
| Stage or scope | What the local records support | What remains separate |
|---|---|---|
| Task | I220 is Supplier A, USD 100. Kael Cho requests a draft. The original is retained. | The selected model output proposes Supplier B instead; no live model or attack success is measured. |
| Decision | A separate decision request checks stored grants without applying either action. | Every application call must recheck identity, action, resource and any required approval. |
| Draft only | Assistant identity can read I220 and save D220. Payment POST returns 403. Fresh reads find no P220 and USD 1,000. | No payment credential or grant follows from a confident proposal. Ordinary drafting still works. |
| Broad tools | The assistant can pay any invoice without independent approval. POST stores P220 to Supplier B and holds USD 100; fresh reads confirm those records. | This is synthetic queue state, not bank settlement. No bank, mail service or real money is involved. |
| Missing approval | A separate executor has a grant on I220, but no matching trusted approval for B and USD 100. Payment POST returns 403; fresh reads find no P220 and USD 1,000. | An unexpired approval must bind executor, invoice, payee, amount, currency and expiry. A client claim or model output is insufficient. |
| Scope and assumptions | Trusted identities and grant/approval storage are assumed. The HTTP/SQL fixture tests decisions, application, fresh reads and retained originals. | A post-story exact Supplier A approval permits a scoped executor call; changed arguments and expired approval fail. This is not assurance for every agent workflow. |
Scene checked 2026-09-30.
CHECK YOUR JUDGMENT
A developer at Meridian Space & Robotics (chronos.orbital ) builds an assistant that reads incoming supplier invoice emails and prepares replies. To save time, the developer gives the assistant’s tool runner a single service-account token that has permission to both save email drafts (mail:draft) and execute live wire transfers (payments:send), relying on the system prompt "Only call payments:send if the email looks completely legitimate." What is the primary architectural flaw?
NEXT FIELD LESSON