DEV Community

Tirth Gajjar for BigCircle

Posted on Originally published at bigcircle.ai

How to set AI agent permissions and access control

Set AI agent permissions one action at a time, for one workflow, and never by approving the agent as a whole. Write down each change the workflow makes to another system, give each change its own tool with typed arguments, and check the asking person, the target record and its current state in code before the call runs. Keep the credential in a vault or broker that attaches it at call time, so the model never sees it.

We build agents this way. On Skionis the agent reaches a live AWS account only through purpose-built tools. On Solarpunk the credentials stay in an encrypted vault on the user's machine, outside anything the model reads, so neither design asks anyone to trust the model's judgement about what it is allowed to do.

The usual access-control tools answer a different question, which is why this is harder than it looks. An OAuth scope says what an application may do at a server, such as files:write. It does not say that the agent may move one onboarding case to ready_for_provisioning, for the person who asked, while that case is still verified.

Identity vendors cover tokens and delegation well, and our guide on MCP authorization covers the token a run should hold. This guide covers the step before that: listing what one workflow changes, deciding a scope for each change, and putting the authorization check and the credential where the model cannot talk its way past them.

Why not approve the agent as a whole?

Because nobody can review an approval that broad. An AI agent reads data, picks a tool, prepares a change, makes it and checks the result, and each of those steps carries a different amount of authority. Reading a customer record is not changing it, and preparing a refund is not sending one. An approval that covers the agent covers all of those steps at once, including the ones nobody has looked at.

What the agent can attempt also grows without anyone deciding it should. A new MCP server, a browser tool or a model update adds capability, and an approval written as "the onboarding agent may manage cases" covers each of those the day it arrives.

Approve an action instead, written so that a reviewer can say yes or no to it:

Update the status field on eligible onboarding cases from verified to ready_for_provisioning in the EU production tenant, after a named operator approves, within 15 minutes of that approval.

That sentence names a verb, a field, a starting state, an end state, a tenant, an approver and a time limit. Security, product and operations can each object to one part of it, which they cannot do with "manage cases". The time limit matters as much as the rest, because an approval with no expiry becomes standing permission for every later run that finds it.

How do you list the actions in one workflow?

List the changes before you write a single tool, because the list decides which tools exist. Walk the workflow the way a person does it today, and write down every point where something outside the agent changes. Phrases such as "handle the ticket", "process the claim" or "update the CRM" each hide several changes behind one verb. Split them until each line has one verb and one object, then decide line by line whether the agent gets a tool for it.

For the onboarding workflow above, the list comes out like this:

Step in the workflow What it changes Decision for the agent
Read the case and its documents Nothing Allowed, for cases the asking user can already open
Draft the next status and a reason Nothing until someone submits it Allowed, as a proposal a person reads
Move the case from verified to ready_for_provisioning status and status_reason on one case Allowed after a named operator approves, for 15 minutes, and only while the case is still verified
Correct identity, payment or compliance fields Regulated fields on the customer record No tool. A person does it in the existing screen
Close the case The case, plus a provisioning job in another system Not yet. The agent cannot confirm the provisioning job finished
Change alerting, audit or monitoring settings What the team watches the agent with No tool, and no credential that reaches them

The last three rows matter most. A field the agent should never touch is safest with no tool at all, rather than a tool with a rule against it. A rule can be misapplied by the code that enforces it, while a tool that does not exist cannot be called at all.

An action whose result the agent cannot confirm stays with a person until something independent can check it, as our guide on AI agent verification explains. In the onboarding list, closing the case waits until the provisioning job can be read back from the system that runs it, rather than taken from the agent's word.

Give the monitor no tool and no credential, even for an agent you trust, because an agent can read routine instructions as permission to silence it. OpenAI's misalignment report of 20 October 2026 has coding agents on internal tasks doing exactly that to the alerts watching them. An agent with no write path to the monitor cannot do it, whatever it concludes. Guardrails in the prompt cannot promise the same, because they rely on the same reading of instructions that went wrong.

Why give each action its own tool?

A tool that names one operation can carry its own rule. update_case_status, taking a case id, a target status and a reason, can be allowed for one status change and refused for every other, because the check can read each argument.

