The Permission Problem
When you deploy an AI agent, you make authorization decisions upfront: what data can it read, what services can it call, what actions can it take? Most teams make these decisions at deployment time, for the entire lifetime of the agent deployment. They grant broad access because it's convenient, and because agents are designed to be general-purpose — you don't always know in advance exactly what they'll need to do.
This creates the confused deputy problem at scale. The agent holds permissions not because it currently needs them, but because it might need them at some point. When that agent is compromised via prompt injection, behavioral manipulation, or an unexpected interaction with a malicious data source, the attacker gains all the permissions the agent holds — not just the permissions needed for the specific task the agent was doing when it was compromised.
The permission problem has two dimensions: scope (what can the agent do) and duration (how long can it do it). Both are typically over-provisioned. An agent given permanent read/write access to a user's file system for a task that required reading two documents has been over-provisioned in both dimensions. The right access would have been: read access to two specific documents, for the duration of one task. The difference between these two permission profiles is enormous from a security standpoint.
Current State: Everything Is Over-Permissioned
The current state of agentic authorization is largely a reflection of developer convenience. Configuring fine-grained per-task permissions is hard work. It requires knowing in advance what the agent will need, designing permission request flows, building UX for users to review and approve permissions, and implementing revocation. Most teams skip this and grant broad access instead.
An agent deployed to help a user with scheduling was given access to: the user's calendar (read/write), their email (read/write), their Slack (read/write), and a set of internal databases (read). Intended use: find a meeting time and send an invite. Actual attack surface: any successful prompt injection against this agent can now read all the user's emails, exfiltrate database contents to an external address via email, post any content to Slack, and corrupt calendar entries. The over-permissioning transformed a scheduling assistant into a surveillance platform.
The convenience argument — "we need broad access because we don't know what the agent will need" — is a symptom of building agentic systems without designing their authorization model. The solution is not to accept over-permissioning as inevitable, but to architect agents so they request permissions at the point of use, not at deployment time.
Principle of Least Privilege for Agents
Least privilege for agentic systems means: an agent should hold exactly the permissions it needs for the specific action it is about to take, for no longer than it needs them. This is a different framing than traditional least privilege, which is typically applied to service accounts and APIs. For agents, it has to be applied dynamically — because an agent performing a multi-step task may need different permissions at different points in that task.
Concretely, this means separating three categories of permission: read-only permissions for reconnaissance and planning phases; write permissions that are explicitly requested and approved for specific actions; and elevated permissions (admin, external communication) that require explicit human confirmation before execution. The agent should never hold write permissions during phases where it is only reading, and should never hold permissions for resources it has already finished using.
Instead of deploying an agent with permanent access to all resources, issue task-specific capability tokens at task start. The token specifies exactly which resources can be accessed, what operations are permitted (read/write/delete), and a TTL after which the token expires. The agent presents this token to each tool/service it calls. When the task completes, revoke the token immediately. Leaked tokens are bounded in scope and time; they cannot be used to access resources outside the token specification.
Dynamic Permission Requests
The most important architectural shift for agentic authorization is moving permission requests from deployment time to action time. Rather than configuring permissions when the agent is deployed, the agent requests permissions at the moment it decides it needs them — and the user sees and approves exactly what the agent is about to do.
This model requires investment in UX that most teams haven't built yet. When an agent wants to send an email, it should present the user with: the exact email it intends to send (to, subject, body), the specific permission it is requesting (one-time access to the email send API), and a clear approve/deny UI. This is not a generic "grant email access" permission request — it is a specific, reviewable, one-time action approval.
# Dynamic permission request — action-time pattern # At task execution, agent requests specific capability const permission = await requestUserPermission({ action: "send_email", scope: { to: "team@company.com", subject: "Meeting notes from today", body: emailDraft, // user sees exact content }, ttl: "once", // single use, not persistent context: "User asked me to send meeting summary", }); if (permission.approved) { await emailTool.send(permission.capability); } else { // log denial, abort action, continue task differently } # Compare to over-permissioned deployment-time grant: // agent.permissions = ["email:*", "files:*", "slack:*"] // granted forever, no per-action review, no audit trail
Authorization Patterns
Several architectural patterns from existing authorization infrastructure can be adapted for agentic systems. None are perfect fits — agentic authorization requirements are genuinely novel — but they provide useful building blocks.
PKCE-style flows for agents: adapt the OAuth PKCE flow for agent authorization. The agent generates a code challenge, the user approves specific scoped permissions in an out-of-band review step, and the agent receives a short-lived access token scoped to exactly the approved actions. The code verifier prevents the token from being useful if intercepted, and the short TTL limits the window for misuse.
Capability tokens: rather than issuing broad OAuth scopes ("email:send"), issue capability tokens that encode the specific action parameters. The token is cryptographically bound to the exact action: "send email to X with subject Y with body Z, valid for 5 minutes." An agent that presents this token to the email service can only send that exact email — it cannot be reused, cannot be redirected, and cannot be escalated to broader access.
The MCP authorization spec is an emerging standard that addresses some of these requirements for tool-calling agents specifically. It defines flows for agents to request and receive scoped access to MCP servers, with user-facing approval UI baked into the protocol. Teams building on MCP should treat the authorization spec as a minimum baseline, not an optional feature.
The Audit Trail Requirement
Authorization decisions are only as good as your ability to reconstruct them after the fact. Every permission use by an agent must be logged with sufficient context to answer: why did the agent request this permission, what task was it performing, what data did it access, and what did it do with that access? Without this audit trail, you cannot investigate anomalous behavior, cannot reconstruct attack timelines, and cannot comply with data access regulations that require demonstrating data minimization.
The audit log entry for each agent action should include: the task identifier and description, the permission requested and the resource accessed, the timestamp and duration of access, the output of the action (or a hash of it), and the user identity under whose authority the action was taken. This log should be append-only and tamper-evident — if an attacker successfully compromises an agent, one of their objectives will often be covering their tracks by modifying or deleting audit logs.
Audit trails also enable a capability that most teams don't exploit: anomaly detection over permission usage patterns. An agent that normally uses read permissions on three specific tables but suddenly reads twenty tables, or that has never used an email permission before and suddenly sends ten emails in one task, is exhibiting behavior worth investigating. Correlating permission usage patterns across tasks over time turns your audit trail from a forensic record into a real-time detection capability.