UCAN Module
Capability-based authorization system for fine-grained permission delegation, attenuation, and on-chain revocation on Sonr blockchain
UCAN Module (x/ucan)
Scope
This document covers the UCAN module's implementation of User Controlled Authorization Networks, including capability management, delegation chains, on-chain validation, and revocation systems. It details data structures, messages, queries, and security patterns. This document does not cover client JWT generation or off-chain validation—see the SDK documentation for those topics.
Audience
Service developers implementing authorization flows. Application developers managing user permissions. Security engineers designing capability systems. Prerequisites: Understanding of JWT tokens, capability-based security, and Protocol Buffers.
Summary
The UCAN module implements User Controlled Authorization Networks for decentralized permission management. It stores and validates capability tokens that delegate specific permissions from issuers to audiences. The module enforces permission attenuation (reduction only), manages delegation chains, and provides on-chain revocation. All capabilities are cryptographically signed tokens that reference resources and allowed actions.
Module Features
The UCAN module provides:
- Capability Management: Create, delegate, and revoke authorization tokens
- Delegation Chains: Hierarchical permission delegation with attenuation
- On-chain Validation: Verify tokens and complete delegation chains
- Resource Permissions: Query permissions for resource/audience pairs
- Revocation System: Permanent invalidation of capabilities
Core Concepts
UCAN Structure
UCANs are JWT-like tokens containing:
- Issuer (iss): DID granting the capability
- Audience (aud): DID receiving the capability
- Capabilities (att): Permissions being granted
- Proofs (prf): Parent capability references
- Expiration (exp): Time-based validity
Capability Format
Capabilities specify resource access:
{
"with": "did:example:resource", // Resource identifier
"can": "store/add", // Action allowed
"nb": {
// Optional constraints
"maxSize": 1048576
}
}
Delegation Rules
- Attenuation only: Delegations can only reduce permissions
- Chain validation: Complete chain must be valid
- Time constraints: Delegations cannot extend expiration
- Issuer authority: Only issuers can revoke capabilities
Revocation Mechanism
Revocation immediately invalidates:
- The revoked capability
- All delegations derived from it
- Any active sessions using it
Data Structures
Capability
Stores UCAN capability data:
message Capability {
string cid = 1; // Content identifier
string issuer = 2; // Issuer DID
string audience = 3; // Audience DID
string resource = 4; // Resource URI
repeated string abilities = 5; // Allowed actions
int64 expiration = 6; // Expiry timestamp
int64 not_before = 7; // Valid from timestamp
repeated string proofs = 8; // Parent CIDs
google.protobuf.Any facts = 9; // Constraints
CapabilityStatus status = 10; // Current status
}
enum CapabilityStatus {
CAPABILITY_STATUS_ACTIVE = 0;
CAPABILITY_STATUS_REVOKED = 1;
CAPABILITY_STATUS_EXPIRED = 2;
}
Revocation
Records capability revocations:
message Revocation {
string cid = 1; // Capability CID
string revoker = 2; // Revoker DID
int64 revoked_at = 3; // Revocation time
string reason = 4; // Reason text
}
State Transitions
Capability Operations
Message | Description | Authorization |
---|---|---|
MsgCreateCapability | Creates new capability | Issuer signature |
MsgDelegateCapability | Delegates with attenuation | Capability holder |
MsgRevokeCapability | Revokes capability | Original issuer |
MsgValidateDelegationChain | Validates chain | Any account |
Governance Operations
Message | Description | Authorization |
---|---|---|
MsgUpdateParams | Updates module parameters | Governance only |
Query Interface
Capability Queries
# Get capability by CID
snrd query ucan capability bafyreib3hxp...
# List capabilities by resource
snrd query ucan capabilities-by-resource 'did:sonr:vault'
# List capabilities by issuer
snrd query ucan capabilities-by-issuer did:sonr:alice123
# Check resource permissions
snrd query ucan resource-permissions 'did:sonr:vault' 'did:sonr:service'
Validation Queries
# Check revocation status
snrd query ucan revocation bafyreib3hxp...
# Validate UCAN token
snrd query ucan validate 'eyJ0eXAiOiJKV1QiLC...'
Transaction Examples
Create Capability
# Basic capability
snrd tx ucan create-capability \
'did:sonr:vault/profile' \
'read,write' \
'did:sonr:service123' \
--from alice
# With expiration (1 hour)
snrd tx ucan create-capability \
'https://api.example.com/data/*' \
'GET,POST' \
'did:sonr:app456' \
--expiration $(($(date +%s) + 3600)) \
--from bob
# With constraints
snrd tx ucan create-capability \
'did:sonr:vault' \
'transfer' \
'did:sonr:service789' \
--facts '{"maxAmount":"1000000","allowedTokens":["usnr"]}' \
--from charlie
Delegate Capability
# Full delegation
snrd tx ucan delegate-capability \
bafyreib3hxp... \
'did:sonr:newuser' \
--from alice
# Attenuated delegation
snrd tx ucan delegate-capability \
bafyreib3hxp... \
'did:sonr:newuser' \
--attenuate 'read' \
--from alice
# Time-limited delegation
snrd tx ucan delegate-capability \
bafyreib3hxp... \
'did:sonr:tempuser' \
--expiration $(($(date +%s) + 1800)) \
--from alice
Revoke Capability
# Revoke with reason
snrd tx ucan revoke-capability \
bafyreib3hxp... \
--reason "No longer needed" \
--from alice
Implementation Patterns
Service Integration
- Request capabilities from users through service registration
- Store tokens securely in service vault
- Attach tokens to requests when acting for users
- Check revocations before using capabilities
- Refresh tokens before expiration
Application Design
-
Define resources with consistent URI patterns:
app/users/{userId}/profile app/documents/{docId} app/settings
-
Design abilities using clear action verbs:
read, write, delete, update transfer, delegate, admin
-
Set constraints in facts field:
{ "maxAmount": "1000000", "allowedTokens": ["usnr", "uatom"], "rateLimit": "100/hour" }
Wallet Features
- Capability viewer: Show granted permissions
- Delegation UI: Enable user-controlled sharing
- Revocation controls: Quick capability invalidation
- Expiration alerts: Notify before timeout
UCAN Token Format
JWT Structure
{
"iss": "did:sonr:alice123", // Issuer DID
"aud": "did:sonr:service456", // Audience DID
"exp": 1702934400, // Expiration timestamp
"nbf": 1702848000, // Not before timestamp
"att": [
{
// Capabilities array
"with": "did:sonr:vault/data", // Resource
"can": "store/add" // Action
}
],
"prf": ["bafyreib3hxp..."], // Proof chain
"fct": {
// Facts/constraints
"maxSize": 1048576
}
}
Common Capabilities
Capability | Description |
---|---|
dwn/records/write | Write DWN records |
dwn/records/delete | Delete DWN records |
dwn/protocols/configure | Configure protocols |
vault/sign | Sign with vault |
bank/send | Send tokens |
service/register | Register services |
Security Model
Best Practices
Least Privilege
Time Limits
Revocation Strategy
Chain Depth
Proof Validation
Module Parameters
| Parameter | Description | Default |
|-----------|-------------|---------||
| max_delegation_depth
| Maximum chain depth | 10 |
| default_expiration
| Default expiry (seconds) | 86400 |
| max_capability_size
| Max data size (bytes) | 10240 |
| enable_revocation_list
| On-chain revocation check | true |
Events
Event | Description | Fields |
---|---|---|
capability_created | New capability created | cid , issuer , audience , resource |
capability_delegated | Capability delegated | parent_cid , new_cid , delegator , audience |
capability_revoked | Capability revoked | cid , revoker , reason |
delegation_validated | Chain validated | root_cid , leaf_cid , depth |
Implementation Example
Create and Delegate
// Create initial capability
cap := &MsgCreateCapability{
Issuer: "did:sonr:alice123",
Audience: "did:sonr:service456",
Resource: "did:sonr:vault/documents",
Abilities: []string{"read", "write"},
Expiration: time.Now().Add(24 * time.Hour).Unix(),
Facts: &anypb.Any{
// Constraints
},
}
// Delegate with attenuation
delegation := &MsgDelegateCapability{
ParentCid: "bafyreib3hxp...",
Audience: "did:sonr:bob789",
Abilities: []string{"read"}, // Reduced from read,write
Expiration: time.Now().Add(1 * time.Hour).Unix(),
}
Validate Permissions
// Check if audience has permission
hasPermission, err := queryClient.ResourcePermissions(ctx,
&QueryResourcePermissionsRequest{
Resource: "did:sonr:vault/documents",
Audience: "did:sonr:bob789",
Action: "read",
},
)
Next Steps
Ready to Implement?
Service Developers: Follow the UCAN Integration Guide for authorization flows.
Application Developers: Review Permission Design Patterns for best practices.
Security Engineers: Study Capability Security for threat models.