Group rules with expressions
Beyond field/operator conditions: expression-only membership, rows and an expression combined with AND, extra target groups, exclusions, and the preview that runs before you activate anything.
Groups and automatic membership covers the original group rule model: a target group, an active flag, and a list of field/operator/value conditions combined with AND. That model still works exactly as described there. This article covers what was added on top of it: an expression condition, additional target groups, per-rule exclusions, and the preview surface that lets you see who a rule matches before it changes anybody's membership.
Three shapes a rule can take
| Rule has | Matches when |
|---|---|
| Conditions only | Every field/operator condition holds — the original behaviour. |
| Expression only | The expression evaluates true. No rows are required. |
| Both conditions and an expression | Both must hold. This is an AND across the two mechanisms, not an OR — a rule cannot be satisfied by the expression alone if it also carries rows, or vice versa. |
| Neither | Refused at save time. A rule with nothing to test matches nobody, and the platform will not let you save one. |
A typical use for the expression half is something the field/operator model genuinely cannot express — group membership itself as a condition (user.isMemberOf({'group.profile.name': ['Engineering']})), a computed check across several attributes at once, or a regex against a naming convention. If what you need is a straightforward equality or prefix match on one profile attribute, the plain condition rows are still simpler and are what most rules should use.
Additional target groups and exclusions
A rule always has one primary target group — the one it was created against — and can now also carry:
- Extra target groups (
target_group_ids), up to 100 in total including the primary one. A single rule can populate several groups at once rather than needing a duplicate rule per group. - Excluded users (
excluded_user_ids), up to 100. Named people who should never be added by this rule even if they match every condition and the expression. Every excluded id must belong to a user in your organisation — naming somebody from another tenant is refused.
Evaluation order for a single user against a single rule is: exclusions first, then the typed conditions, then the expression. An excluded person is never added, full stop, regardless of what else about them would otherwise match.
Preview, extended
Show me who this matches (covered in Groups and automatic membership) now accepts the same three fields — expression, extra targets, exclusions — and the expression is compiled before a single user is read, so a typo is reported immediately rather than after scoring your whole directory. The response gains target_group_ids and, importantly, expression_errors / expression_error: if the expression itself cannot be evaluated for some or all users, that is reported distinctly from "evaluated fine and matched nobody". A misspelled attribute name, for instance, shows up as an expression error for every user, not as a silent zero.
Preview still runs under a tighter deadline than a live evaluation (250ms per expression rather than 50ms, per the expression engine article), and the same 2,000-user scoring cap and 50-member listing cap from the base preview surface still apply.
Backfill on save
Creating, updating, activating or deactivating an active rule now schedules an automatic reconciliation — you no longer have to remember to press Re-evaluate everyone after every edit to an expression-bearing rule. This runs detached, under a time budget; if your organisation is large enough that the budget is not enough to finish in one pass, the periodic worker sweep (the same one Groups and automatic membership describes) finishes the rest. The save response and the console's save notice tell you when a backfill was scheduled, so you know whether to expect membership to lag slightly behind the save.
What gets refused, and the messages
- A non-boolean expression (one that evaluates to a string or a number) is refused at save time — a rule condition has to be a predicate.
- More than 100 target groups or 100 exclusions is refused.
- An exclusion naming someone outside your organisation is refused.
- A target group from another organisation is refused.
- Your organisation's 2,000-rule-with-an-expression ceiling (shared with mappings and policy conditions, from the expression engine article) applies here too, refused with HTTP 409 once reached.
- A compile error is reported with the line and column of your original text — the same position-mapping the expression engine guarantees generally.
Everything else about groups — the permission gate on writes, the group profile document, the group type field being cosmetic, and the case-sensitivity of value comparisons — is unchanged from Groups and automatic membership; this article only covers what the expression, extra targets and exclusions add on top.