Agent Permission Model Specification: RBAC, Scopes, and Tool-Level Auth
AI agents act on behalf of users and must be authorized as carefully as humans. This specification defines roles, OAuth scope mapping, per-tool authorization, consent prompts, time-bound grants, and MCP permission propagation so an agent never exceeds the principal's least-privilege boundary.
TL;DR
Give each agent an identity, a role, and a token issued via OAuth 2.0 with the smallest set of scopes the workload needs. Authorize at the tool level, not just the integration level. Require explicit consent for write tools and any read tool that touches sensitive data. Make every grant time-bound, attribute every action to a human principal, and write the full chain to an immutable audit log.
Why an agent permission spec exists
A general OAuth scope like read:all is too coarse for agents that loop over many tools. Without per-tool authorization, a single compromised prompt can exfiltrate data, send messages, or move money. RFC 6749 defines scopes (RFC 6749), and RFC 8693 defines token exchange for on-behalf-of patterns (RFC 8693); this spec wires them into the agent loop so production agents inherit the same controls a human user has.
Core principles
- Least privilege. Default deny. Each tool requires an explicit scope.
- Identity per agent. Agents are first-class principals with a stable ID.
- On-behalf-of. Every agent action carries the originating user's principal.
- Time-bound. Grants expire; long-lived tokens are an anti-pattern.
- Human-in-the-loop for risk. Sensitive writes require explicit consent.
- Auditability. Every action is traceable end-to-end.
Identity model
An agent has three identity layers:
| Layer | Purpose | Example |
|---|---|---|
| Service identity | Stable identity for the agent itself | agent:geodocs-writer@stelixx |
| Principal | The human who delegated the action | user:alex@stelixx |
| Session | A bounded run with its own token + traceable lifetime | session:run_2026-05-03_8a1c |
Tokens issued to an agent always include claims for all three layers so downstream services can enforce policy on any of them.
RBAC for agents
Roles define a permission bundle. Default agent roles include:
- agent.reader — read-only access to non-sensitive data.
- agent.editor — read + write to declared resources, no destructive actions.
- agent.admin — destructive actions (delete, archive); reserved for explicit elevation.
- agent.billing — anything that moves money; always requires per-action consent.
Roles compose. An agent's effective permissions are the intersection of its role set and the principal's role set; the agent never exceeds what the principal can do.
OAuth scope mapping
Each tool declares the scopes it requires:
{
"tool": "slack.sendMessage",
"required_scopes": ["chat:write", "channels:write"],
"requires_consent": true,
"data_classification": "internal"
}At agent boot, the runtime computes the union of scopes across registered tools, requests them from the OAuth provider, and rejects any tool whose scope is missing from the issued token. Scope grants are stored in the agent's manifest, not the prompt.
Tool-level authorization
Beyond scopes, each tool call is authorized at runtime:
- Resolve the principal and session from the token.
- Check that the tool is enabled for this agent and role.
- Apply per-tool ABAC predicates (e.g., resource.tenant == principal.tenant).
- Require fresh consent if the tool is marked requires_consent.
- Record the decision in the audit log before invoking the tool.
Deny-by-default is mandatory. A missing predicate is treated as deny.
Consent prompts
Consent UI must distinguish three risk classes:
| Class | Trigger | Consent UX |
|---|---|---|
| Low | Read non-sensitive | Implicit at agent install |
| Medium | Write to a single resource | Per-action confirmation |
| High | Bulk write, delete, money movement | Per-action + reason capture |
For agents that run unattended (background workflows), High actions must be pre-approved via a written policy, not via inline consent. Anthropic and OpenAI both document patterns for human-in-the-loop confirmation as part of tool use (Anthropic tool use; OpenAI function calling).
Time-bound grants
- Default token lifetime: short (typically minutes to a few hours).
- Refresh tokens scoped per-agent, per-principal.
- Elevations expire; an agent.admin grant should auto-revert to agent.editor after the session ends.
- Any grant longer than 24 hours requires a documented justification on the policy page.
Treat exact lifetime numbers as policy decisions for your environment; the principle is that no token should outlive the workflow it authorizes.
Multi-user delegation
When one agent acts for many users (e.g., a shared workspace assistant):
- Maintain a separate token per principal; never share tokens.
- Use OAuth 2.0 token exchange (RFC 8693) to derive per-user tokens from a parent service identity.
- Stamp every action with both the agent identity and the on-behalf-of principal.
- Deny any action where the resource does not belong to the on-behalf-of principal.
MCP permission propagation
In a Model Context Protocol server, propagate permissions explicitly:
- The agent runtime presents the principal's token (or a derived token) to the MCP server.
- The server enforces its own scope checks before invoking the tool.
- The server returns a permission_denied error for missing scopes; the agent never silently degrades.
- The server logs the principal, session, tool, and decision in the audit trail.
MCP itself standardizes the tool surface but treats authorization as a host responsibility (MCP specification).
Audit log integration
Audit records are append-only and include at minimum:
{
"timestamp": "2026-05-03T08:00:00Z",
"agent": "geodocs-writer",
"principal": "alex@stelixx",
"session": "run_2026-05-03_8a1c",
"tool": "notion.updatePage",
"resource": "page:1234",
"scopes": ["pages:write"],
"decision": "allow",
"reason": "role agent.editor + tenant match"
}Decision: allow, deny, or consent_required. Records are streamed to a tamper-evident store and surfaced in the trace UI alongside spans (see the related trace instrumentation spec).
Policy example
agent: geodocs-writer
roles: [agent.editor]
tools:
notion.updatePage:
required_scopes: [pages:write]
abac:
- resource.workspace == principal.workspace
requires_consent: false
slack.sendMessage:
required_scopes: [chat:write]
abac:
- target.channel in principal.allowed_channels
requires_consent: true
payments.refund:
required_scopes: [payments:write]
abac:
- resource.amount <= principal.refund_limit
requires_consent: true
risk_class: highValidation checklist
- [ ] Each tool declares required scopes.
- [ ] Default policy is deny.
- [ ] Tokens carry agent + principal + session claims.
- [ ] Consent UX matches risk class.
- [ ] Grants expire automatically.
- [ ] Audit log is append-only.
- [ ] Cross-tenant access is rejected at the predicate layer, not relied on UI to suppress.
FAQ
Q: Should an agent ever hold a long-lived admin token?
No. Use short-lived tokens with refresh and require elevation per session. Admin grants longer than a session are a major incident vector.
Q: Can agents share tokens to save round trips?
No. Token sharing breaks attribution and consent. Use token exchange to derive per-principal tokens from a service identity.
Q: What if a tool needs a scope the principal does not have?
Reject the action with a clear error. Never silently substitute a different scope or fall back to a service token.
Q: How do consent prompts work for unattended agents?
Replace inline consent with a written policy that pre-approves the action class. The policy itself is reviewed and signed off through your normal change-management process.
Q: How do permissions interact with retrieval?
Apply ACL filters at retrieval time using the principal's identity. The agent must not see chunks the principal cannot see, even if the index contains them.
Related Articles
Agent Knowledge Base Specification: Structure, Refresh, and Versioning
Production specification for AI agent knowledge bases: document model, chunking strategies, metadata enrichment, refresh cadence, version pinning, and rollback.
Agent Memory Pattern Specification: Short-Term, Long-Term, and Episodic
Specification for AI agent memory: working, episodic, semantic, and procedural tiers with consolidation, eviction, and PII handling.
Agent Tool Naming Conventions Specification for LLM Routing Reliability
Specification for naming AI agent tools to maximize LLM routing reliability: verb-noun, namespaces, length, anti-collision, and deprecation rules.