The agent sends {"projectId":"project-a","confirmed":true} to a deletion tool.
What established the permission: the authenticated user, a verified approval, or a boolean the model supplied?
If the execution component treats that boolean as proof, your confirmation dialog may be protecting the appearance of the action rather than the action itself.
Separate a proposed action from authority to perform it
Consider a hypothetical project-management assistant. It reads project notes and proposes an archive or delete action. The tool receives arguments chosen by the agent.
The note can describe a project. It cannot grant the current user permission to delete it. A model-produced statement that “the user approved” is also a statement to verify, not a new source of authority.
OWASP's AI Agent Security guidance calls for tool authorization outside the agent's context and explains why a confirmation flag alone is insufficient.
Test a policy the model cannot rewrite
Here is an intentionally narrow, in-memory example of an object authorization check:
function authorizeDelete(actor, project, args) {
if (actor.role !== "maintainer" ||
actor.tenantId !== project.tenantId ||
args.projectId !== project.id) {
throw new Error("Forbidden");
}
return project.id;
}
For this exercise, actor comes from a trusted server boundary, and project is the server-loaded record. Neither comes from the model's argument object. No actual deletion occurs.
Running controlled inputs gives these results:
| Input | Policy result |
|---|---|
| Maintainer, matching tenant and project | Allowed |
Reader adds confirmed: true and role: "maintainer" to arguments |
Denied |
| Maintainer from another tenant | Denied |
| Mismatched project identifier | Denied |
This illustrates one authorization layer. It does not implement a complete deletion endpoint, identity verification or an approval service. A production operation also needs input validation and an appropriate consistency strategy so the authorization decision cannot become stale before execution.
Approval needs an identity and an exact action
For a destructive operation, a real approval mechanism must verify who approved, which operation and target were approved, whether the approval is still valid, and whether it was already consumed. The execution boundary should check and consume it atomically before the action. A changed target or changed parameters must not silently reuse the original approval.
Keep ordinary authorization in place too. Confirmation does not give a reader the permissions of a maintainer.
OWASP's Authorization Cheat Sheet describes denying access by default and validating permissions on each request. Those principles still matter when an agent constructs the request.
Review the tool boundary before polishing the prompt
Ask the team to show what happens when the agent submits a valid-looking call for the wrong tenant. Then change the project after approval. Then try to reuse the approval.
Observe the executor's decision and resulting state. Do not accept a reassuring explanation from the model as the test result.
A system prompt can describe the intended behavior. The executor still needs to enforce the permissions independently.
Which check in your agent would still hold if the model supplied the wrong arguments?
Top comments (0)