• Concept
  • Version · 6.0
  • Deliver

What is Checks Targeting?

Last updated: September 29, 2026

Note: Checks Targeting requires Liquibase Secure 6.0 or later and a valid Liquibase Secure license.

Checks Targeting lets you set up persistent rules that change how an individual policy check treats specific changesets during checks run. Instead of disabling a check, editing your changelog, or maintaining separate checks settings files, you add a rule that either lets certain changesets be inspected without failing the run, or restricts a check so it inspects only certain changesets. Affected changesets are recorded in the console output and the HTML report, so every exception is auditable.

Rules live in a targeting file paired with your checks settings file, which Liquibase creates the first time you add a rule. Targeting is never automatic: a run applies rules only when it names that file with --targeting-file, so a checks run without it behaves exactly as it did before.

The two rule types

Checks Targeting has two kinds of rules, and you can use both together on the same check.

Exempt rules

An exempt rule lets matched changesets be inspected without stopping the run. The check still evaluates the changeset, but a match on a covered changeset reports as INFO (Return code: 0) instead of failing the run. The result still appears in reports and logs, so you keep an audit trail. Changesets the rule does not match keep their normal severity. If every changeset that triggers the check is covered by an exempt rule, the run exits with code 0.

Use an exempt rule when a change is a known, approved exception that should not block a deployment but should still be visible.

Restrict rules

A restrict rule narrows a check so it inspects only the changesets the rule matches. Every other changeset is skipped for that check. Skipped changesets are not evaluated and do not appear in the normal results, but they are listed in a dedicated audit section so you can see exactly what was excluded.

Use a restrict rule when a check should be restricted to only a defined subset of your changesets.

How targeting selects changesets

Targeting rules match changesets using six changeset attributes and their filters: teams, releases, keywords, conditions, labels, and contexts. Matching is a straight, case-insensitive comparison against a comma-separated list of values and does not support logical operators. For how these attributes and filters work, see the attribute and filter reference pages under Changelog attributes, and Apply changeset attributes in bulk with modifyChangeSets for setting them across a changelog.

A rule can set more than one filter, using one or more of teams, releases, keywords, conditions, labels, contexts, with the value to match. Matching is case-insensitive. Values within one filter are a comma-separated OR list, and separate filters combine with AND, so a rule with two filters matches only changesets that satisfy both. A filter always matches strictly, so a leading @ on a value is accepted but does nothing. A rule with no filter matches every changeset for the check.

labels and contexts are matched differently from the other four, and the difference catches out anyone who knows the runtime filters. A changeset's value for either can legitimately contain boolean syntax, such as contexts="(dev or test) and !prod", but Checks Targeting never evaluates it as logic the way --context-filter and --label-filter do on update and checks run. It treats each word in the value as an independent name to match, and discards and, or, not, parentheses, and !.

So a changeset with contexts="(dev or test) and !prod" matches --contexts-filter=test, --contexts-filter=dev,test, and --contexts-filter='!prod', because the ! is stripped and prod is one of the words present. It never matches --contexts-filter=and. A changeset with the plain labels="dev,test" behaves like any other attribute: dev, dev,test, and dev,prod all match, and prod alone does not.

Note: Because and, or, and not are discarded, a changeset whose entire labels or contexts value is one of those three words cannot be matched by a targeting filter. Nothing is left to compare once they are removed, so the rule treats the attribute as unset. Use keywords or conditions for a value like that, because neither has reserved words.

How it differs from other options

  • Runtime attribute filters (--teams-filter and the others) apply to a single command run and are transient. A targeting rule is persistent and specific to one check.

  • checks run --check-name with a ! prefix excludes a whole check for one run. A targeting rule keeps the check active and instead adjusts how it treats selected changesets, permanently by default.

Auditing

Checks Targeting is designed so exceptions stay visible:

  • Exempted changesets that trigger a check still appear in the console output and log as INFO (Return code: 0), and the console block names the targeting file and the rule that applied.

  • Changesets skipped by a restrict rule are listed in a dedicated "Changesets skipped" section of the console output, with the ID of each skipped changeset and the check that skipped it.

  • The HTML report includes a Checks Targeting section that lists the checks with an active exempt or restrict rule, and exempted matches carry an "Exempt" badge in the Details by Changeset section.

  • You can add a --reason to any rule and set an --expiration so a rule stops applying after a specific date, such as 2026-10-30, or after a duration measured from when you added the rule, such as 2w for two weeks.

When a targeting rule affects a check that triggers, the console block for that changeset carries the targeting detail, so console and log readers see what the HTML report shows:

loading

Targeting Filepath is the targeting file the run used. Targeting Rule is EXEMPT, RESTRICT, or both. Targeting Reason and Targeting Expiry appear only when the rule sets them. An expiration always shows as a resolved date, so a rule added with a duration such as 2w shows the date it expires rather than the duration.

More than one rule of the same type can match the same changeset, and every match applies. The changeset stays covered until the last of them lapses, so Targeting Expiry shows the latest expiration across every matching rule, and both lines say how many matched:

loading

Targeting Rule counts the matches beyond the first, so two matching rules read (+1 more rule matched) and three read (+2 more rules matched). Targeting Reason still shows a single reason, the one from the first rule that matched.

Note: If any matching rule has no expiration, the Targeting Expiry line is left out rather than showing a date that would understate how long the rules apply. Expired rules are not applied and do not count toward the total, so a changeset whose matching rules have all expired carries no targeting lines at all.

A changeset that a restrict rule keeps in scope carries its own Targeting Rule line reading RESTRICT. That line is what tells you the changeset appears because it matched the rule, rather than because targeting was never applied.

Note: When the same check has both an exempt rule and a restrict rule that match one changeset, Targeting Rule lists both in evaluation order, and each reason and expiration line is labeled with the rule it came from.

loading

To review the current rules at any time, run checks targeting list.

Best practices

  • Every rule leaves an audit trail. There is no way to skip a changeset silently: exempted matches are still reported as INFO, and skipped changesets are listed in the console output.

  • Anyone who can edit the targeting file can change the rules, so control access to that file the same way you control access to any other Liquibase resource file, such as your checks settings file, flow file, or properties file.

See also