Reference

match_on / match_with Operator Reference

Full operator reference for match_on and match_with arrays, including value, regexp, expression, and or logic.

match_on and match_with Operator Reference

Used to filter resources conditionally in match_on and match_with arrays. All objects in the array follow AND logic.

Operator Type Description
property String (Required) The property to evaluate. Supports dot notation traversal (domain.owner).
relation String Optional. When set, property refers to a property of outgoing relations with this label instead of the node itself.
value Any Exact equality check. Supports Tera.
not Any Inequality check. Supports Tera.
contains String Substring match for strings, or element match for arrays. Supports Tera.
excludes String Ensures substring or element is missing. Supports Tera.
exists Boolean Checks if property is present and not null.
empty Boolean Checks if property is missing, null, "", or [].
greater Number Strictly greater than (>).
lower Number Strictly less than (<).
regexp String Regular expression match. Supports Tera templating.
expression String Evaluates a Tera template directly; matches if result is exactly "true".
lib Object Calls a library function (e.g. Rhai in lib/); matches if it returns true. Format: { path = "file.rhai", function = "fn_name" }.
or Array Groups conditions with logical OR. Accepts a flat list of conditions or condition groups (legacy DNF form), and nests freely with and blocks.
and Array Groups conditions with logical AND. Accepts a flat list of conditions and nests freely with or blocks.
in Array, String Matches if the property’s value is contained in this list or comma-separated string.

match_on is valid inside rule blocks such as [[create_resource]], [[link_resources]], [[output]], [[control]], or [[action]]. At file header scope it is ignored.

Grouping with or and and

Entries in a match_on / match_with array are combined with AND. For other logic, group conditions inside a single entry:

# top level: (A) AND (B OR C)
match_on = [
  { property = "environment", value = "prod" },
  { or = [
      { property = "tier", value = "gold" },
      { property = "tier", value = "silver" }
    ] }
]

# explicit and-group, nestable inside or
match_on = [
  { or = [
      { and = [ { property = "env", value = "prod" }, { property = "tier", value = "gold" } ] },
      { and = [ { property = "env", value = "dev" } ] }
    ] }
]

Rules:

  • and / or blocks nest freely; there is no limit on depth.
  • One grouping key per object: an object cannot combine or and and. Split them into separate array entries — match_on = [{ or = ... }, { and = ... }].
  • An empty and group ({ and = [] }) evaluates to true; an empty or group ({ or = [] }) evaluates to false.
  • Bare arrays in entry position (match_on = [ [ {...}, {...} ] ]) are implicit AND-groups; the legacy DNF form { or = [ [ {...} ], [ {...} ] ] } is still accepted.

Unknown condition keys are hard errors. If a condition object contains a key that is not in the operator table above (for example a leftover op = "neq"), the build fails with a deserialization error instead of silently ignoring the condition. In Jsonnet models, rescile.neq(...) / rescile.notEq(...) emit the supported not operator.

Cross-Resource Matching in Compliance

In compliance controls ([[control.target]]), match_on evaluates against a traversable vertex representation of origin_resource. This allows dot-notation traversal across relationships directly in property paths:

[[control.target]]
origin_resource_types = "database"
match_on = [
  # Check properties on the server running this database
  { property = "server.environment", value = "production" },
  { property = "backup_policy.status", value = "active" }
]

Direction caveat: relation traversal is undirected. origin_resource.<RELATION> and dot-notation paths collect neighbors across both edge directions, and the list is sorted by neighbor name — [0] does not prefer the outgoing side. When a relation label exists in both directions (e.g. a certificate chain where a subordinate is SIGNED_BY a root and other subordinates are signed by it), select the intended neighbor by direction:

{ expression = "{% set issuer = [s for s in origin_resource.SIGNED_BY if s._relation.direction == 'outbound'] %}{{ 'true' if issuer else 'false' }}" }

The outbound / inbound Tera filters do the same selection with less ceremony (see the Tera reference).

Library Matching (lib)

To evaluate complex cross-resource conditions or calculations (e.g. time-slice audits or CIDR calculations) without polluting data models, use the lib match operator or Jsonnet rescile.libMatch():

[[control.target]]
origin_resource_types = "fee_schedule"
match_on = [
  { lib = { path = "timeline_audit.rhai", function = "has_schedule_overlap" } }
]

In Jsonnet (compliance/*.jsonnet):

local rescile = import 'rescile/v1/rescile.libsonnet';

rescile.target(
  originResourceTypes='fee_schedule',
  match=[
    rescile.libMatch('timeline_audit.rhai', 'has_schedule_overlap')
  ],
  // ...
)

Notes on expression

  • The template must render exactly the string "true" to match — a common pattern is {% if <condition> %}true{% endif %}.
  • Inside [[link_resources]] match_with expressions, both origin_resource and target_resource are available; in other contexts typically only origin_resource.
  • Tera’s in operator is not supported in these expressions and fails with a render error. Use tests instead: is containing(...) for substring/multi-value cell matching and is ending_with(...) for suffix matching.
# Multi-value cell: link when the algorithm name appears in the endpoint's `algorithms` list
{ expression = "{% if origin_resource.algorithms is containing(target_resource.name) %}true{% endif %}" }

# Suffix match: link a certificate to its parent domain
{ expression = "{% if origin_resource.name is ending_with(target_resource.name) %}true{% endif %}" }

Relation-Property Matching

Set relation to evaluate a condition against properties stored on the relationship instead of the node. The condition looks at every outgoing relation with the given label from the node being evaluated and succeeds if any matching relation satisfies the condition.

# In a compliance rule: flag computes whose DEPLOYED_AS relations lacks encryption
[[control]]
name = "deployment-must-be-encrypted"
[[control.target]]
origin_resource_types = ["compute"]
match_on = [
  { relation = "DEPLOYED_AS", property = "encrypted", value = false }
]

If property is omitted or empty and relation is set, the condition checks only for the existence of a relation with that label. This behaves like the node-level exists operator, but scoped to a specific relationship.