Fine-Grained Authorization for AI Agents
Rate limits, domain restrictions, and delegation depth—right in your OAuth tokens
Stop building custom authorization middleware for every agent. AAP gives you structured JWT claims for capabilities (with constraints), task binding, delegation tracking, and oversight requirements. Works with any OAuth 2.0 Authorization Server.
Why AAP?
OAuth 2.0 wasn't designed for agents that act autonomously
Agents get too much access
OAuth scopes like "read:web" or "write:cms" are too broad. You can't express "search only these domains" or "create drafts but don't publish." So you either block agents entirely or give them dangerous privileges.
No way to track intent
When an agent gets a token, you can't tell what task it's for. Is this web search for customer research or competitive intelligence? Without purpose binding, there's no way to prevent "purpose drift" or audit why an action happened.
Delegation creates black holes
Your agent calls a tool. That tool calls another tool. Three layers deep, who's actually responsible? Without delegation tracking, you lose visibility into privilege chains and can't enforce "no re-delegation" policies.
Impossible audit trails
When something goes wrong, can you trace it back to the specific agent, task, and authorization? With standard OAuth, the answer is usually "maybe" or "we think so." That's not good enough for regulated industries.
Valid actions, wrong context
An agent has permission to delete files. It deletes your production database. Technically authorized, catastrophically wrong. Without constraints like time windows or domain restrictions, you can't prevent abuse.
Rate limits? Good luck.
Try implementing "this agent can make 50 requests per hour to these domains only" with OAuth scopes. You'll end up with brittle, custom middleware that breaks every time you add a new agent.
How AAP Solves This
Five structured claims that make agent authorization actually work
Know exactly which agent did what
The `aap_agent` claim includes agent ID, type (LLM, bot, scripted), operator organization, and runtime environment. No more "some agent somewhere" in your logs—every action is traceable to a specific identity.
{
"aap_agent": {
"id": "agent-researcher-01",
"type": "llm-autonomous",
"operator": "org:blogcorp",
"model": "gpt-4",
"runtime_context": {
"environment": "production",
"version": "1.2.0"
}
}
}Capabilities with teeth
Each `aap_capabilities` entry specifies an exact action ("search.web", "cms.publish") plus server-side enforceable constraints: allowed domains, rate limits, time windows. The agent can't tamper with these—they're validated by your Resource Server.
{
"aap_capabilities": [
{
"action": "search.web",
"constraints": {
"domains_allowed": ["example.org", "wikipedia.org"],
"max_requests_per_hour": 50,
"time_window": {
"start": "2025-01-01T00:00:00Z",
"end": "2025-01-31T23:59:59Z"
}
}
},
{
"action": "cms.draft",
"constraints": {
"max_drafts_per_day": 10
}
}
]
}Bind tokens to tasks
The `aap_task` claim links the token to a specific task ID and declared purpose. This prevents "I got this token for research but I'll use it to delete production data." Your Resource Server can reject requests that don't match the task context.
{
"aap_task": {
"id": "task-123",
"purpose": "research_and_draft_article",
"data_sensitivity": "public",
"context": {
"topic": "OAuth for AI agents",
"target_audience": "developers"
}
}
}See the full delegation chain
The `aap_delegation` claim tracks every hop in the delegation chain with depth limits. Agent A delegates to Tool B, which delegates to Service C—you see the full path. Enforcing "max 2 delegation hops" becomes trivial.
{
"aap_delegation": {
"depth": 1,
"max_depth": 2,
"chain": [
{
"sub": "spiffe://example.com/agent/main",
"delegated_at": 1735686000
}
]
},
"act": {
"sub": "spiffe://example.com/agent/main"
}
}Require human approval
The `aap_oversight` claim lists actions that need human approval before execution. Your agent can create drafts all day, but publishing requires a human to click "yes." Build approval workflows directly into your authorization layer.
{
"aap_oversight": {
"requires_human_approval_for": [
"cms.publish",
"payment.execute"
],
"approval_workflow": {
"type": "slack_channel",
"channel_id": "C1234567890"
}
}
}100% compatible with OAuth 2.0
AAP isn't a replacement—it's an extension. Use standard Client Credentials flow, Token Exchange (RFC 8693), DPoP for proof-of-possession, and mTLS for transport security. Your existing OAuth infrastructure just works.
# Client Credentials Flow
POST /token HTTP/1.1
Host: as.example.com
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials
&client_id=agent-researcher-01
&client_secret=...
&scope=aap:research
# Token Exchange for delegation
POST /token HTTP/1.1
grant_type=urn:ietf:params:oauth:grant-type:token-exchange
&subject_token=...
&requested_token_type=urn:ietf:params:oauth:token-type:access_tokenHow It Works
Six steps from policy to audit trail
Operator defines what agents can do
Before any agent gets a token, you configure policies in your Authorization Server: which capabilities, what constraints, which actions need approval.
Agent authenticates
The agent proves its identity using Client Credentials with mTLS (certificate-based) or client secret.
AS issues JWT with AAP claims
The Authorization Server issues a standard JWT containing OAuth claims (iss, sub, aud, exp) plus AAP claims (aap_agent, aap_capabilities, aap_task, aap_oversight, aap_delegation).
Agent calls Resource Server
The agent includes the token in the Authorization header. If DPoP or mTLS is required, the agent includes a cryptographic proof that it controls the token.
RS validates everything
The Resource Server validates: signature, expiry, audience, proof-of-possession, capability match for the requested action, constraint compliance (rate limits, domains, time windows), delegation depth, and oversight requirements.
Every action is logged
Authorized requests are executed and logged with trace IDs linking agent identity, task ID, action performed, and result. Denied requests are logged with the specific failure reason.
Use Cases
Real-world scenarios where AAP adds value
Scenario
An autonomous agent gathers information from multiple web sources to generate a report.
Challenges
- Needs access to search and scraping APIs
- Must be limited to trusted domains to prevent data exfiltration
- Requires rate limiting to avoid getting blocked or abusing APIs
- Purpose must be auditable for compliance
AAP Solution
- "search.web" capability with domains_allowed: ["example.org", "wikipedia.org"] and max_requests_per_hour: 50
- Task binding with purpose: "research_for_quarterly_report" and task.id linking to your project management system
- Delegation tracking if the agent calls external tools (translation, sentiment analysis)
- Full audit trail: every search logged with agent ID, task ID, timestamp, and target URL
Why Teams Choose AAP
Security, compliance, and operational benefits
Security
Prevent agent impersonation
With mTLS or DPoP, only the agent with the private key can use the token. Token theft from logs or network capture becomes useless without the corresponding proof.
Block capability escalation
Constraints are enforced server-side. Even if an agent is compromised, it can't modify its own rate limits, allowed domains, or action permissions.
Catch purpose drift early
Task binding lets you reject requests that are technically authorized but contextually wrong—like using a "customer support" token to delete database records.
Control delegation sprawl
Depth limits prevent agents from excessively delegating. Permission reduction at each hop ensures delegated tokens never gain privileges.
Compliance
Audit trails that actually work
Every action links to: agent ID, operator, task purpose, capability used, timestamp, and result. When auditors ask "who did this?", you have a real answer.
GDPR-aware by design
task.data_sensitivity (public/internal/confidential/personal) lets you enforce data handling policies at the authorization layer, not just app logic.
Built-in approval workflows
Oversight claims integrate human approval into authorization. High-risk actions (publishing, payments) require explicit human confirmation before execution.
Data minimization in tokens
AAP tokens include only necessary claims. No user emails, full names, or sensitive context—just IDs and references.
Operational
Rate limiting that scales
Define per-capability rate limits once in your Authorization Server. Every Resource Server enforces them consistently without custom middleware.
No vendor lock-in
Built on OAuth 2.0, JWT, and IETF standards. Works with any OAuth library, JWT validator, or identity provider that supports custom claims.
Incremental adoption
Start with one agent and one Resource Server. AAP tokens work alongside traditional OAuth scopes—no need to migrate everything at once.
Interoperates with existing identity
Use OIDC for human identity, SPIFFE for workload identity, or any sub format. AAP doesn't replace your identity layer—it extends it.
AAP Token Example
A complete JWT with all five AAP claims—ready to validate
1 { 2 "iss": "https://as.example.com", 3 "sub": "spiffe://example.com/agent/researcher-01", 4 "aud": ["https://api.example.com"], 5 "exp": 1735689600, 6 "iat": 1735686000, 7 "jti": "unique-token-id-abc123", 8 9 "aap_agent": { 10 "id": "agent-researcher-01", 11 "type": "llm-autonomous", 12 "operator": "org:blogcorp", 13 "model": "gpt-4", 14 "runtime_context": { 15 "environment": "production", 16 "version": "1.2.0" 17 } 18 }, 19 20 "aap_task": { 21 "id": "task-123", 22 "purpose": "research_and_draft_article", 23 "data_sensitivity": "public", 24 "context": { 25 "topic": "OAuth for AI agents", 26 "target_audience": "developers" 27 } 28 }, 29 30 "aap_capabilities": [ 31 { 32 "action": "search.web", 33 "constraints": { 34 "domains_allowed": ["example.org", "wikipedia.org"], 35 "max_requests_per_hour": 50 36 } 37 }, 38 { 39 "action": "cms.draft", 40 "constraints": { 41 "max_drafts_per_day": 10 42 } 43 } 44 ], 45 46 "aap_oversight": { 47 "requires_human_approval_for": ["cms.publish"], 48 "approval_workflow": { 49 "type": "slack_channel", 50 "channel_id": "C1234567890" 51 } 52 }, 53 54 "aap_delegation": { 55 "depth": 0, 56 "max_depth": 2 57 } 58 }
AAP Claims Reference
- iss
- Issuer: Authorization Server that issued the token
- sub
- Subject: Agent identity (SPIFFE ID)
- aud
- Audience: Authorized Resource Servers
- exp
- Expiry: Expiration timestamp (short tokens recommended)
- iat
- Issued At: Issuance timestamp
- jti
- JWT ID: Unique token identifier (for revocation)
- aap_agent
- Explicit agent identity with type, operator, and context
- aap_task
- Task binding with purpose and data sensitivity
- aap_capabilities
- Capabilities with server-side enforceable constraints
- aap_oversight
- Human oversight requirements
- aap_delegation
- Delegation tracking and limits
Start Building with AAP
Everything you need: spec, schemas, reference implementation, and test vectors
Read the Full Specification