Skip to main content

Module ucan

Module ucan 

Source
Expand description

macula 12’s UCAN, macula’s macula_ucan in Rust: tokens signed in the node’s crypto profile (D7), and a provider’s authorization of one. macula’s test/vectors/UCAN_V1.md is the contract, and tests/vectors/ucan holds its vectors; every verdict here is macula’s, reached in the same order.

A token is a JWT, header.payload.signature, each part base64url without padding. The header names the profile’s algorithm: ML-DSA-87 in pq_pure, ML-DSA-87-PS384 (the LAMPS composite id-MLDSA87-RSA4096-PSS-SHA512) in pq_hybrid. The signature is the issuer’s node key’s over the header and payload as sent. The payload’s iss is a did:key for the issuer’s key as carried; aud is the lowercase hex node_id of the node that presents the token, which must be the request’s verified caller; cap lists {with, can}; exp is in seconds, at most MAX_LIFETIME past now.

A token may rest on a parent: its prf names the parent by proof_id, and the parents travel beside it in the request’s caller-signed proofs. The chain is walked to its root, which must be the issuer the policy names; each link’s own signature and validity window hold, each parent’s aud is the node_id of its child’s issuer, can is equal at every step, and a child’s capability is covered by one of its parent’s (covers). Every proof that travelled must be used.

Structs§

Capability
One grant: a with (an MRI) and a can.
Context
What a token is authorized against: the request’s verified caller, the provider’s profile, the time in seconds, the request (None to check the token alone, as a gate with no request in front of it), and the proofs that travelled with it, keyed by proof_id.
Options
A token’s claims beyond iss, aud and cap: exp (seconds) is required, the rest optional. prf names the token’s parent by proof_id; at most one.
Request
The request a token is presented with: its realm id and procedure.

Enums§

CreateError
Why create mints no token, naming the values it compared.
Policy
What a gated procedure requires of a request’s token.
Refusal
Why a token does not authorize: one of macula_ucan’s refusals, by the same name (Refusal::name).

Constants§

MAX_LIFETIME
The furthest past now, in seconds, that a token’s exp may lie: ten years of 365.25 days, as macula_ucan:max_lifetime/0. UCAN_V1 has no revocation, so exp is the only bound on a token’s life. An exp in milliseconds lies far beyond it, so a token minted with one is refused, by create and by authorize, rather than valid for tens of thousands of years.

Functions§

authorize
Whether token authorizes ctx’s caller under p: the token’s claims when it does, or the first refusal, in macula_ucan’s order.
carried_key
The key a did:key carries, when it is a key in its one carried form for profile (D13); Refusal::Malformed otherwise.
covers
Whether a grant covers another grant or a request, by D7’s narrowing: a realm grant covers its realm, an org grant covers that org and its procedures, a procedure grant only itself. False for a with that is not one of the three MRIs, whose realm name is not canonical, or whose procedure has no org.
create
A token from issuer’s identity key, for the audience’s node_id, granting caps until o.exp. An exp more than MAX_LIFETIME past now, or an nbf not before exp, is refused, naming the values.
did_key
The did:key for a key as carried in profile.
proof_id
The id a child’s prf names a parent token by: the lowercase hex of the SHA-384 of the token’s bytes as they travel.