Where LLM Access Controls Belong in the Request Path
The question behind the question Teams searching for best practices on LLM access controls and monitoring usually already have a working agent. The agent calls tools. The tools work. The question is not whether to add
The question behind the question
Teams searching for best practices on LLM access controls and monitoring usually already have a working agent. The agent calls tools. The tools work. The question is not whether to add controls, it is where the controls go, and why that location matters more than the control itself.
This is an architecture question. Get the placement right and the rest of the checklist becomes mechanical. Get it wrong and every control you add is advisory.
What AI agent security covers
AI agent security is the discipline of constraining what an autonomous or semi-autonomous system can do with the credentials and tools it holds. It is not prompt engineering. It is not content filtering. It is the same problem as any other privileged workload: an identity acts on resources, and something between the identity and the resource decides whether that action is allowed.
The difference is that the identity is a model, the action is chosen at runtime, and the resource is often an internal API that was never designed to face an unpredictable caller.
Attack surface, concretely
Consider an agent with three tools: a ticket reader, a repository writer, and an HTTP fetcher. Each tool holds a credential. Each credential was issued once, at setup, and never scoped to a task.
Three failure modes follow.
First, over-broad scope. The repository writer can push to any branch in any repository the token can reach, because the token was issued for the whole organization. The agent only ever needed one repository.
Second, no expiry. The credential outlives the task. A session that ran for four minutes leaves a token that is valid until someone rotates it.
Third, no decision log. When the agent calls the HTTP fetcher with a URL it constructed from untrusted input, nothing records which agent identity made the call, under which scope, and whether that scope was intended for this task. Without that record there is no way to answer what happened.
None of these require an attacker to be clever. They require the agent to be useful, which it is.
The mechanism that stops it
The control belongs in the request path, between the agent runtime and the tool. Not in the system prompt, not in a policy document, not in a review process.
The ordering matters:
- Resolve the agent identity. Every call carries a stable identity, not a shared service account.
- Resolve the requested scope. The call declares what it wants to do, not just which tool it wants.
- Check the permission. The identity either holds that scope for this task or it does not.
- Record the decision. Allow or deny, with identity, scope, tool, and time.
- Execute, or return a denial the agent can handle.
If step one is missing, every later check is anonymous. If step two is missing, you are checking tool access rather than action access, which is the same as checking nothing. If step four is missing, you have enforcement without observability, and you cannot tighten what you cannot see.
The reason this belongs in the request path rather than the prompt is that the prompt is model input. Model input is advisory. A model that is instructed to stay within scope may still construct a call outside it, and there is nothing between that call and the tool. A check in the request path is not advice. It is a gate.
Monitoring is the other half
Enforcement without monitoring produces denials you cannot explain and permissions you cannot safely remove.
The useful log entry is small: agent identity, requested scope, tool, decision, timestamp. From that you can answer three questions that matter operationally.
Which scopes are never used? Those are candidates for removal.
Which identities request scopes outside their usual set? Those are candidates for review.
Which denials cluster around one tool? That tool is either misconfigured or being probed.
A permission that is never exercised is a permission you can delete. That is the whole point of logging: it turns least privilege from a one-time design decision into a loop you can run continuously.
Implementation with RESK
reskSecure enforces the request path checks. Agent identity, scope resolution, permission decision, and the decision record sit between the runtime and the tool, so a call that is out of scope does not reach the tool.
ReskPoints provides the visibility layer over those decisions. It surfaces which scopes are exercised, which identities are requesting what, and where denials concentrate, so the permission set can be tightened against real traffic rather than a guess made at setup.
Together they cover the two halves of the problem: the gate and the record. Enforcement stops the call. The record tells you what to change next.
If you are starting from an agent that already holds broad credentials, the practical sequence is to put the gate in place first, observe for a period, then remove the scopes that the record shows are unused.
Checklist
- Every agent call carries a distinct identity, not a shared service account.
- Every call declares a scope, and the scope is checked before the tool runs.
- The permission check sits in the request path, not in the prompt or in a document.
- Every allow and every deny is recorded with identity, scope, tool, and time.
- Scopes that are never exercised are removed on a schedule.
- Denials are reviewed, because a cluster of them is a signal.
- Credentials expire, and expiry is tied to the task rather than to a rotation calendar.
For the related question of how tool permissions are scoped per agent, see the article on AI agent tool permissions.
Enforce least privilege on your agents with reskSecure.
Originally published by Dev.to Security. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.