AI tools: input trust, execution identity and approvals
Prove when lower-trust content changes a protected tool action, then locate the missing authorization or consent boundary.
- 01Pin legitimate task
- 02Map context to tool
- 03Run paired trials
- 04Check server decision
- 05Minimize evidence
At each step: retain the control → record the observation → continue only while the next boundary is understood.
Used in these playbooks#
Setup and security invariant#
Start with a local agent application, two researcher-owned identities, and stub tools that write only to an in-memory ledger or local JSONL file. Record the model identifier, sampling settings, application commit, available tools, connector scopes and legitimate user task. The invariant is: retrieved content can supply task data, but cannot grant permission, change the acting principal or silently expand an approved operation. Reuse the authorization matrix for tool objects and identity/session procedure for credentials.
Make a four-column trust map: attacker-editable source, transformation, tool argument, server-side decision. Include tool descriptions, tool results, document text, OCR and summaries. Follow the actual source path using source-to-sink review. A changed answer style demonstrates instruction influence; a security finding needs an unauthorized read, write, destination, privilege or other protected consequence. OWASP separates excessive tool functionality, permissions and autonomy. OWASP Excessive Agency
Controlled procedure#
- Record the baseline. Ask the owned victim agent to summarize one benign shared document. Save the exact prompt, document hash, tool calls and outbox state. Verify that a separately authorized mock write succeeds and an unapproved write is rejected; otherwise a silent tool failure could masquerade as protection.
- Change one lower-trust input. In a copy of the document, add a test instruction requesting a harmless change to the stub destination. Keep task, tools and identities constant. Run five fresh baseline trials and five fresh candidate trials with a fixed small token budget. Save every attempt, including failures; do not assume sampling controls make a hosted model deterministic.
- Inspect execution independently. Compare suggested calls, dispatched calls and committed stub events. Record which principal reached the backend. A model claiming success is insufficient. Repeat the same operation directly through the local tool adapter to determine whether the backend itself has an ordinary object-authorization defect.
- Bind approval to the action. Approve one harmless draft, then vary only its object ID, destination or content in the local fixture. The approved values and executed values must match, or the product must request renewed approval according to its contract. Compare canonical argument digests, not UI labels.
- Check the MCP boundary separately. With your own OAuth fixtures, compare a correct-resource token with a valid token for another resource. Exercise client A consent followed by a fresh client B request. MCP requires intended-audience validation and per-client consent in the documented proxy scenario; inherited upstream consent is not sufficient. Match all requests to the deployed protocol version. MCP authorization, MCP security guidance
Command and evidence cheat sheet#
Run these local inspection commands in the reviewed lab checkout. lab/tool-events.jsonl is your recorded adapter output, with one JSON object per event; these commands inspect evidence and do not invoke an agent.
rg -n 'approve|consent|tools/call|audience|tenant_id|workspace_id' ./src
python3 -I -S -m json.tool lab/case.json
python3 -I -S - <<'PY'
import json
from collections import Counter
with open('lab/tool-events.jsonl') as stream:
rows = [json.loads(line) for line in stream if line.strip()]
print(Counter((r['case'], r['decision']) for r in rows))
PY
Use event fields case, trial, principal, tool, argument_digest, decision and committed. Redact credentials. Python's JSON CLI validates the case file; it does not assess the security result. Python JSON documentation
Evidence, false positives and completion#
Preserve the legitimate task, attacker capability, differing document bytes, full relevant tool trace, principal and controlled side effect. Exclude hallucinated actions, canaries already present in the attack text, intentionally authorized tool use, and tests requiring nonexistent attacker editing rights.
- Baseline allowed operation and denied operation both work as expected.
- Every candidate has an unchanged benign comparison.
- Suggested, attempted and committed actions are distinguished.
- Approval arguments and execution identity are recorded.
- Successes/attempts and cleanup of local fixtures are included.
Continue across task lifetime#
An initial allowed or denied tool call does not cover later resumed work. Continue with AI state lifecycle for memory/checkpoint ownership, MRTR state binding, cancel/retry behavior and private caches. Apply resource budgets to tool fan-out, loop limits and per-principal cost without generating load on a live service. For model-output HTML, SQL or file effects, inspect the final consumer using browser trust, injection tracing and file boundaries; model output is input to those components.
Vulnerability reverse references#
- Indirect prompt injection into protected tool actions — Lower-trust retrieved content influences the agent into a tool operation outside the legitimate task or granted authority.
- Agent tool accepts unauthorized object or tenant parameters — A tool trusts caller-supplied object or workspace identifiers instead of enforcing the authenticated principal’s authority.
- Agent approval is not bound to executed arguments — An approved harmless action can be modified before dispatch without revalidating the approval’s scope.
- MCP proxy consent confuses different clients — A proxy reuses upstream consent in a way that grants a new MCP client access without the resource owner’s intended per-client consent.
- MCP accepts a token for another resource — A protected MCP resource accepts a token that was not issued for that resource.
- MCP resumed state changes authorization or request meaning — An MRTR server trusts modified or context-mismatched requestState when it affects a protected resumed operation.
- Untrusted model artifact reaches executable deserialization or custom code — An attacker-controlled artifact reaches a loader whose execution trust exceeds the uploader's intended data-only authority.
Nearby shared procedures#
Object, function, and property authorization · Authentication, recovery, federation, and session lifecycle · Trace input into queries, commands, and templates · Server-side fetching and network trust boundaries · Browser execution, cross-origin reads, and forged actions · Uploads, downloads, paths, archives, and XML · Workflow invariants, replay, idempotency, and races · REST, GraphQL, gRPC, WebSocket, and SSE permission parity