RapidValueDocs RapidValue.eu
Docs/The governance model

Filter DSL + attribute_path

One filter syntax for triggers, conditions and separation-of-duties rules.

One filter DSL, several use cases

app/core/attribute_path.py is the single source of path resolution and filter evaluation. It drives, among others:

  • Workflow definition trigger filters
  • generate_value conditional branches
  • Separation-of-duties (SoD) rule conditions (condition_a + condition_b)
  • Rule-based (dynamic) IGAGroup membership
  • Audience and scoping conditions

One mental model — admins learn it once and use it everywhere. In the UI the DSL is the wire format: the default editing surface is picker-based (field + operator + a value picker bound to the real options); the expression editor is the advanced fallback for what a picker cannot express.

resolve_path — four resolution strategies

  • resolve_path("subject.email", subject=ident) — direct ORM column.

  • resolve_path("subject.attributes.<key>", subject=ident) — JSONB lookup.

  • resolve_path("subject.<key>", subject=ident) — fallback to attributes.

  • resolve_path("payload.<dotted>", payload=dict) — dict walk.

  • resolve_path("literal:foo") — escape hatch for literals (handy in workflow steps).

Several departments, locations or companies

A person can belong to more than one department, function, cost centre, location or company at the same time. The singular paths (subject.department) answer for one stored value only. To ask about the full set, use the plural paths subject.departments, subject.functions, subject.cost_centers, subject.locations and subject.companies with includes, for example {"path": "subject.departments", "op": "includes", "value": "Finance"}. The plural paths carry the labels you see in the UI. The plural paths work where the membership set is supplied: separation-of-duties rule scopes, rule-based group membership, audience conditions, the reconciliation rule scope and configured views. Workflow trigger filters and generate_value conditions do not supply it yet, so use the singular paths there. A call site that cannot supply the membership set does not fall back to the singular value: the leaf fails closed and the platform logs the path by name.

Filter DSL — a tree of conditions

{
  "all": [
    {"path": "subject.department", "op": "eq", "value": "IT"},
    {"any": [
      {"path": "subject.function", "op": "in",
       "value": ["sysadmin", "devops"]},
      {"path": "subject.attributes.risk_level", "op": "regex",
       "value": "high|critical"}
    ]}
  ]
}

all = AND, any = OR. Nest as deep as you need. Leaf conditions are {path, op, value?}.

Operators — what the DSL understands

Equality: eq ne. Membership: in not_in contains includes. Pattern: regex. Existence: exists not_exists. Ordering: gt gte lt lte.

includes tests whether a list contains an element; contains is a substring match.

Paths that start with an underscore are refused on entity objects, so a filter cannot walk from a record into platform internals. Custom properties whose key starts with an underscore are plain data and still resolve.

A regex is checked before it runs. A pattern is refused when it is longer than 256 characters, uses backreferences, or has the nested or overlapping repeats that cause catastrophic backtracking, and a value longer than 1,024 characters does not match. Saving a rule with such a pattern is rejected with the reason; a stored one evaluates as no match.

ℹ Good to know

An unknown operator or an unresolvable path makes the filter return False (fail-closed). No exceptions that silently skip rules — you do get a log warning so you can find the typo.


Further reading:

Did this answer your question?One click records the page; add detail by email if something is missing.

Try “tenant isolation”, “role mining” or “Entra”.