rcan

A Rust crate for capability-based authorization through signed, chainable ed25519 delegations.

Library
Cargo
v0.4.0
24stars
Apache License 2.0

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
62/100Good
Development Activity96
Maintenance72
Community20
Maturity40
Momentum20

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
71/100Good
Architecture82
Code Quality78
Innovation68
Learning Curve55

rcan (Really simple user Controlled Authorization Networks) is a Rust crate from n0-computer implementing a UCAN-style capability system: an issuer grants a Capability to an audience by signing a Delegation, and delegations can be re-delegated in a chain so a receiver can pass along an attenuated grant it was itself given. An Authorizer holding a principal’s public key verifies that an invocation is backed by a valid, unexpired chain of delegations rooted at that principal — no central authorization server or database lookup is required to check a grant.

The crate is deliberately narrow in scope: it defines the Capability and CapabilityEncoding traits, the Delegation<C> type (generic over the capability payload, defaulting to opaque bytes via OpaqueCapability), expiry handling (Expires), and the encode/decode/verify machinery, using ed25519-dalek for signing and postcard/serde for the wire format. Application authors implement Capability::permits for their own capability enum to define which grants imply which others, then use Delegation::issue/delegate to mint tokens and Authorizer::check_invocation_from to verify them.

What You Get

  • A Capability trait applications implement to define their own grantable permissions and the permits relation between broader and narrower capabilities
  • A generic Delegation<C> type that signs and encodes a capability grant, defaulting to OpaqueCapability (raw bytes) until typed via try_with_capability_type
  • Chainable delegation via Delegation::delegate, so a capability holder can re-delegate an attenuated grant to another audience, tracked through CapabilityOrigin
  • Expiry support via Expires::valid_for, checked at verification time with is_valid_at
  • An Authorizer type that verifies an invocation against a signed delegation chain rooted at a known issuer’s public key, via check_invocation_from / check_invocation_from_at
  • Compact binary encoding via postcard, plus base32 string encode/decode for human-readable transport of delegations

Common Use Cases

  • Issuing scoped, expiring access tokens between peers in a distributed or peer-to-peer Rust application without a central auth server
  • Letting a service delegate a narrower slice of its own permissions to a downstream client or agent, which can itself re-delegate further
  • Verifying that an incoming request is backed by an unbroken, unexpired chain of signed grants back to a trusted root key
  • Building capability-secure APIs where authorization is proven by possession of a valid delegation rather than looked up from a database

Under The Hood

Architecture The crate is a single flat module (src/lib.rs) built around one core type, Delegation<C>, generic over a capability payload type that defaults to OpaqueCapability (raw bytes) and is upgraded to a concrete type via try_with_capability_type. A delegation bundles issuer and audience VerifyingKeys, a CapabilityOrigin (issuer-owned or chained from a prior delegation), an Expires window, the encoded capability bytes, and an ed25519 Signature over all of it. Chaining is expressed structurally through CapabilityOrigin::Delegation, letting Authorizer::check_invocation_from walk a chain back to a trusted root key with no external state. This keeps the trust boundary entirely local: verification is a pure function of the chain plus a known public key, with no lookup service in the loop.

Tech Stack Pure Rust, edition 2021, minimum Rust 1.91. Signing/verification is delegated to ed25519-dalek (with a pinned pre-release range for v3), capability payloads are (de)serialized generically through serde plus a postcard binary codec chosen specifically for its compact varint encoding and blanket CapabilityEncoding impl over any Serialize/Deserialize type, data-encoding/data-encoding-macro provide base32 string transport, smallvec avoids heap allocation for small capability payloads, and n0-error supplies structured, stack_error-derived error enums (DecodeError, InvocationError). No async runtime or I/O dependency — the crate is computation-only.

Code Quality Tests live in a dedicated src/tests.rs module (14 #[test] functions) covering issuance, delegation chaining, expiry, and decode/verify failure paths, using assert_matches, ron, and minicbor-serde as dev-dependencies to check cross-format behavior. Errors are typed and structured via n0_error::stack_error rather than stringly-typed, public API surfaces are documented with doc comments including a worked impl Capability example, and the repo runs cargo-deny (license/advisory/ban checks) plus a multi-workflow CI (ci.yaml, tests.yaml, wasm.yaml, zizmor.yaml for workflow security linting) on every change, indicating a maintained, security-conscious release process.

API Design The public API is small and centered on a handful of well-named entry points — Delegation::issue, Delegation::delegate, Authorizer::check_invocation_from — with the generic C parameter defaulting to OpaqueCapability so callers can start with raw bytes and opt into a typed capability later via try_with_capability_type. Any Serialize + DeserializeOwned type automatically satisfies CapabilityEncoding, so integrating a custom capability enum requires implementing only the single permits method of the Capability trait rather than hand-rolling an encoding. Documentation is thorough at the type and method level, though the crate currently ships no top-level usage example or examples/ directory, so a newcomer has to piece together a full flow from doc comments and tests.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search