Bend 2 vs. AWS Cedar: Policy and Authorization Engines, Formal Verification, Parallel Graph Evaluation, and When to Choose Each
How to choose between AWS Cedar’s decidable
permit/forbid authorization engine and Bend
2’s parallel recursive compute and
LAWS.bend/PROOF.bend verification
kernel.
Executive Summary
In modern DevSecOps and platform engineering, replacing fragile Python and Bash admission scripts requires choosing the right policy and verification engine. Two formally grounded tools stand out in our platform automation triad (Bend 2 in DevSecOps benchmark):
- AWS Cedar (
cedar-policy): A domain-specific authorization language designed by AWS for RBAC/ABAC access control (permit/forbidoverprincipal,action,resource, andcontext). Its core evaluator (cedar-spec) is verified in Lean 4 and backed by SMT solver analysis. - Bend 2 (
bendlang/bendv2.0.38): A general-purpose, affine functional language and equational proof checker (LAWS.bend/PROOF.bend) verified in 20,981 lines of Lean 4. It compiles via BendTT to native multi-core CPU binaries (bend-rs), GPU compute warps (bend-cuda), and zero-dependency JavaScript (Bend 2 Decision Guide).
While both tools share Lean 4 formal foundations and eliminate ad-hoc scripting bugs, they solve fundamentally different classes of policy and verification problems:
- Choose AWS Cedar when: You evaluate
point-in-time request authorization
(
Can Principal P perform Action A on Resource R given Context C?) over flat attributes and entity group memberships, where loop-free syntax and SMT policy slicing are required. - Choose Bend 2 when: Your policy gate must traverse recursive dependency trees, evaluate multi-stage deployment DAGs in parallel, compute Pareto frontiers, or prove multi-step state-machine conservation laws (DevSecOps policy benchmark).
1. Empirical Benchmark: Native Bend 2 vs. AWS Cedar vs. Rust vs. Python
In our 15-iteration hardware benchmark evaluating multi-stage
deployment promotion policies under strict cgroup isolation
(jobs.slice at Nice=10), we measured
wall-clock latency and peak resident memory (RSS) across
identical policy workloads (DevSecOps
benchmark dataset):
| Policy Engine Implementation (benchmark) | Mean Latency | Median (p50) | Peak RAM (RSS) | Speedup vs. Python | Memory Reduction vs. Python |
|---|---|---|---|---|---|
Custom Native Rust (cargo -Zscript)
(source) |
2.05 ms | 1.99 ms | 2.62 MB | 14.8x faster | 82.7 % |
Bend 2 Native (bend -o binary) (source) |
3.11 ms | 3.09 ms | 2.66 MB | 9.8x faster | 82.5 % |
AWS Cedar (Rust cedar-policy SDK) (source) |
9.57 ms | 9.02 ms | 10.93 MB | 3.2x faster | 28.0 % |
| Python 3.14 (Procedural Baseline) (source) | 30.36 ms | 30.47 ms | 15.18 MB | 1.0x | 0.0 % |
| Node.js / TypeScript Hook Baseline (source) | 45.12 ms | 44.20 ms | 55.66 MB | 0.67x | -266.7 % |
Why Is Compiled Bend 2 3.1x Faster and 4.1x Lighter Than Cedar on This Workload?
AWS Cedar’s Rust library (9.57 ms /
10.93 MB RSS) parses the .cedar policy set,
builds an in-memory Entities hierarchy graph from JSON,
validates entity schemas, and evaluates
forbid-overrides-permit slices at runtime (DevSecOps
benchmark).
By contrast, bend -o compiles the algebraic data types
(Role, Action, Environment,
Context) and pattern-matching decision trees directly into
unboxed C machine code (3.11 ms /
2.66 MB RSS), with zero runtime policy parsing or JSON
entity-graph deserialization overhead.
2. Expressiveness: Loop-Free Point Authorization vs. Recursive Tree & DAG Policies
AWS Cedar and Bend 2 differ sharply in what constructs a policy author may express.
AWS Cedar:
Intentionally Non-Recursive (permit /
forbid)
To guarantee that every policy terminates quickly and can be
translated into quantifier-free SMT formulas (cvc5), AWS
Cedar deliberately prohibits recursion, unbounded loops,
user-defined functions, and tree/graph fold operations:
// AWS Cedar: Clean, declarative point authorization over flat context attributes
permit (
principal == Role::"CiRunner",
action == Action::"PromoteImage",
resource == Environment::"Production"
)
when {
context.critical_cve == 0 &&
context.high_cve == 0 &&
context.age_days <= 90 &&
context.signed == true
};
// Emergency break-glass override
permit (
principal == Role::"SreAdmin",
action == Action::"PromoteImage",
resource == Environment::"Production"
)
when {
context.human_approved == true
};
This restriction is a feature when auditing IAM
policies across thousands of API endpoints: a security engineer knows a
.cedar file can never hang or mutate state.
Where Cedar Hits a Wall (and Bend 2 Excels)
What happens when your policy gate is not a flat attribute check, but a recursive graph, tree, or multi-step state machine?
Consider three real DevSecOps and platform verification problems
where Cedar cannot express the rule directly: 1. Recursive
Supply-Chain & SBOM Provenance Trees: Verifying that every
transitive dependency in a 10,000-node Merkle or SBOM tree
(bend-sha256 / merkle) carries a valid
attestation and zero critical CVEs across all branches. 2.
Cycle-Free Task & Deployment DAG Verification:
Proving and evaluating that a multi-stage dependency graph contains zero
cycles and satisfies topological promotion invariants (as implemented in
Dicklesworthstone/beads_bend).
3. Multi-Step Stateful Protocol & Settlement
Oracles: Verifying conservation laws across multi-turn state
transitions, resource exchanges (pareto-frontier), or
OAuth2 state machines (oauth2-fsm) (Bend 2 vs. Lean 4).
In Bend 2, recursive trees and parallel branch reductions are first-class citizens:
import Base
type AttestationTree is Data:
Leaf{pkg_id: U32, critical_cve: U32, signed: Bool}
Node{left: AttestationTree, right: AttestationTree}
# Parallel recursive policy fold: left and right subtrees reduce across CPU/GPU cores simultaneously
def verify_supply_chain(tree: AttestationTree) -> Bool:
match tree:
case Leaf{pkg_id, critical_cve, signed}:
U32.is_eq(critical_cve, 0) && signed
case Node{left, right}:
ok_left ok_right = verify_supply_chain(left) verify_supply_chain(right)
Bool.and(ok_left, ok_right)
Notice the parallel binding
ok_left ok_right = verify_supply_chain(left) verify_supply_chain(right):
BendRT automatically distributes the left and right subtrees across
independent CPU threads or GPU warps. On the 16-core Apple M4 Max
benchmark suite, recursive tree workloads like Merkle Tree
Construction scale from 4.222 s
(SEQ-CPU) down to 0.422 s
(PAR-CPU) and 0.071 s
(PAR-GPU, 59.5x speedup) (ecosystem benchmark dataset).
3.
Formal Verification Architecture: CedarLean + SMT
vs. LAWS.bend + PROOF.bend
Both AWS Cedar and Bend 2 take formal verification seriously, but they expose verification to application developers in very different ways:
| Verification Dimension | AWS Cedar (cedar-policy + cedar-spec) |
Bend 2 (LAWS.bend + PROOF.bend +
--verdict) |
|---|---|---|
| How the Engine Is Verified | AWS verified the Cedar evaluator and validator in Lean 4
(cedar-spec). |
HigherOrderCO verified BendTT’s type soundness and confluence in
20,981 lines of Lean 4 (bend2/bendtt.lean) (ecosystem dataset). |
| How Your Rules Are Verified | External SMT solver (cedar-policy-symcc /
cvc5) checks policy subsumption or equivalence across flat
requests. |
Inline equational laws (LAWS.bend) and inductive proofs
(PROOF.bend) live in the same language and repository as
your code. |
| Proof-Checking Speed | Milliseconds to seconds via external SMT solver (bounded to loop-free policies). | 0.38 s for 3,200 generic instantiations via
$ bend PROOF.bend (Kevin Ngo
benchmark). |
| Can Prove Inductive Properties Over Trees/State Machines? | No (no recursion or algebraic data types). | Yes (structural induction over arbitrary recursive ADTs, lists, trees, and state transitions). |
| AI Coding Agent Guardrail | Agent edits .cedar file; external test runner checks
sample JSON entities. |
Human locks LAWS.bend; agent must synthesize both
implementation and PROOF.bend (Proof-Blocked
AI). |
In Bend 2, PROOF.bend mathematically proves that an
emergency break-glass override never grants access when
human_approved == False{} across all CVE counts and image
ages (for all c, h, a: U32, s: Bool). Every commit checks
that proof in < 0.4 s (DevSecOps
policy benchmark).
4. The Production Automation Triad: When to Use Rust, Cedar, or Bend 2
In our platform engineering standard
(prefer-rust-scripts-cedar-bend), single-file Rust
(cargo -Zscript), AWS Cedar, and
Bend 2 are complementary tools rather than mutually
exclusive competitors:
flowchart TD
Start["New Policy, Gate, or Verification Task"] --> Q1{"What is the primary workload?"}
Q1 -->|"OS/CLI I/O, Git hooks, HTTP, file parsing"| Rust["Single-File Rust (cargo -Zscript)<br/>2.05 ms / 2.62 MB RSS"]
Q1 -->|"RBAC/ABAC point authorization<br/>(Principal, Action, Resource, Context)"| Cedar["AWS Cedar (cedar-policy)<br/>9.57 ms / Decidable permit-forbid"]
Q1 -->|"Recursive tree/DAG evaluation, parallel simulation,<br/>or state-machine test oracle with inductive proofs"| Bend["Bend 2 (LAWS.bend / PROOF.bend)<br/>3.11 ms native | 0.38 s proofs | GPU/CPU parallel"]
Head-to-Head Decision Matrix
| Evaluation Criterion | Choose AWS Cedar (cedar-policy) |
Choose Bend 2 (bendlang/bend) |
Choose Single-File Rust (cargo -Zscript) |
|---|---|---|---|
| Primary Sweet Spot | IAM, RBAC/ABAC API gates, flat resource permissions
(permit/forbid). |
Parallel tree/DAG policy folds, state-machine reference oracles, inductive proofs. | CLI tools, git hooks, filesystem/network I/O, orchestrating Cedar or Bend 2. |
| Data Structures | Entity hierarchies (in), flat records, sets. |
Arbitrary algebraic data types (type Tree,
type State), pattern matching. |
Full systems types, zero-copy slices, serde, OS
handles. |
| Parallelism | Single-threaded per request (parallelized externally by Rust host). | Automatic multi-core CPU (+RTS --threads N) and GPU
warp reduction. |
Explicit rayon / tokio concurrency. |
| Formal Assurance | SMT policy analysis + Lean-verified interpreter. | Inline LAWS.bend + PROOF.bend
(0.38 s) + Lean 4 --verdict receipts. |
Type safety + borrow checker + cargo-mutants /
proptest. |
| Cross-Compilation to JS | Via WASM bindings. | Native first-class bend -o policy.js for
bun/Node differential testing. |
Via wasm-bindgen. |
Summary Recommendation
- Use AWS Cedar when security and compliance teams
want a declarative, loop-free
permit/forbidpolicy file for API or CI admission checks over flat entity attributes. - Use Bend 2 when your policy, rulebook, or
verification oracle operates over recursive trees, DAGs, or
multi-step state machines. It delivers multi-core CPU
and GPU parallelism alongside 0.38 s
LAWS.bend/PROOF.bendinductive verification for AI coding agents (Bend 2 Decision Guide). - Wrap both inside a lightweight Rust host binary
(
2.05 msstartup,2.62 MB RSS) for deterministic CLI and I/O orchestration (Bend 2 in DevSecOps).