esdb_capability (reckon_gater v1.3.0)
View SourceCapability token creation, signing, and delegation
Provides functions for creating UCAN-inspired capability tokens that grant specific permissions to specific audiences. Tokens can be delegated with attenuation (reduced permissions).
Token Lifecycle
1. Create: Build a capability with issuer, audience, and grants 2. Sign: Sign with issuer's private key 3. Encode: Serialize to JWT or Erlang binary format 4. Transmit: Send with request to server 5. (Server) Verify: Check signature, expiry, revocation, permissions
Delegation
Tokens can be delegated to create child tokens with reduced permissions. The child token includes a proof reference to the parent token. Permissions can only be attenuated (reduced), never expanded.
Example
Create and sign a capability:
Issuer = esdb_identity:generate(), Audience = esdb_identity:generate(), Grants = [esdb_capability:grant(Resource, Action)], Cap = esdb_capability:create(Issuer, Audience, Grants, #{ttl => 900}), SignedCap = esdb_capability:sign(Cap, esdb_identity:private_key(Issuer)), Token = esdb_capability:encode(SignedCap, jwt).
Summary
Functions
Check if grants are attenuated (subset of parent)
Get the audience DID
Create a capability token with default TTL
Create a capability token with options
Decode a capability from either format (auto-detected)
Delegate a capability to a new audience with attenuated grants
Delegate with options
Encode capability to default format (Erlang binary)
Encode capability to specified format
Get the expiration timestamp
Create a capability grant
Get the capability grants
Check if the capability is expired
Get the issuer DID
Get the proof chain (parent token CIDs)
Sign a capability token with the issuer's private key
Types
Functions
-spec attenuate([capability_grant()], [capability_grant()]) -> {ok, [capability_grant()]} | {error, term()}.
Check if grants are attenuated (subset of parent)
-spec audience(capability()) -> binary().
Get the audience DID
-spec create(identity(), identity() | binary(), [capability_grant()]) -> capability().
Create a capability token with default TTL
-spec create(identity(), identity() | binary(), [capability_grant()], map()) -> capability().
Create a capability token with options
Options: - ttl: Time to live in seconds (default: 900 = 15 minutes) - nbf: Not before timestamp (default: now) - facts: Additional claims map (default: #{})
-spec decode(binary()) -> {ok, capability()} | {error, term()}.
Decode a capability from either format (auto-detected)
-spec delegate(capability(), identity() | binary(), [capability_grant()]) -> capability().
Delegate a capability to a new audience with attenuated grants
The new capability will include a proof reference to the parent capability. The grants must be a subset of (or equal to) the parent's grants.
-spec delegate(capability(), identity() | binary(), [capability_grant()], map()) -> capability().
Delegate with options
-spec encode(capability()) -> binary().
Encode capability to default format (Erlang binary)
-spec encode(capability(), binary | jwt) -> binary().
Encode capability to specified format
Formats: - binary: Erlang term_to_binary (compact, fast, BEAM-only) - jwt: JSON Web Token format (interoperable)
-spec expires_at(capability()) -> integer().
Get the expiration timestamp
-spec grant(binary(), binary()) -> capability_grant().
Create a capability grant
-spec grants(capability()) -> [capability_grant()].
Get the capability grants
-spec is_expired(capability()) -> boolean().
Check if the capability is expired
-spec issuer(capability()) -> binary().
Get the issuer DID
-spec proof_chain(capability()) -> [binary()].
Get the proof chain (parent token CIDs)
-spec sign(capability(), binary()) -> capability().
Sign a capability token with the issuer's private key