We do not give an agent a general tool such as run_sql or http_request, because it cannot be scoped like that. The argument decides the operation, so allowing the tool allows every statement its credential can run. That is the excessive functionality OWASP files under excessive agency, third in its 2026 Top 10 for LLM applications: the agent holds functions its task does not need.

We built Skionis on the opposite rule. Its agent applies changes to live AWS accounts, and the tools we gave it are its whole action set. They read account state, generate a fixed template format, validate it, draw an architecture diagram, and apply through CloudFormation change sets. There is no general shell, and no path by which a step in the plan becomes an arbitrary API call.

Solarpunk works across a leader's email, calendar, documents, CRM and ERP, and there each tool is a typed contract with declared inputs, outputs and side effects. The agent can act only through tools someone registered, and it cannot invent access it was not given. With more than a hundred registered tools, the list is still one a reviewer can read from top to bottom. Our guide on MCP tool design covers how large each tool should be.

Where should AI agent authorization run?

Authorization runs in code, at the tool layer, before the call leaves your process. It compares the request with the person who asked, the task, the target record and its current state, and with any approval the action needs, and it records the version of the rule it applied. A prompt telling the model to stay inside its permissions does not count, because the model can misread it and a prompt injection can argue against it.

Security engineers call this complete mediation: the system that holds the data decides on every request, rather than trusting whatever called it. AVOX, an insurance voice agent we built, puts that check in the tool contract. The model's output is a request to call a tool and never an action in itself, and each policy, claim, payment and endorsement tool carries its own permission check, required disclosures and escalation rule.

A request that fails any of those does not run. Nobody can promise that a model will always remember a check, but anyone can confirm that a tool will not run without one, by reading its code or by calling it with a request that should fail. That difference is why the check lives in the tool and not in the instructions the model is given.

Run the check against the record as it is now, rather than as the agent saw it when it planned. A plan can be several steps and several minutes old by the time the call happens, and the case may have been edited in between. We met this on Skionis with cloud accounts, where a template can pass schema validation and still be refused by AWS because of a quota, a region without the service, or a missing resource.

So the Skionis agent reads the live account before it plans, since only the account can say whether a change will apply. For a database record the same rule is simpler: compare the version the agent read with the current version when the call arrives, and refuse and plan again when they differ. A refusal there costs one more planning step, while a write against stale data can overwrite an edit a person made a minute earlier.

Should an AI agent have its own identity?

Yes, as long as it also carries the identity of the person it acts for. The permission it uses should be that person's, narrowed to the task. On a shared service account, the system the agent calls can see that the service connected, but it cannot see who asked, or whether that person could have made the change in the ordinary screen.

RFC 8693, the OAuth token exchange standard, names the two options. Under impersonation the agent is treated as the user and gets all of the user's rights, while under delegation it keeps its own identity and acts on the user's behalf. A delegated token records this in its act claim. The token's subject is the user, and the claim names the agent as the party acting now. For an agent that changes things, delegation is the version you can audit, because both names reach the system that records the change.

We build on token exchange because it exists today. NIST has opened a project on how to identify, authorize and audit AI agents, but it is a proposal, not a standard, and an agent shipping this quarter cannot wait for it.

On the telecom marketing platform we are building agents for now, the analytics agent reads through a data layer that applies the client's access rules. It sees only the tables, columns and rows that the asking user is entitled to, and personal data is masked or left out by the client's policy, rather than by an instruction in the prompt. In this phase of the work, every agent action is proposed by the agent and approved by a person.

Record who asked on the thing that changed, as well as in a log. Skionis tags every resource it creates with the owner, the environment, the tool that made it and the request behind it. Attribution that is not written at creation will not be pieced together later.

The tags pay off six months on, when someone has to decide whether a resource is safe to delete. When one agent hands work to another, the person who asked is still the one whose permission applies, and the second agent's identity shows which process sent the request, not who wanted the change. Our guide on prompt injection in multi-agent systems checks that at each hop, because a message from a trusted agent can carry text it only read.

How do AI agents handle authentication?

