Skip to main content

Capability Tokens

Capability Tokens are Ed25519-signed JWTs that grant specific, time-limited permissions to agents. They provide fine-grained access control beyond what's declared in the manifest.

Purpose

Capability tokens enable:

  1. Time-Limited Access: Tokens expire automatically
  2. Scope Limiting: Grant subset of manifest capabilities
  3. Revocation: Invalidate tokens before expiry
  4. Audit Trail: Track which token was used for each action
  5. Delegation: Third parties can issue tokens with constraints

Token Structure

Example Token Payload

{
"iss": "issuer-abc123",
"sub": "customer-support-bot",
"aud": "uapk-gateway",
"iat": 1702560000,
"exp": 1702646400,
"jti": "tok-xyz789",
"cap": ["email:send", "crm:read"],
"con": {
"max_actions": 100,
"allowed_recipients": ["*@acme.com"]
}
}

Token Claims

ClaimTypeDescription
issstringIssuer ID (capability issuer)
substringSubject (agent ID)
audstringAudience (gateway identifier)
iatintegerIssued at (Unix timestamp)
expintegerExpiry (Unix timestamp)
jtistringToken ID (for revocation)
caparrayGranted capabilities
conobjectAdditional constraints

Issuing Tokens

1. Register a Capability Issuer

First, register a capability issuer to get signing keys:

curl -X POST http://localhost:8000/api/v1/orgs/$ORG_ID/capability-issuers \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "main-issuer",
"description": "Primary token issuer for production"
}'

Response includes the public key:

{
"issuer_id": "issuer-abc123",
"name": "main-issuer",
"public_key": "MCowBQYDK2VwAyEA...",
"created_at": "2024-12-14T10:00:00Z"
}

2. Issue a Token

curl -X POST http://localhost:8000/api/v1/orgs/$ORG_ID/capability-tokens \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"issuer_id": "issuer-abc123",
"agent_id": "customer-support-bot",
"manifest_id": "manifest-uuid",
"capabilities": ["email:send", "crm:read"],
"expires_in_hours": 24,
"constraints": {
"max_actions": 100
}
}'

Response:

{
"token_id": "tok-xyz789",
"token": "eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9...",
"expires_at": "2024-12-15T10:00:00Z",
"capabilities": ["email:send", "crm:read"]
}

3. Use the Token

Include the token in gateway requests:

curl -X POST http://localhost:8000/api/v1/gateway/execute \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"uapk_id": "customer-support-bot",
"agent_id": "customer-support-bot",
"capability_token": "eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9...",
"action": {
"type": "email",
"tool": "send",
"params": {...}
}
}'

Token Validation

The gateway validates tokens by checking:

Revocation

Revoke a token before expiry:

curl -X POST http://localhost:8000/api/v1/orgs/$ORG_ID/capability-tokens/tok-xyz789/revoke \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"reason": "Suspected compromise"
}'

Capability Scoping

Tokens can only grant capabilities that are:

  1. Declared in the agent's manifest
  2. Approved for the manifest
Cannot Exceed Manifest

A token cannot grant capabilities not declared in the manifest.

Constraints

Tokens can include additional constraints beyond the manifest:

ConstraintTypeDescription
max_actionsintegerMaximum actions with this token
allowed_recipientsarrayEmail recipient restrictions
ip_whitelistarrayAllowed IP addresses
customobjectCustom constraints for tools
{
"constraints": {
"max_actions": 50,
"allowed_recipients": ["*@acme.com", "partner@example.com"],
"ip_whitelist": ["10.0.0.0/8"],
"custom": {
"max_email_size_kb": 1024
}
}
}

Best Practices

Short Expiry

Issue tokens with the shortest practical expiry. 24 hours is a good default.

Minimal Scope

Grant only the capabilities needed for the specific task.

One Token Per Task

Issue new tokens for distinct workflows rather than reusing tokens.

Token Storage

Agents should store tokens securely and never log the full token value.