Scope, Access, and Conditions
Scope, access, conditions, and gated variants are rules shared by journeys, workflows, steps, sections, buttons, actions, and menus. Journeys, workflows, steps, and menus are described in Editor Page.
| Concept | Answers | Used for |
|---|---|---|
| Scope | Which entities does this apply to? | Limiting an item to quotes, policies, transaction categories, or transaction types |
| Access | Who may see, edit, or run this? | Hiding, locking, or disabling a node |
| Conditions | What does the data say? | Data tests inside access rules (when, unless) |
| Gated Variants | Which version applies here? | Choosing one of several titles, sections, journeys, or menus |
Scope
scope is an array of selectors declaring which entities an item applies to. An item with no scope applies to every entity. An entity is in scope if at least one positive selector matches and no negated (!) selector matches. Scope cascades by narrowing: a child can restrict its parent's set, never widen it.
| Selector | Matches |
|---|---|
quote | Quotes |
policy | Policies |
transaction | Every transaction, of any category |
transaction.cancellation | Every cancellation |
transaction.cancellation.* | Cancellations that carry a custom type. Cancellations with no custom type don't match |
transaction.*.RenewalAmendment | A transaction type, regardless of category |
!transaction.cancellation.FlatCancellation | Removes this type from the set |
This section shows only on renewals:
{
"title": "Prior Term Experience",
"scope": ["transaction.renewal"],
"include": ["elements.ExperiencePriorTerm"]
}For advanced cases, an object form lists several types: { "kind": "transaction", "category": "cancellation", "type": ["MidTermCancellation", "FlatCancellation"] }.
Access
access governs three effects:
| Effect | When granted |
|---|---|
read | The item is visible. |
write | The item is editable. Implies read. |
execute | A button or action can run. |
Each effect takes an access rule:
| Form | Meaning |
|---|---|
| (omitted) | Granted. |
false | Never granted: always hidden, locked, or disabled. |
["role", …] | Granted to these roles. |
{ gate } | Granted when every part of the gate holds: scope, roles, when, unless. |
[{ gate }, …] | Granted when any gate grants. |
This rule hides the commission section until a broker of record is chosen, then lets only admins edit it:
{
"include": ["data.commission"],
"access": {
"read": { "unless": { "field": "brokerOfRecord", "operator": "isEmpty" } },
"write": {
"roles": ["Admin"],
"when": { "field": "brokerOfRecord", "operator": "isNotEmpty" }
}
}
}A list of gates grants an effect if any one grants it. For example, underwriters can always edit, and everyone else only while the quote is a draft:
{
"write": [
{ "roles": ["Underwriter"] },
{
"when": {
"scope": "root",
"field": "quoteState",
"operator": "eq",
"value": "draft"
}
}
]
}Roles
- Roles are matched by name, exactly as shown on the "Roles" tab of a user's profile, such as
"Underwriter". Don't use role IDs or API permission names. - The match is case-sensitive:
"underwriter"doesn't match a role named"Underwriter", and the item stays hidden with no error. - Prefix a role with
!to exclude it:["!Underwriter"]grants to everyone except underwriters.["Agent", "!Underwriter"]grants to agents who aren't also underwriters.
Access Rules
- Access cascades by narrowing. An effect is granted only if the item and all of its ancestors grant it.
- Fields take only a data-driven subset. See Field Access.
execute is not inherited from ancestors yet. Set it on the button or action itself.
Access controls in UI configuration only change what users see. Role-based permissions must also be enforced on the server.
Conditions
Conditions are the data tests in when (allow when) and unless (deny when) clauses. unless is the more common idiom. For example:
{
"scope": "root",
"field": "data.directBusiness",
"operator": "eq",
"value": true
}| Property | Description |
|---|---|
field | The field path. With the default self root, a field in the same record as the item, such as the quote's or exposure's data, by its bare name. With root, a path from the quote itself. |
operator | eq, neq, in, notIn, isEmpty, isNotEmpty. |
value | The value to compare against. Not needed for isEmpty or isNotEmpty. |
scope | Optional resolution root: self (default) or root. Not the same as an item's scope. |
A single condition is written directly. To combine conditions, group them with all (and) and any (or), which can nest:
{ "any": [ <condition>, { "all": [ <condition>, <condition> ] } ] }Gated Variants
A gated variant list is an ordered array of alternatives. The UI uses the first entry whose gate (scope, roles, when, unless) matches the current entity and user. An entry with no gate is the default, so put it last.
Gated variants are accepted for:
- Journeys
- Step names
- Section slots, where one position on a step holds a list of alternative sections
- Section titles
- Menus
This step shows a different first section on renewals and on quotes:
{
"sections": [
[
{
"scope": ["transaction.*.RenewalAmendment"],
"title": "General Renewal Details",
"include": ["startTime", "endTime", "data.issuingCompany"]
},
{
"scope": ["quote"],
"title": "General Submission Details",
"include": [
"data.submissionDate",
"startTime",
"endTime",
"data.issuingCompany"
]
}
]
]
}Where an item is resolved without the entity's data or the user's roles (some menus, transaction-editor journeys, and details-page tabs), only scope gates apply reliably.