Blockchain

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

  1. Attenuation only: Delegations can only reduce permissions
  2. Chain validation: Complete chain must be valid
  3. Time constraints: Delegations cannot extend expiration
  4. 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

MessageDescriptionAuthorization
MsgCreateCapabilityCreates new capabilityIssuer signature
MsgDelegateCapabilityDelegates with attenuationCapability holder
MsgRevokeCapabilityRevokes capabilityOriginal issuer
MsgValidateDelegationChainValidates chainAny account

Governance Operations

MessageDescriptionAuthorization
MsgUpdateParamsUpdates module parametersGovernance 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

  1. Request capabilities from users through service registration
  2. Store tokens securely in service vault
  3. Attach tokens to requests when acting for users
  4. Check revocations before using capabilities
  5. Refresh tokens before expiration

Application Design

  1. Define resources with consistent URI patterns:

    app/users/{userId}/profile
    app/documents/{docId}
    app/settings
  2. Design abilities using clear action verbs:

    read, write, delete, update
    transfer, delegate, admin
  3. Set constraints in facts field:

    {
      "maxAmount": "1000000",
      "allowedTokens": ["usnr", "uatom"],
      "rateLimit": "100/hour"
    }

Wallet Features

  1. Capability viewer: Show granted permissions
  2. Delegation UI: Enable user-controlled sharing
  3. Revocation controls: Quick capability invalidation
  4. 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

CapabilityDescription
dwn/records/writeWrite DWN records
dwn/records/deleteDelete DWN records
dwn/protocols/configureConfigure protocols
vault/signSign with vault
bank/sendSend tokens
service/registerRegister services

Security Model

Best Practices

Least Privilege

Grant minimal required capabilities

Time Limits

Set appropriate expiration times

Revocation Strategy

Plan for capability invalidation

Chain Depth

Limit delegation complexity

Proof Validation

Verify complete delegation chains

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

EventDescriptionFields
capability_createdNew capability createdcid, issuer, audience, resource
capability_delegatedCapability delegatedparent_cid, new_cid, delegator, audience
capability_revokedCapability revokedcid, revoker, reason
delegation_validatedChain validatedroot_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.