Thoryn

Rules, programmable

How it works

Deterministic rule evaluation, claim extraction, decision traces — a pure library, not a service.

Library, not a service

Policy Engine is a pure Kotlin library, not an HTTP service. Broker, TrustGate, and your JVM app embed it as a Maven dependency and call evaluate(rule, facts) directly. No network hop, no serialisation overhead, no additional operational component.

Rule shape

Rules are JSON trees. Each leaf is a triple {fact, operator, value}; internal nodes are all (AND), any (OR), or not. Operators: equality, inequality, numeric comparison, list membership, existence checks. No regex, no wildcards — deliberately.

{
  "all": [
    { "fact": "vct", "operator": "equal", "value": "KvKCompanyCredential" },
    { "fact": "kvk_number", "operator": "exists" },
    { "fact": "valid_until", "operator": "greaterThan", "value": "$today" }
  ]
}
Rule tree shape — all / any / not with leaf comparisons
Internal nodes combine (all / any / not); leaves are typed comparisons (equal / greaterThan / exists / in). No regex, no wildcards — by design.

Claim extraction

Before evaluation, your caller extracts facts from the verified credential claims into a typed map. For Broker, the extractor is part of wallet-profile config; for a custom app, it's whatever mapping you need. The engine only compares against the prepared map.

Decision trace

Every evaluation returns a full trace — which leaves were checked, which passed, which failed, and why. Traces are structured objects suitable for logging, audit, or user-facing explanation. An ALLOW decision is never opaque; a DENY always tells you which specific facts failed.

Policy Engine evaluation — rule + facts → decision + trace
The evaluator walks the rule tree against the facts map, short-circuits where it can, and returns a decision plus a structured trace explaining every node's outcome.

Short-circuit evaluation

AND stops on the first failure; OR stops on the first success. Rules with expensive fact-gathering should be ordered cheapest-first to let short-circuiting skip unnecessary work. Thread-safe: the engine is stateless; the same rule can evaluate many facts-maps in parallel.

No dynamic code execution

The engine has no eval, no script surface, no plugin loader. A JSON rule is data; it can't escape into execution. This is deliberate — it makes the engine safe to accept from untrusted sources (e.g. tenant-authored rules).

Ready to turn policy into code?

Request access to see the library, the rule schema, and the evaluation fixtures.