Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Policy Evaluation

The ABAC policy engine evaluates access requests through a multi-layer optimization pipeline. Each layer short-circuits on success, so most requests never reach the sequential evaluation fallback.

Basic evaluation

#![allow(unused)]
fn main() {
use abac_rs::{AbacPolicy, AbacRequest, AttributeType};

let mut policy = AbacPolicy::new();
// ... add rules ...

let mut request = AbacRequest::new();
request.add_attribute("user", AttributeType::String("alice".into()), vec![]);
request.add_attribute("resource", AttributeType::String("db-01".into()), vec![]);
request.add_attribute("action", AttributeType::String("read".into()), vec![]);

let decision = policy.evaluate(&request);
if decision.is_allowed() {
    // Grant access
}
}

Optimization pipeline

  1. Layer 0: Constant result (~15 ns) – universal allow/deny detection
  2. Layer 1: Bitmap deny index – u64 bitmask intersection when universal allow exists
  3. Layer 2: LRU cache (sub-μs) – memoization of recent evaluations
  4. Layer 3: AHash – 2-3x faster than SipHash for non-cryptographic use
  5. Layer 4: Compiled evaluator – pre-extracted attributes + array indexing
  6. Layer 5: Composite index (O(log n)) – candidate selection fallback
  7. Layer 6: Deny-only indexing – skip allow rules when universal allow exists

The compiled evaluator (Layer 4) is automatically detected and applied when all rules use consistent dimensions. It pre-extracts request attributes once (3 HashMap lookups) instead of per-candidate (600+ lookups), providing a 62x speedup at large scales.

Deny-only indexing: When a universal allow rule exists, only deny rules are indexed. This is valid because:

  1. Deny rules are checked first (deny-override semantics)
  2. If no deny matches, universal allow guarantees Allow decision
  3. Individual allow rules become irrelevant

This optimization reduces index size and evaluation time dramatically in typical deployments where most rules are allow and only a few are deny exceptions.

See ABAC Performance for detailed layer breakdown.

Lazy index building

Indexes are built on first evaluation after rule changes, not during add_rule(). This eliminates O(n²) overhead during batch rule loading.

Deny-override semantics

  1. Check all deny rules – if any match, return Deny
  2. Check all allow rules – if any match, return Allow
  3. Default to Deny if no rules match

Denials always take precedence over allows.

See also