Skip to main content

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:

  1. Human authenticates with an API key or OIDC token
  2. Human requests a delegation token scoped to specific capabilities and budgets
  3. The delegation token is passed to an agent
  4. 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:

BucketMeaningAgent action
availableToken has sufficient scopeSafe to invoke
restrictedMissing a grantable scopeRequest additional authority from the specified grantor
deniedStructurally 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