Cedar Policy Language Overview
- Cedar Policy Language is a compact DSL for authorization that combines role-based, attribute-based, and relation-based access control in a unified syntax.
- It employs static typing, schema validation, and SMT encoding to ensure safe, error-free policy evaluation and support formal analysis.
- Its efficient Rust implementation and policy slicing enable rapid, scalable decision-making and automated checks for policy equivalence and conflicts.
Cedar is a new authorization policy language designed to be ergonomic, fast, safe, and analyzable, with the explicit aim of externalizing authorization logic from application code into a dedicated DSL (Cutler et al., 2024). Its design supports common authorization use-cases by combining role-based, attribute-based, and relation-based access control in a compact policy form, while balancing optional static validation, deterministic deny-overrides evaluation, a sound and complete SMT encoding, a mechanized Lean model, and a high-performance Rust implementation (Cutler et al., 2024, Disselkoen et al., 2024).
1. Design objectives and overall architecture
Cedar was created to meet four potentially competing objectives: expressiveness, safety, analyzability, and performance (Disselkoen et al., 2024). In the extended presentation of the language, these appear as ergonomics, safety, performance, and analyzability: a small, intuitive syntax for RBAC, ABAC, and ReBAC; a default-deny, deterministic evaluation strategy with an optional static validator; policy indexing and linear (or near-linear) evaluation times; and a sound and complete translation to SMT that supports precise queries such as equivalence and change-impact (Cutler et al., 2024).
These goals determine Cedar’s overall architecture. All policies are first statically validated against a user-supplied schema, which ensures type safety of record lookups and extension-function calls at run time (Disselkoen et al., 2024). Policies that pass validation are compiled into two paths: a Lean “definitional” evaluator and authorizer used as the formal specification and test oracle, and a high-performance Rust evaluator used in production (Disselkoen et al., 2024). In parallel, a symbolic compiler translates policies to decidable SMT formulas, enabling automated reasoning for tasks such as policy-equivalence checking (Disselkoen et al., 2024).
A central architectural feature is policy indexing, also called slicing. The language and engine are organized so that only the small subset of policies relevant to a given request need be evaluated, and sound slicing is proved in the mechanized model (Disselkoen et al., 2024). This arrangement is not incidental: the policy structure is designed so that access requests can be decided quickly, while still permitting formal analysis and machine-checked proofs (Cutler et al., 2024).
2. Policy structure, concrete syntax, and expressive fragment
A Cedar policy set is a collection of rules. Each rule has three parts—effect, scope, and condition—written in a compact concrete syntax (Cutler et al., 2024). The effect is permit or forbid; the scope constrains principal, action, and resource; and conditions appear in when or unless blocks (Cutler et al., 2024).
A simplified grammar for the core of Cedar is given as follows (Disselkoen et al., 2024):
$\begin{aligned} PolicySet &::= \{\,Policy\;\}^{*} \ Policy &::= Effect\;\scopedExpr\;\bigl[\keyword{when}\;\!CondExpr\bigr]\;\semicolon \ Effect &::= \keyword{permit} \mid \keyword{forbid} \ \scopedExpr &::= \texttt{(}\;principal\;,\;ActionExpr\;,\;ResourceExpr\;\texttt{)} \ CondExpr &::= BoolLit \mid Ident \mid Expr\;\keyword{and}\;\Expr \mid Expr\;\keyword{or}\;\Expr \mid \keyword{not}\;\Expr \ &\quad\mid Expr\;op\;Expr \mid Expr\;\keyword{in}\;\Expr \mid Expr\;\keyword{has}\;\Ident\mid\cdots \end{aligned}$
The extended version presents a related grammar in which scope clauses may use exact match or entity-hierarchy membership, for example principal [in | ==] E_\pi, action in [A_1,\dots,A_k], and resource [in | ==] E_r; expressions include values, variables, field projection, membership, equality, conjunction, and further expression forms (Cutler et al., 2024).
The expressive fragment is deliberately hybrid. Cedar supports both RBAC-style and ABAC-style policies, together with relation-based patterns, including role membership, attribute tests, wildcards, set and string operations, record projection, and custom extension functions (Disselkoen et al., 2024). The scope restricts principal, action, and resource by exact match or by entity-hierarchy membership, while conditions inspect attributes or group membership (Cutler et al., 2024). Extension functions include operators such as like, length, and IP range checks (Disselkoen et al., 2024).
This design is meant to preserve readable policies while combining several access-control paradigms in a single language. A common misconception is to view Cedar as only an RBAC language; the formal descriptions instead present it as a language whose simple syntax “naturally leverages concepts from role-based, attribute-based, and relation-based access control models” (Cutler et al., 2024).
3. Static typing, schemas, and validation
Cedar offers an optional schema and validator to catch run-time errors at authoring time (Cutler et al., 2024). The schema has two parts: an entity schema , which gives for each entity type its record type and allowed parent types, and an action schema , which gives for each action the allowed principal types, resource types, and context record type (Cutler et al., 2024). In one formulation, Cedar’s core types include bool, string, num, set<\tau>, record\{f_1:\tau_1,\dots,f_n:\tau_n\}, and entity_T for each principal, resource, or action type label (Disselkoen et al., 2024).
The basic typing judgment is
with selected rules such as variable lookup, Boolean literals, equality, set membership, and has-tests (Disselkoen et al., 2024). The extended presentation refines this into a judgment of the form
where singleton types , optional versus required attributes, and capabilities are used to track which optional attributes have been proved present before use (Cutler et al., 2024). For example, e has f can establish a capability, and field projection e.f is admitted when that capability has been established (Cutler et al., 2024).
Validation proceeds by converting a rule to an expression , instantiating each action environment permitted by the action schema, and checking that the resulting expression has Boolean type in a small, decidable type system (Cutler et al., 2024). Because the same rule is checked in each environment 0, the validator is described as precise, with few false alarms, and linear in policy size times the number of actions (Cutler et al., 2024).
The safety objective is stated strongly. Cedar is intended to guarantee that well-typed policies never “go wrong” at runtime: no record-field missing, no type errors in comparisons, and no infinite recursion in validation (Disselkoen et al., 2024). Ill-typed policies can be rejected statically by a validator, so that at runtime every policy that survives validation can be evaluated without dynamic type checks (Disselkoen et al., 2024). In the proved metatheory, validation soundness is formulated as: if a policy passes schema-validation, evaluating it can never raise a type error (Disselkoen et al., 2024).
4. Operational semantics, authorizer behavior, and SMT analysis
Cedar is given both concrete evaluation semantics and a symbolic denotational account. For the operational semantics of one policy, the judgment
1
means that policy 2, under request 3 and entity store 4, evaluates to satisfied (Disselkoen et al., 2024). In the extended version, expression evaluation is a small-step judgment 5, where 6 is the entity store and 7 is the request environment mapping principal, action, resource, and context to values (Cutler et al., 2024).
Once each policy has been evaluated, the authorizer collects the satisfied permit and forbid policies and computes the final decision as follows (Disselkoen et al., 2024):
8
This is the core deny-overrides rule: forbid-trumps-permit and default-deny (Disselkoen et al., 2024). The extended version states the same behavior as a full authorizer equation in which authorization is computed from the sliced policy set, then returns Allow iff the forbid set is empty and the permit set is non-empty (Cutler et al., 2024).
Slicing is semantically integrated. The cross-product of the ancestors of 9 and 0 is used to index only those policies with matching scope, so evaluation is linear in the slice rather than in the entire policy set (Cutler et al., 2024). The mechanized model proves sound slicing: the indexed slice yields the same decision as the full set (Disselkoen et al., 2024).
For analyzability, Cedar policies are translated to SMT-LIB-style formulas. The symbolic compiler guarantees
1
and the encoding is described as sound and complete and hence decidable (Disselkoen et al., 2024). The extended exposition explains that each Cedar type is mapped to an SMT sort, records become SMT datatypes with one field per attribute, optional fields become Option types, and the entity store and request become uninterpreted SMT constants and functions (Cutler et al., 2024). Because Cedar policies only mention a finite “footprint” of entity constants, grounded well-formedness constraints are added only for those entities, rather than general quantified axioms, which keeps the encoding decidable (Cutler et al., 2024).
The resulting analyses include equivalence, change-impact, subsumption, redundancy, conflict detection, and coverage (Cutler et al., 2024, Disselkoen et al., 2024). The implementation ships with a command-line tool, cedar analyze, and a gRPC API for these analyses (Cutler et al., 2024).
5. Mechanized metatheory and verification-guided development
Cedar is formalized in Lean 4. The evaluator, authorizer, validator, and slicer are written as total, terminating Lean 4 functions over algebraic datatypes, and all definitions are proven to terminate by structural recursion (Disselkoen et al., 2024). The implementation strategy is described as verification-guided development: write an executable model of the system and mechanically prove properties about the model; write production code and use differential random testing to check that the production code matches the model; and use property-based testing to check properties of unmodeled parts of the production code (Disselkoen et al., 2024).
The main theorems proved in Lean include forbid-trumps-permit, default-deny, explicit-allow, order-independence, sound slicing, validation soundness, and termination (Disselkoen et al., 2024). For example, forbid-trumps-permit is stated as
3
and the extended version highlights the corresponding results as default-deny, forbid-trumps-permit, explicit-allow, sound slicing, and validation soundness (Cutler et al., 2024).
The testing regime is unusually explicit. The Lean model is compiled to an executable oracle, and a fast Rust production engine is checked against it using cargo-fuzz and libFuzzer (Disselkoen et al., 2024). The system generates millions of random triples 2 each day and checks equality between the Rust engine and the Lean model (Disselkoen et al., 2024). QuickCheck-style testing is then applied to the parser/pretty-printer, JSON-schema parser, Rust-only APIs such as template linking and JSON output, and the property that type-checked policies never produce dynamic errors (Disselkoen et al., 2024).
This process uncovered subtle defects. Lean proofs found and fixed 4 bugs in Cedar’s policy validator, and DRT and PBT uncovered 21 production bugs in policy evaluation, validation, parsing, formatting, and extension-function handling (Disselkoen et al., 2024). The reported examples include inconsistent IPv4/IPv6 parsing between Rust and Lean, pretty-printer comment loss, raw-string and like parsing errors, and validator mis-typing of has expressions (Disselkoen et al., 2024).
6. Performance characteristics and policy idioms
Cedar ships as a Rust-based authorizer and validator, built for single-digit-microsecond decision times, together with a Lean 4 reference specification and validator used to fuzz-test the Rust code for divergences (Cutler et al., 2024). In the performance comparison reported in the extended paper, Cedar was evaluated against OpenFGA and OPA/Rego on three example applications—gdrive, github, and TinyTodo—using 100,000 random authorizations on growing data sets (Cutler et al., 2024). The median and p99 figures reported for Cedar are 3 and 4 on gdrive, 5 and 6 on github, and 7 and 8 on TinyTodo; the paper states that Cedar is on average 28× faster than OpenFGA and 43× faster than Rego, and that its running time grows only linearly with policy slice size (Cutler et al., 2024).
The language is illustrated with the TinyTodo example, which mixes ABAC and RBAC (Disselkoen et al., 2024):
4
At runtime, the authorizer slices the policy set to those policies whose scope overlaps the current request, evaluates each condition in Rust, and applies forbid-trumps, default-deny, and explicit-allow to reach a final Allow or Deny decision (Disselkoen et al., 2024).
Several common patterns are explicitly identified. Role-based access is written using a built-in or user-defined Role::"name" entity together with principal in Role::"name"; attribute-based access uses resource has f and equality or inequality on numbers, strings, and dates; delegation can be represented by an attribute such as delegatees; and set operations appear in approvals such as principal in resource.approvers together with negation (Disselkoen et al., 2024). Cedar also supports policy sets and policy templates; templates can be parameterized by schema values and instantiated multiple times, and large collections rely on slicing to achieve sub-linear evaluation cost in the number of total policies (Disselkoen et al., 2024).
7. Subsequent research uses and extensions
Later work has treated Cedar not only as a language for application authorization, but also as a target formalism for other security workflows. In "Autoformalization of Agent Instructions into Policy-as-Code" (Mondl et al., 25 Jun 2026), an LLM-based generator-critic loop translates agent prompts, MCP tool descriptions, and natural-language policy documents into formally verified policies written in the Cedar Policy Language. That system uses the AWS Cedar Policy Engine, emits a Cedar schema from tool JSON schemas, invokes the Cedar CLI as a hard critic, and iterates until all rules pass both hard and soft critics; the resulting policy sets are described as deterministically verified, with enforcement coverage 9 on MedAgentBench and higher coverage than hand-coded symbolic enforcement in prior work (Mondl et al., 25 Jun 2026). This suggests that Cedar’s combination of simple syntax, static typing, and formal semantics makes it suitable as a policy-as-code target beyond its original authorization setting.
In "Automatically Tightening Access Control Policies with Restricter" (Wu et al., 21 Jan 2026), Cedar serves as the substrate for automatic least-privilege refinement. Restricter leverages Cedar’s default-deny, deny-overrides semantics, its type system, and its symbolic SMT encoding to tighten overly permissive permit rules with respect to access logs (Wu et al., 21 Jan 2026). The system works by incremental strengthening through SyGuS, using a finite, type-safe set of candidate predicates generated from the Cedar schema and environment (Wu et al., 21 Jan 2026). Across two case studies, the reported results are that Restricter successfully tightened all 5 loosened rules in the classroom-management setting; in the conference-management setting it recovered the ideal tightening in 2 of 5 cases, while the remaining 3 cases removed at least 0 of over-privileges while preserving at least 1 of intended but unlogged privileges; overall, 6 of 8 target rules were tightened to the “ideal” form, and all tightened rules removed more than 2 of over-privilege on average (Wu et al., 21 Jan 2026).
Taken together, these later works reinforce a specific picture of Cedar already present in the 2024 papers: a policy language whose syntax is compact, whose semantics are formalized, whose validator and SMT translation are mechanized, and whose implementation supports both efficient enforcement and external reasoning tasks (Cutler et al., 2024, Disselkoen et al., 2024). A plausible implication is that Cedar’s distinctive contribution lies less in any single access-control paradigm than in the balanced co-design of language fragment, validator, semantics, proof infrastructure, and production engine.