stateset-authz 1.23.3

IO-free, framework-agnostic authorization engine for StateSet iCommerce — roles, permissions, rate limiting, audit logging, and field redaction
Documentation

stateset-authz

crates.io docs.rs

An IO-free, framework-agnostic authorization engine: roles and permissions, rate limiting, audit logging, and sensitive-field redaction.

Zero IO is the point. No filesystem, no network, no database — you bring the persistence, so the same engine runs in a CLI, an axum server, a WASM module, or a Node NAPI binding and reaches the same decision in all four.

Features

  • Permission levelsNone < Read < Preview < Write < Delete < Admin
  • Role-based access control — built-in admin, operator, viewer, none roles, plus a RoleBuilder for custom roles
  • Window-based rate limiting — per-actor, per-resource request tracking
  • Audit logging — in-memory ring buffer, filterable by actor, resource, and time
  • Sensitive field redaction — recursive JSON traversal with partial string masking
  • Access decisionsAllowed, Denied, RequiresApproval, each with reasons
  • Zero IO — bring your own persistence

Usage

use stateset_authz::{AuthzEngineBuilder, Role, Action, Resource, RateLimitRule};
use std::time::Duration;

let mut engine = AuthzEngineBuilder::new()
    .add_role(Role::admin())
    .add_role(Role::viewer())
    .assign_role("alice", "admin")
    .assign_role("bob", "viewer")
    .rate_limit_rule(RateLimitRule::new("orders", 100, Duration::from_secs(60)))
    .build();

// Alice (admin) can create orders
let decision = engine.authorize("alice", &Resource::new("orders"), &Action::Create);
assert!(decision.is_allowed());

// Bob (viewer) cannot
let decision = engine.authorize("bob", &Resource::new("orders"), &Action::Create);
assert!(decision.is_denied());

// Every decision is recorded in the audit log
assert_eq!(engine.audit_log().len(), 2);

Decisions carry a third state that matters for agent workflows — RequiresApproval lets you gate an action on a human without modeling it as a denial.

Why Redaction Lives Here

An authorization engine already knows which fields an actor may not see, so redaction belongs next to the decision rather than in each caller. redaction walks JSON recursively and masks partially (4111********1111), so audit records stay useful without leaking card numbers or secrets into logs.

Part of StateSet iCommerce

A Rust port of the permission model in the StateSet CLI, so a decision made in the CLI and one made in the Rust engine agree. Part of the StateSet iCommerce engine, consumed by stateset-http.

License

MIT OR Apache-2.0