Compared with OPA, CEL, JSON Logic and Drools
How Rule Cascade differs from Open Policy Agent (OPA), the Common Expression Language (CEL), JSON Logic and Drools, and when each one is the better choice.
Rule Cascade, Open Policy Agent (OPA) and the Common Expression Language (CEL) all evaluate logic that lives outside the application code. They answer different questions. This page says what each one is for, where they differ, and when to choose which. It also covers JSON Logic and Drools.
In one sentence each
- OPA is a general-purpose policy engine. Policies are written in Rego and answer questions such as "may this user do this", "is this Kubernetes manifest allowed" or "does this Terraform plan follow our rules".
- CEL is an expression language: one typed, side-effect-free expression, embedded in a host's configuration. Kubernetes validation rules and Envoy filters use it.
- Rule Cascade is a business rules engine for data that people and programs submit: "may this order be saved, and if not, which field is wrong and what does the user read". The same rule runs in the browser form and in the API.
Side by side
| OPA | CEL | Rule Cascade | |
|---|---|---|---|
| What it is | Policy engine and language (Rego) | Expression language | Rules engine with a rule format, compiler and engines |
| Unit of logic | A policy module that computes any JSON document | One expression | A ruleset: rules, messages, parameters and golden tests |
| Typical question | Is this request authorized? Is this config allowed? | Does this object satisfy this condition? | Is this record valid, which fields are wrong, what does the user see? |
| Result | Whatever the policy computes | A value, usually a boolean | A decision (allow/deny) and findings, each with a rule, code, field, severity and localized message |
| Where it runs | A server or sidecar called over HTTP, a Go library, or Rego compiled to WebAssembly | Inside the host, through a library: official ones for Go, Java and C++ | Inside the host: libraries for TypeScript (browser and Node), Java, Go and Python, a command, WebAssembly, and an optional rule server |
| Agreement between languages | One engine (Go); WebAssembly carries policies to other hosts | One specification and a conformance suite | One specification and a conformance suite of 1,899 cases that every engine runs in CI |
| Hierarchy | Policies are composed in code | None: the host decides where expressions come from | Rulesets extend parents; each rule and parameter is locked, tighten-only or open |
| User-facing messages | Written by the policy author as data | None | Message catalogs per locale, with fallback |
| Warnings and exceptions | Modeled by the author | None | Warnings that must be acknowledged; errors whose risk an authorized role may accept, with a justification |
| Tests | opa test with Rego test rules | Up to the host | Golden tests inside the ruleset; a failing test stops the build |
Where they differ
The question. OPA is strongest where the answer depends on who asks and on a lot of
surrounding data: roles, relationships, resource attributes, cluster state. Rule Cascade is narrow
on purpose. A rule targets an entity and a field, runs for an operation such as create or
update, and produces a finding a person can act on. It does not fetch data or join documents:
evaluation is a pure function of the request (see the
specification, section 1).
Expressions, and everything around them. CEL is close in spirit to Rule Cascade's expression
language: typed, without loops, without side effects. The two differ in what surrounds the
expression. A business rule needs an id, a severity, a finding code, a message in each language,
the field it points at, the moments it runs (change, blur, submit), what an override may
change, and tests. With CEL the host builds those parts; in Rule Cascade they are the rule format.
CEL is also a text language, so a rule editor must parse and print it. Rule Cascade expressions are
JSON trees, which JSON Schema validates and a language model can be constrained to produce. The
reasons are in ADR 0001.
The browser. Rule Cascade is built for one rule to give the form and the API the same answer.
The engine for TypeScript runs in the browser, the client manifest leaves out server-only rules,
and triggers say which rules run on change, which on blur and which on submit. OPA can run in a browser
through WebAssembly, and CEL has community implementations in JavaScript, but neither defines what
a form shows. A client evaluation is advice; the server evaluation is the decision
(section 9).
The cascade. An organization sets a limit, a business unit narrows it, a team narrows it
further. A child ruleset may tighten a tighten-only parameter but not loosen it, may not touch a
locked rule, and must give a reason for every override. A violation fails the build, not the
request (ADR 0004). In OPA and CEL
that structure is the author's to build.
Money. Rules compare amounts. In binary floating point 0.1 + 0.2 <= 0.3 is false, and CEL's
standard numeric types are integers and doubles. Rule Cascade computes in decimal, with 34
significant digits, identically in every language
(section 4.2).
Failing closed. In Rule Cascade a type mismatch or a missing value that a rule needs is an
evaluation error: the rule produces a blocking finding and the decision is deny. The engine never
guesses (section 8).
When to choose which
Choose OPA for authorization across services, Kubernetes admission control, infrastructure and configuration policy, and any decision that needs data the request does not carry. Its ecosystem for those uses (Gatekeeper, Conftest, the Envoy plugin, decision logs) is far larger than Rule Cascade's.
Choose CEL when a system already embeds it, such as Kubernetes ValidatingAdmissionPolicy or
CRD validation rules, or when a product needs one short condition that its users type, and the host
supplies everything around it.
Choose Rule Cascade when the same business rules must hold in a form, an API, a batch job and an AI agent, written in different languages; when users must read why something was refused and fix it; when warnings, risk acceptance or a hierarchy of owners are part of the rules; or when amounts must compare exactly.
They also work together. OPA decides whether the caller may submit an order; Rule Cascade decides whether the order is valid. The two checks run one after the other in the same handler.
Other tools
JSON Logic. Rule Cascade expressions started from JSON Logic and differ in typing, arithmetic and the operator shape. A converter moves expressions in both directions and says where the meaning changes: see JSON Logic and Rule Cascade.
Drools. Drools is a Java rule engine with forward chaining: rules insert facts that make other rules fire, over a working memory that can persist between calls. Rule Cascade has no inference. Evaluation is three fixed phases (compute, state, validation) and one decision, the same in every language. Choose Drools for inference over many interacting facts on the JVM; choose Rule Cascade for validation and decisions that must give the same answer outside the JVM too.
Try it
The playground runs the real engine in your browser. The quickstart writes, tests and evaluates a first rule in five minutes.