# Tool layer Find every tool the model can call: functions registered with decorators (for example `@tool`, `@agent.tool`, `@mcp.tool`, `@function_tool`), schemas passed in a `tools=` parameter, and MCP servers in configuration. For every tool: - **Identity.** Find where the identity used for authorisation comes from. It must come from the authenticated request and be passed in code. If the model provides it as a tool argument, report broken authorisation (LLM03). - **Authorisation.** Is there a check in the tool handler, against that identity, before the action? A check only in the system prompt, only in the user interface or only on the endpoint that starts the agent isn't enough, because the model can call the tool on behalf of anyone whose text reaches it. - **Rules.** For every "only" or "never" in the system prompt, find the code that enforces it. A rule that exists only in the prompt is a finding. - **Arguments.** Treat every argument as untrusted input. For write tools, list the values that would cause harm (internal ranges, wildcards, other people's accounts, large quantities) and confirm the code rejects them. Arguments used in SQL, shell commands, file paths or URLs need the same checks as in any other code review (injection, path traversal, SSRF). - **Credentials.** Which token does the tool use, and what else can it do? Classify the tool as read or write by what its credentials allow, not by its name. Could it use credentials scoped to the invoker instead of a service account? - **Approval.** For write actions: - Is approval enforced by the application, with the tool call stopping until someone approves? A tool the model is asked to call before acting isn't a control. - Are the parameters stored by the application when approval is requested, and shown to the approver exactly as they will run, formatted by code rather than summarised by the model? - Does the approval handler check who approved against a list, and exclude the requester for sensitive actions? - Does it reject expired and reused approvals? - Does it run only the stored parameters? - Is the approval logged? - **Tool sets.** Are write tools available in requests that don't need them? Check whether tools are registered per request, user or channel, or whether the full list is always available. - **Text written by tools.** If a tool writes text produced by the model somewhere (a message, an email, a record, a file), add it to the map as an output and check it with [output-handling.md](output-handling.md). - **Tool results.** Tool results go back into the context. If a tool returns content written by third parties (web pages, emails, logs, tickets), add it to the map as an untrusted input.