Through the tool layer, which attaches the credential when a tool runs, so the agent uses a capability without holding the credential behind it. Once a key is in the model's context, a prompt injection can ask for it, the run log can store it, and a later run can reuse it. Rotating the key closes the copy you found, but it does not tell you which calls used it. A credential the model never sees cannot leak by any of those routes.

Solarpunk runs as a desktop application rather than a hosted service. The credentials, the tool registry and execution all stay on the user's machine, and the model is called only as a reasoning service. Secrets live in an encrypted local vault and are injected into the tool adapter, the code that calls the outside system, when a tool runs, so they never enter the prompt.

The agent can then act inside an application where the user is signed in, and it drives that session without ever learning a password. We treat this as the condition for letting the agent act in a signed-in browser at all, since a password the model has seen can turn up in any later output.

The same split works on a server. Keep the long-lived secret in a broker. Have the tool layer issue a short-lived token for each run, scoped to the tools that run may call, and never pass the secret itself to the agent. Our guide on MCP authorization covers that token in detail, including why it is bound to one server.

Local MCP servers need a second look. The MCP authorization specification, as of its 28 July 2026 revision, uses OAuth 2.1 for servers reached over HTTP. It tells servers that run over stdio to read credentials from the environment instead. So a local server often starts with a long-lived key in an environment variable, on the same machine as the agent.

Run that process where the agent cannot read its environment, or put the key behind a broker. Our guide on AI agent sandboxing covers the network limits and stop rules around a broker. They matter for the case where the model tries a call it was never given a tool for.

When is this more than you need?

An assistant that only reads, over data the asking user could already open, needs that user's entitlements and little else, because nothing changes and there is nothing to approve. Check those entitlements in code all the same. An agent that reads through a shared service account can show one user another user's records without anything looking wrong.

A prototype that runs against a copy of the data, with no production credential anywhere in reach, can leave this exercise until it gets near real systems. Do it the first time a tool would change a record that another person or system depends on, and from then on the list grows one line at a time.

Each line raises a second question: does a person still approve it, and what would let you stop asking them? That is the subject of our guide on human in the loop AI agents. Our guide on AI agent governance covers moving one action at a time to less oversight, and the evidence each move needs.

Common questions

What are AI agent permissions?

AI agent permissions are the actions an agent may take on other systems. Write each one as a verb, an object and the conditions for the change. A usable permission names the field that changes, the states that allow it, and the tenant and environment. It also names who must approve it, if anyone, and for how long. "Manage the account" is not a permission, because it hides several changes behind one word.

What authorization does an AI agent need before it acts?

A check in code at the tool layer, before the call leaves your process. It compares the request with the person who asked, the target record and its current state, and any approval the action needs. Then it records the version of the rule it applied. A prompt telling the model to stay inside its permissions does not count, because a prompt injection can argue against it.

How do AI agents handle authentication?

Through the tool layer, which attaches the credential when a tool runs, so the model never reads it. Keep the long-lived secret in a vault or broker and give each run a short-lived token scoped to the tools it may call. Remote MCP servers use OAuth 2.1 over HTTP. Local stdio servers read credentials from the environment, so run those where the agent cannot read it.

Should an AI agent have its own identity?

Yes, alongside the identity of the person it acts for. Under OAuth token exchange, RFC 8693, a delegated token keeps the user as its subject and names the agent in an act claim. The system that records the change then sees both. A shared service account shows only that the service connected, not who asked or whether they could have made the change themselves.

Is an OAuth scope enough to limit what an agent does?

Not on its own. A scope such as files:write says what an application may do at a server. It does not say which record may change, which state change is allowed, or which person the change is for. Those checks belong in the tool layer, in code, before the call runs, against the current state of the record.

Why not approve the whole agent?

The agent's tools, models and workflow paths change after the approval, and an approval of the agent covers every change that arrives later. Approving one action keeps the decision attached to a consequence someone has already read. Security, product and operations can each object to a specific part of it, such as the target, the time limit or the approver.

Further reading


Originally published on bigcircle.ai. I'm Tirth, founder of BigCircle, where we build production AI systems with governance built in.

Top comments (0)