Delegation and Permissions
ANIP separates authentication from authorization, and makes both explicit. Instead of treating bearer tokens as opaque blobs, ANIP uses structured delegation — a chain of authority from human to agent to service, with explicit scopes, budgets, and purpose constraints at each link.
How delegation works
A typical delegation chain:
- Human authenticates with an API key or OIDC token
- Human requests a delegation token scoped to specific capabilities and budgets
- The delegation token is passed to an agent
- The agent uses the token to invoke capabilities — the service validates the chain
Issuing a token
curl -X POST https://service.example/anip/tokens \
-H "Authorization: Bearer demo-human-key" \
-H "Content-Type: application/json" \
-d '{
"scope": ["travel.search", "travel.book"],
"capability": "book_flight",
"purpose_parameters": {
"task_id": "trip-planning-2026",
"budget_usd": 500
}
}'
{
"issued": true,
"token": "eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9...",
"scope": ["travel.search", "travel.book"],
"capability": "book_flight",
"expires_at": "2026-03-27T12:00:00Z"
}
The resulting JWT encodes:
- Who issued it (the human principal)
- What scope was granted
- What capability it's for
- When it expires
- Purpose constraints (budget, task context)
Token structure
ANIP delegation tokens are standard JWTs signed by the service's key pair:
{
"iss": "travel-service",
"sub": "human:demo@example.com",
"scope": ["travel.search", "travel.book"],
"capability": "book_flight",
"purpose_parameters": { "task_id": "trip-planning-2026", "budget_usd": 500 },
"iat": 1711526400,
"exp": 1711569600
}
The service validates the token's signature against its own JWKS before allowing any invocation.
Permission discovery
Permission discovery is a first-class ANIP primitive. Before invoking a capability, an agent can ask "what am I allowed to do?" and get a structured answer:
curl -X POST https://service.example/anip/permissions \
-H "Authorization: Bearer <delegation-token>" \
-H "Content-Type: application/json" \
-d '{}'
{
"available": [
{
"capability": "search_flights",
"scope_match": "travel.search",
"constraints": {}
}
],
"restricted": [
{
"capability": "book_flight",
"reason": "missing scope: travel.book",
"grantable_by": "human:admin@company.com"
}
],
"denied": [
{
"capability": "admin_reset",
"reason": "requires admin principal class"
}
]
}
Three-bucket model
The response separates capabilities into three buckets:
| Bucket | Meaning | Agent action |
|---|---|---|
| available | Token has sufficient scope | Safe to invoke |
| restricted | Missing a grantable scope | Request additional authority from the specified grantor |
| denied | Structurally impossible (wrong principal class, etc.) | Do not attempt — explain to user |
This is fundamentally different from REST APIs, where the agent discovers permissions only by attempting actions and interpreting error codes. With ANIP, the agent can plan before acting and explain blockers to its user.
Why this matters for agents
Permission discovery enables agent behaviors that are impossible with traditional APIs:
- Pre-flight planning: Agent checks what it can do before constructing a multi-step plan
- Informed escalation: Agent tells the user "I can search flights but need your approval to book — shall I request access from admin@company.com?"
- Budget-aware decisions: Agent knows its delegation budget before committing to expensive operations
- Graceful degradation: Agent falls back to read-only operations when write access is restricted, rather than failing mid-workflow
Next steps
- Failures, Cost & Audit — What happens when invocations fail
- Checkpoints & Trust — Verification and trust posture