Skip to main content

Module policy

Module policy 

Source
Expand description

Attribute-Based Access Control (ABAC) policy engine — hot-reloadable, default-deny, zero locks on the request path.

§Why RBAC isn’t enough at Tier-1

PermissionGuard answers “does this role hold orders:refund?”. A fintech audit asks “may this senior agent refund this much for this tenant right now?” — a decision over attributes of the subject, resource, and environment. Those rules change with compliance reviews, not deploy cycles, so they must live outside the binary and hot-reload.

§Zero-lock mechanics

The whole rule set sits behind one ArcSwap<PolicySet> (the same proven pattern as secret rotation and dynamic tenants): evaluation is one atomic pointer load, a HashMap lookup, and pure compiled predicates. Reloads (file watcher, OPA bundle poller, admin endpoint) build a fresh PolicySet off-path and swap it in — version-monotonic, so stale loads are ignored. No policy-agent network call ever happens on the hot path.

§Usage

// boot:
ctx.provide(PolicyEngine::new(my_rules_v1()));

// route-level (macro): all listed actions must Permit
#[Post("/:id/refund", security("bearer"))]
#[RequirePolicies("orders.refund")]
async fn refund(ctx: RequestContext, #[Body] dto: RefundDto) -> Result<Json<Value>, HttpException> {
    // fine-grained re-check with resource attributes:
    policy::check_policies(&ctx, &["orders.refund.amount"],
        serde_json::json!({ "amount_cents": dto.amount_cents }))?;
    /* ... */
}

Structs§

CompiledRule
One compiled rule: a pure predicate — no I/O, no locks, no await.
EnvAttributes
PolicyEngine
Hot-swappable decision point. Provide via ctx.provide(PolicyEngine::new(…)).
PolicyInput
Everything a rule may inspect for one decision.
PolicySet
An immutable, versioned rule set. Default-deny: actions with no matching rule are denied — the zero-trust posture auditors expect.

Enums§

Decision

Traits§

PolicySource
External policy origin (rules file, OPA bundle endpoint, DB) — the app implements it; a background watcher feeds PolicyEngine::reload.

Functions§

check_policies
Evaluate every action against the engine; all must Permit.