Skip to main content

Crate delegated

Crate delegated 

Source
Expand description

§delegated

delegated is a small Rust library for evaluating issuer-signed bearer capability tokens.

crates.io docs.rs CI

It answers one question: does a token issued by a key this service explicitly trusts authorize the operation this service is about to execute?

It does not discover issuers, authenticate users, validate OIDC or SPIFFE identities, terminate TLS, operate a control plane, or turn caller-supplied request metadata into trusted context.

§What the crate provides

  • A strict 0.2 JSON capability format and Rust data model.
  • DelegationTokenBuilder for issuing Ed25519-signed capabilities.
  • Evaluator for binding a capability to the audience, action, resource, and delegation depth supplied by the host.
  • IssuerKeyResolver for connecting evaluation to explicitly trusted issuer keys.
  • TrustStateStore for connecting evaluation to revocation, agent-deny, and atomic replay state.
  • AuditEvent and AuditSink for recording allow and deny decisions.
  • In-memory key, state, and audit implementations for tests and single-process use.

The crate provides an authorization decision primitive. It does not provide an HTTP server, middleware, database, identity provider, multi-hop delegation protocol, or proof that the bearer is the agent named in the token.

§When it is useful

Use delegated when one component is allowed to mint narrowly scoped, short-lived authority that another component must verify locally and consistently. Typical examples include an agent gateway authorizing a tool call, a workflow service granting one downstream action, or an internal control plane issuing a single-use operational capability.

Do not use it as a replacement for user authentication, OAuth/OIDC login, workload identity, or a general policy language. The issuer remains responsible for deciding whether delegation should be granted.

§Project status

Version 0.2 is a pre-1.0 security primitive with a deliberately small synchronous API. The core evaluation path is tested and fail-closed, but the crate has not undergone an independent security audit. Production use requires host-provided durable state, audit persistence, key management, and careful operation mapping. Treat it as integration-ready for controlled deployments, not a turnkey authorization platform.

§Install

[dependencies]
delegated = "0.2"

§Security model

  • The host configures trusted issuer keys through IssuerKeyResolver.
  • The issuer signs every capability claim with Ed25519.
  • The host supplies OperationContext from the actual route/tool/operation being executed.
  • Audience, action, resource, and delegation-depth constraints fail closed.
  • TrustStateStore provides revocation, agent deny, and atomic nonce consumption.
  • Trust-store errors deny evaluation; evaluate_and_audit also prevents an allow from being returned when audit persistence fails.

Tokens are bearer credentials. Anyone possessing a valid token can use it until it expires, is revoked, or its nonce is consumed. Use short lifetimes and transport security.

§Example

use chrono::{Duration, Utc};
use ed25519_dalek::SigningKey;
use delegated::{
    DelegationTokenBuilder, Evaluator, InMemoryTrustState, OperationContext,
    PinnedIssuerKeys, envelope,
};

let issuer_key = SigningKey::from_bytes(&[7; 32]);
let trusted_keys = PinnedIssuerKeys::new();
trusted_keys.insert(
    "https://issuer.example",
    "issuer-2026-01",
    issuer_key.verifying_key(),
)?;

let now = Utc::now();
let token = DelegationTokenBuilder::new()
    .token_id("token-123")
    .issuer("https://issuer.example")
    .agent_id("agent:scheduler")
    .delegator_id("user:alice")
    .audience("calendar-api")
    .allowed_action("calendar.create")
    .allowed_resource("calendar:alice")
    .max_delegation_depth(0)
    .issued_at(now)
    .expires_at(now + Duration::minutes(10))
    .nonce("random-128-bit-value")
    .key_id("issuer-2026-01")
    .build_and_sign(&issuer_key)?;

let raw = serde_json::to_vec(&envelope(token, Some("request-123".into())))?;

// Construct this from the handler/route and validated target, never from `raw`.
let operation = OperationContext::new("calendar-api", "calendar.create")
    .with_resource("calendar:alice")
    .with_delegation_depth(0);

let state = InMemoryTrustState::new();
let (decision, audit_event) =
    Evaluator::new(&trusted_keys, &state).evaluate(&raw, &operation, now);

if decision.allowed {
    // Persist audit_event, then execute exactly `operation`.
}

InMemoryTrustState is a reference implementation for tests and single-process services. Distributed deployments must provide shared storage with atomic consume_nonce behavior.

§Documentation

Related crates:

§Required deployment work

  1. Load issuer keys from trusted configuration or a verified key service.
  2. Provide durable shared TrustStateStore storage (delegated-redis for Redis).
  3. Build OperationContext from the operation that will actually run.
  4. Persist AuditEvent to a durable, access-controlled sink before executing an allow.
  5. Protect bearer tokens in transit and at rest.

§Checks

cargo fmt --all -- --check
cargo clippy --all-targets -- -D warnings
cargo test
RUSTDOCFLAGS="-D warnings" cargo doc --no-deps
cargo package --offline

The wire contract is documented in SPEC.md. The project is pre-1.0 and the 0.2 wire format is intentionally incompatible with the earlier experimental format.

§License

MIT OR Apache-2.0

Re-exports§

pub use audit::AuditSink;
pub use audit::VecAuditSink;
pub use contracts::KIND_DELEGATION_TOKEN;
pub use contracts::KIND_REQUEST_ENVELOPE;
pub use contracts::SPEC_VERSION_CURRENT;
pub use contracts::validate_request;
pub use contracts::validate_token;
pub use crypto::IssuerKeyResolver;
pub use crypto::PinnedIssuerKeys;
pub use crypto::SIGNATURE_ALG_ED25519;
pub use crypto::sign_token;
pub use engine::DEFAULT_MAX_ENVELOPE_BYTES;
pub use engine::EvaluationConfig;
pub use engine::Evaluator;
pub use issuance::DelegationTokenBuilder;
pub use issuance::envelope;
pub use models::AuditEvent;
pub use models::Decision;
pub use models::DelegationToken;
pub use models::OperationContext;
pub use models::RequestEnvelope;
pub use models::Violation;
pub use revocation::InMemoryTrustState;
pub use revocation::TrustStateAdmin;
pub use revocation::TrustStateError;
pub use revocation::TrustStateStore;

Modules§

audit
Audit persistence contracts and reference implementations.
contracts
Wire-contract constants and structural validation.
crypto
Issuer-key resolution, Ed25519 signing, and signature verification.
engine
Fail-closed capability evaluation and operation binding.
issuance
Builder APIs for issuer-side capability creation.
models
Wire models, trusted operation context, decisions, and audit events.
revocation
Revocation, emergency-deny, and atomic replay-state contracts.