The problem is not the output
Most teams secure an LLM deployment by filtering what comes out of it. That is the wrong boundary. The dangerous artifact is not the text the model returns to the user. It is the tool call the model emits on the way there.
An agent is a model plus a set of tools plus a credential that lets it call them. When a prompt injection lands, the attacker does not need to break the model. They need the model to name a tool the agent already holds. The agent then calls that tool with the scope it was granted, on behalf of nobody in particular.
This article covers what goes wrong concretely, and the access control and monitoring practices that stop it.
What is AI agent security
AI agent security is the discipline of constraining what an autonomous or semi-autonomous LLM system can do with the authority it holds. It covers the model, the tools it can call, the credentials behind those tools, and the data those tools reach. The core question is not whether the model is aligned. It is whether the agent can be made to act outside the authority of the user it is serving.
The specific question: access controls and monitoring
Best practices for implementing LLM access controls and monitoring reduce to a small number of enforceable rules:
- Every tool call carries a principal. The agent must act as a specific user or service identity, not as itself.
- Every tool has a scope narrower than the agent credential. The agent should not hold a credential broader than the union of what its current task needs.
- Authorization is decided outside the model. The model proposes a call. A policy layer decides whether that call is allowed for that principal.
- Every call is logged with principal, tool, arguments, and decision. Monitoring is not a dashboard. It is the record you need to reconstruct what an agent did.
- Deny by default. A call with no resolvable principal is refused, not allowed.
None of these depend on the model behaving well. That is the point.
Attack surface, concretely
Consider an agent that can read tickets, query a database, and send email. It holds one service credential with read access to the database and send access to the mail relay.
A user opens a ticket containing text that instructs the agent to summarize the ticket and email the summary to an address in the ticket body. The model follows the instruction. It calls the mail tool with the attacker address and a body drawn from the database query it ran a moment earlier.
The model did nothing wrong by its own logic. It followed the most recent instruction. The failure is architectural: the mail tool had no notion of which user the agent was serving, and the database tool had no notion that its output was about to leave the boundary.
This is not theoretical. It is the standard shape of a prompt injection that escalates into data movement. The same shape applies to code execution tools, file readers, and any tool that can reach an external endpoint.
The monitoring gap makes it worse. If the only log is the final model output, you cannot tell which tool ran, with what arguments, for which user. You find out after the email is sent.
The mechanism that stops it
The control belongs between the model and the tool. The model emits a proposed call. Before the call executes, a policy layer resolves the principal, checks the tool scope against that principal, and either allows or denies. The tool never sees a call that has not been authorized for a specific identity.
This ordering matters. If authorization runs after the tool has begun, or if the tool itself decides, the model has already influenced the decision. The check must be a gate, not a post-hoc audit.
Two properties make the gate effective:
- Least privilege per call. The agent credential is scoped to the task, not to the union of everything the agent might ever do. A summarization task does not need send access.
- Argument-aware policy. Denying a tool outright is coarse. Denying a mail call whose recipient is outside the current user domain is precise, and it catches the injection above without breaking the feature.
Monitoring complements the gate. Every decision, allow or deny, is logged with the principal and the arguments. Denials are the interesting signal: a burst of denied calls from one agent session is what an injection attempt looks like from the outside.
Implementation with RESK
reskSecure enforces least privilege on agent tool calls. It sits at the boundary between the model and the tool, resolves the principal for each call, and applies policy before execution. The agent does not get to decide its own scope.
ReskPoints provides the decision and logging surface: each tool call is evaluated against policy and recorded with the principal, the tool, and the arguments, so that allow and deny decisions are reconstructable after the fact.
For the tool permission model in more depth, see the companion article on AI agent tool permissions.
To enforce least privilege on your agents, start at reskSecure.
Checklist
- Every tool call resolves a principal before execution.
- Agent credentials are scoped to the current task, not the union of all tasks.
- Authorization runs as a gate between model and tool, not inside the tool.
- Policy is argument-aware where the tool can reach an external endpoint.
- Calls with no resolvable principal are denied by default.
- Every allow and deny is logged with principal, tool, and arguments.
- Denials are monitored as a signal, not just stored.
- Tool permissions are reviewed against the same model as the companion permissions article.
Top comments (0)