policy-dl
v1.0.2
Published
This repository contains a small rule language for evaluating JSON-like data.
Readme
Policy Decision Language
This repository contains a small rule language for evaluating JSON-like data.
Syntax Guide
Rules must be prefixed with allow if or deny if.
Data Model
Rules evaluate against a JSON-like object (the "root"). Paths access nested fields using dot notation:
subject.idresource.tagscontext.date
Arrays can be checked with has (see below).
Literals
Primitive literals:
- Strings: "..." or '...'
- Numbers: integers or decimals (
7,-3,3.14) - Booleans:
true,false - Dates:
YYYY-MM-DD(treated as UTC dates)
Operators
Comparison operators:
is(equality)greater_than(numbers or dates)less_than(numbers or dates)contains(string contains substring)starts_with(string prefix)ends_with(string suffix)has(arrays; value or object match)
Logical operators:
notandor
Precedence (highest to lowest):
- Parentheses
( ... ) notandor
has Semantics
has supports two forms:
- Array of primitive values:
resource.tags has "internal"- Array of objects: evaluate the inner expression with each element as the root:
subject.relations has (
role is "employee"
and subject.type is "entity"
)The has expression is true if any array element matches.
Examples
Basic comparisons:
allow if subject.id is "123"
allow if resource.classification less_than 7
allow if context.date greater_than 2025-12-11String operators:
allow if resource.type contains "file"
allow if resource.type starts_with "fi"
allow if resource.type ends_with "le"Logical composition:
allow if (subject.active is true and subject.type is "entity") or action.name is "share"Full sample:
allow if (
subject.id is "123"
and not subject.type is "entity"
or (
subject.active is false
and subject.relations has (
role is "employee"
and subject.type is "entity"
)
)
)
and (action.name is "share" and action.scopes has "read")
and resource.classification less_than 7
and resource.tags has "internal"
and context.date greater_than 2025-12-11Usage
Exports:
parse(input)-> ASTvalidate(ast, data)->{ valid, errors }evaluate(ast, data)->true/false/nullevaluateAll(rules, data)->true/falsefindRules(data, rules)-> array of PDL strings
Scripts
npm run build:grammarcompilesgrammar.neintogrammar.jsnpm run test:pdlruns the PDL test harness
Notes
- Missing paths cause validation errors.
- Type mismatches (e.g.
greater_thanwith a non-number/non-date) cause validation errors. - Dates are parsed as UTC midnight and compared by timestamp.
allow ifreturnstruewhen the condition is true, otherwisenull.deny ifreturnsfalsewhen the condition is true, otherwisenull.evaluateAllreturnsfalseif any rule evaluates tofalseor if all rules evaluate tonull.evaluateAllreturnstrueif there is at least onetrueand nofalse.findRulesreturns the subset of rules that reference at least one existing path in the provided data.- You can use https://kuselan84.github.io/policy-dl-web/ to compose your rules interactively.
- Minimal PDP server that evaluates JSON to rules is at https://github.com/kuselan84/policy-dl-pdp.
