9 min read
AI agent permissions, tool scopes and audit trails
An agent's blast radius is the sum of everything it is allowed to call. Here is how to scope permissions per tool, keep credentials narrow and short-lived, and record an audit trail that answers who asked, what ran, and what changed.
AI agent permissions should be scoped per tool, not per agent: each tool gets the narrowest credential that lets it work, writes are separated from reads, and every action is recorded with who asked, what ran, and what changed. That combination limits the blast radius of a bad decision and gives you an audit trail you can defend.
This article is the implementation companion to securing agents in the most dangerous period of digital evolution, which lays out the threat model: prompt injection, tool abuse, excessive agency, identity, memory poisoning, and supply chain. Here the focus is narrower and more practical: how to design identities, scopes, runtime checks, and logs so that when an agent is manipulated or simply wrong, the damage stays small and the record stays clear.
Why agent permissions sprawl
Scoping permissions properly is tedious, and agents are usually built under demo pressure. The fastest path is one service account or one API key with broad access, shared by every user and every tool. It works on the first day and stays in place, because tightening it later means touching every integration.
Third-party platforms add to the problem. Many software-as-a-service scopes are coarse: a single write scope may cover every field on every contact. The agent needs to update two fields on one record type, but the credential allows far more. Unless your own code narrows that access, the platform's scope becomes the agent's effective permission.
Finally, agents change over time. A new tool is added for one workflow and becomes available to all of them. Permissions that were reasonable at launch quietly widen.
What teams often get wrong
- A shared machine identity. If every action runs as the same service account, logs cannot say which user or which agent run caused a change.
- Prompts as policy. Instructions such as "only update the email field" guide the model; they do not stop a manipulated call. Policy must be enforced in the code that executes the tool.
- Scoping at connection time only. Checking permissions when an account is connected, but not when each tool is called, misses revoked access, cancelled runs, and changed entitlements.
- Every tool for every run. Offering the full tool list to each run, regardless of what the user has connected or needs, widens the attack surface for no benefit.
- Long-lived plain-text tokens. Stored unencrypted, or reused across users, a leaked token becomes a standing breach.
- Logs that record too little or too much. Missing actor and arguments make incidents unexplainable; logging full secrets or personal data creates a new liability.
A practical architecture for AI agent permissions
Think in layers. Each layer narrows what the one above it allows.
Identity: user, agent, and run
Every action should be attributable to three things: the person or system on whose behalf it ran, the agent that performed it, and the specific run. Use delegated authorization, typically OAuth, so the agent acts with the user's own granted access rather than a global key, and give each agent its own machine identity where the platform supports it.
Scopes: request the minimum
Request the narrowest scopes each connector offers, and prefer read-only connections for agents that only need to look things up. If a workflow needs both reading and writing, consider whether writes can be staged in your own system and applied separately, so the agent's connection never needs the broad write scope.
Tool policy: narrow what the platform allows
Where platform scopes are coarse, enforce finer rules in the tool itself: allowlisted objects, allowlisted fields, value ranges, allowed target identifiers, and limits on batch size. Validate the model's arguments against a typed schema before any request leaves your server. Offer each run only the tools it needs, filtered by what the user has connected and is entitled to.
Runtime checks: verify on every step
Before each reasoning step and each tool call, confirm that the run has not been cancelled, the user is still entitled to the agent, and the target belongs to the user. Revoked access should take effect on the next call, not the next deployment.
Approvals for irreversible actions
Payments, outbound messages, deletions, and permission changes should require an approval stored as a durable record. The design of those gates is covered in human-in-the-loop agents.
Credentials: encrypted, short-lived, bound
Encrypt stored tokens, bind them to the user they belong to, refresh them rather than extending their life, and delete them on disconnect. For agent runs that call your own services, issue per-run credentials that expire and are bound to one user and one run, and store only their hash.
Designing the audit trail
An audit trail is useful when it can answer an incident question without guesswork: who asked for this, what did the agent see, what did it call, what changed, and who approved it. Design it as an append-only, ordered log per run. Each event should carry:
- A sequence number written in the same transaction as the event, so order is never ambiguous.
- The user, agent, and run identifiers.
- The event type, such as step started, tool called, tool completed, approval requested, approval granted, failed, or cancelled.
- The tool name and either the arguments or a redacted or hashed form of them, depending on sensitivity.
- The outcome and, for writes, the identifier of the record changed.
- A reference to the approval record when one was required.
Keep secrets out of the log entirely, minimize personal data, and set a retention period that matches your legal and contractual obligations. For regulated contexts, have the retention and access rules reviewed by someone qualified in the relevant law.
Implementation considerations
- OAuth hygiene: use a random, single-use state value with a short expiry for every authorization flow, verify callback signatures where the platform provides them, and compare signatures in constant time.
- Service-to-service calls: when a queue or scheduler invokes a worker, verify the caller's signed identity token and the expected service account, not just a shared header.
- Tool-call ledger: record each write before executing it, so a retry can detect an uncertain outcome and ask for verification instead of repeating it.
- Revocation: make disconnecting an account delete its tokens and remove its tools from new runs immediately.
- Sandboxing: run code execution and browsing in isolated environments with limited network egress.
- Review cadence: periodically compare each agent's granted scopes and tools against what it actually used, and remove the difference.
Trade-offs
Fine-grained permissions reduce blast radius and increase build time and connector complexity. Per-user delegated access gives clean attribution but depends on every platform supporting it well; some force a shared integration account, which your own logs must compensate for.
Logging full arguments makes incidents easy to reconstruct and creates a store of sensitive data. Hashing or redacting arguments protects that data but can make investigations slower. Many teams log full arguments for writes and approvals, and minimal detail for reads.
Short-lived credentials limit exposure and add refresh logic and failure modes. For high-value connections, that cost is worth paying.
Lessons from ImadDhin work
These are code-level observations from the Agent workspace in this portal, not client outcomes.
- Tools follow connections. Each run is offered commerce or CRM tools only when the user has connected that provider; everything else is filtered out before the model sees the tool list.
- Writes are narrowed in code. CRM writes are limited to a short allowlist of contact and deal fields, and cart identifiers are only accepted if they were created in the same account and run.
- Checks run on every step. Before each reasoning step and each tool call, the runtime confirms the run is not cancelled and the user's entitlement to the agent is still approved.
- Credentials are sealed and short-lived. Connector tokens are encrypted per user; OAuth state values are random, single-use, consumed in a transaction, and expire quickly; store callbacks are verified with a constant-time signature comparison; per-run tool credentials are stored only as hashes and expire soon after the run.
- The worker verifies its caller. The background worker accepts jobs only with a verified identity token from the expected service account.
- Events are ordered. Every run writes a sequenced event log, with each sequence number assigned in the same transaction as the event, and gated writes carry an approval record with their exact arguments.
- Let the credential match the job. Code-level gates can compensate for a coarse platform scope, but they are a second line of defense. A common finding in agent reviews is a connection that requests both read and write scopes even when some agents only research. Offering a separate read-only connection for research-only agents narrows the credential itself, so the gate is not the only thing between a manipulated run and a write.
Common mistakes to test for
- Remove a user's entitlement mid-run and confirm the next tool call fails.
- Disconnect an account and confirm its tools disappear from new runs and its tokens are deleted.
- Try to write a field outside the allowlist and confirm rejection before any external request.
- Reuse an OAuth state value, or use an expired one, and confirm the flow fails.
- Call the worker without a valid identity token and confirm it refuses.
- Reconstruct a past run from the audit log alone: who asked, what was called, what changed, and who approved.
When a simpler solution is better
If an agent only answers questions from public or internal documents and calls no tools that change anything, a read-only design with a single scoped search credential is enough. If a task is fully predictable, a scheduled script with a fixed service account and a fixed query is easier to secure than an agent. Add delegated identities, per-tool policy, and detailed audit trails when the agent acts on real records for real users.
Make the blast radius small and the record clear
Scope per tool, check on every step, keep credentials narrow and short-lived, and log what an investigator would need. If you want a permissions and audit review of an agent you already run, see AI agent development, request it through the project brief, or walk through your tool scopes in a 30-minute call.
Frequently asked questions
What does least privilege mean for AI agents?
Each tool gets the narrowest credential and the smallest set of allowed objects, fields, and values that lets it do its job, and each run is offered only the tools it needs. The agent's effective permission is the union of its tools, so every tool is scoped individually.
Should an AI agent use its own identity or the user's?
Ideally both: delegated user authorization so the agent acts within the user's own access, plus a distinct agent identity and run identifier so every action is attributable. Avoid one shared service account for everything.
What should an agent audit trail record?
An ordered, append-only log per run with user, agent, and run identifiers, event types, tool names, arguments or a redacted form of them, outcomes, changed record identifiers, and references to approvals. Keep secrets out and minimize personal data.
Are OAuth scopes enough to restrict an agent?
Often not, because many platform scopes are coarse. Enforce finer limits in your tool code, such as allowlisted fields and value ranges, and validate arguments before any request leaves your server.
How is this different from securing agents against prompt injection?
Prompt injection cannot be fully prevented, so permissions and audit trails are the containment layer: they limit what a manipulated agent can do and make any misuse visible and explainable afterward.
Review what your agents can actually do
Walk through your agents' tools, scopes, and approval gates.
Book a 30-minute callPer-tool scoping, sealed credentials, ordered audit logs, and approval gates.
See AI agent developmentMap where an agent's blast radius is larger than intended.
Request a permissions reviewKeep reading
Securing agents in the most dangerous period of digital evolution
An agent is a system that reads untrusted text and then takes real actions. That combination is new, and most of the controls teams rely on were never designed for it.
Human-in-the-loop AI agents: approval steps that don't kill the return on investment
Approval steps protect trust in an agent, but applied to everything they erase the time it was meant to save. Here is how to gate only the actions that need a person, and how to design the approval itself.
MCP server development: when your product needs one and how to ship it safely
An MCP server turns your product's capabilities into tools that AI agents can call. Here is when that is worth building, when a simpler integration is enough, and how to ship one without handing agents more access than they need.
AI agent evaluation before production: a practical evaluation harness
An agent that looked good in five demo conversations can still fail on the sixth real one. A small, repeatable evaluation harness turns quality from an impression into a report you can rerun on every change.