Geodocs.dev

Agent Permission Model Specification: RBAC, Scopes, and Tool-Level Auth

ShareLinkedIn

Open this article in your favorite AI assistant for deeper analysis, summaries, or follow-up questions.

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

  1. Least privilege. Default deny. Each tool requires an explicit scope.
  2. Identity per agent. Agents are first-class principals with a stable ID.
  3. On-behalf-of. Every agent action carries the originating user's principal.
  4. Time-bound. Grants expire; long-lived tokens are an anti-pattern.
  5. Human-in-the-loop for risk. Sensitive writes require explicit consent.
  6. Auditability. Every action is traceable end-to-end.

Identity model

An agent has three identity layers:

LayerPurposeExample
Service identityStable identity for the agent itselfagent:geodocs-writer@stelixx
PrincipalThe human who delegated the actionuser:alex@stelixx
SessionA bounded run with its own token + traceable lifetimesession: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:

  1. Resolve the principal and session from the token.
  2. Check that the tool is enabled for this agent and role.
  3. Apply per-tool ABAC predicates (e.g., resource.tenant == principal.tenant).
  4. Require fresh consent if the tool is marked requires_consent.
  5. Record the decision in the audit log before invoking the tool.

Deny-by-default is mandatory. A missing predicate is treated as deny.

Consent UI must distinguish three risk classes:

ClassTriggerConsent UX
LowRead non-sensitiveImplicit at agent install
MediumWrite to a single resourcePer-action confirmation
HighBulk write, delete, money movementPer-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:

  1. The agent runtime presents the principal's token (or a derived token) to the MCP server.
  2. The server enforces its own scope checks before invoking the tool.
  3. The server returns a permission_denied error for missing scopes; the agent never silently degrades.
  4. 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: high

Validation 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.

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

specification

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.

specification

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.

specification

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.

Stay Updated

GEO & AI Search Insights

New articles, framework updates, and industry analysis. No spam, unsubscribe anytime.