#pattern-matching #access-control #authorization #policy

karu

An embeddable policy engine focusing on structural pattern matching over arbitrary JSON data

1 unstable release

0.1.0 May 13, 2026

#1962 in Authentication


Used in karu-cli

MIT license

720KB
17K SLoC

karu

karu is an embeddable policy engine for structural pattern matching over JSON data.

For full documentation, examples, and release notes, see the repository root README:

https://github.com/wellknown-id/karu#readme


lib.rs:

Karu

An embeddable policy engine focusing on structural pattern matching over arbitrary JSON data. Inspired by Polar/Oso, designed to solve the complex hierarchical data validation that strict-schema engines like Cedar cannot handle.

Core Philosophy

  • Structure over Schema: We don't enforce schemas. We match patterns.
  • Search, Don't Index: Lists are searched automatically with in.
  • Partial Matching: Pattern {a: 1} matches {a: 1, b: 2}.
  • Optionally Strict: Flip a switch for Cedar-level rigor when needed.

Quick Start

use karu::{Policy, Rule, Condition, Pattern, Effect};
use serde_json::json;

// Create a policy
let policy = Policy::new()
    .with_rule(Rule::allow("admin_access", vec![
        Condition::eq("principal.role", Pattern::literal("admin")),
    ]))
    .with_rule(Rule::deny("block_dangerous", vec![
        Condition::eq("action", Pattern::literal("delete")),
    ]));

// Evaluate
let request = json!({
    "principal": {"role": "admin"},
    "action": "read"
});

assert_eq!(policy.evaluate(&request), Effect::Allow);

Collection Search (The Killer Feature)

use karu::{Policy, Rule, Condition, Pattern, Effect};
use serde_json::json;

let policy = Policy::new()
    .with_rule(Rule::allow("check_capability", vec![
        Condition::contains(
            "user.permissions",
            Pattern::object([
                ("action", Pattern::literal("write")),
                ("resource", Pattern::literal("/data/*")),
            ]),
        ),
    ]));

let request = json!({
    "user": {
        "permissions": [
            {"action": "read", "resource": "*"},
            {"action": "write", "resource": "/data/*"}
        ]
    }
});

assert_eq!(policy.evaluate(&request), Effect::Allow);

Dependencies

~0.8–6MB
~103K SLoC