Write Your Broker’s Access Policy
Every broker operation—creating users, deploying Actions, publishing to topics—passes through Rules before it executes. This page is the complete syntax reference for writing those rules: the conditions you can check, the scopes you can target, and the patterns that tie them together.When You Need This Reference
Deploying rules: In a LoT Notebook, write the rule and run the cell. For MQTT clients, use
-addRule (broker commands). Custom ACL rules require a Growth or Enterprise license.Rule Structure
Every rule follows this structure:
Unconditional forms are valid too:
Conditions
Rules evaluate conditions to decide whether to ALLOW or DENY an operation.User Identity Checks
Group Membership
Permission Flags
Client Identity and Endpoint
Rules can inspect the MQTT session’s client identifier and network endpoint:CLEANSESSION, SUBSCRIBETOPIC, SUBSCRIBEQOS, and DISCONNECTREASON also parse in rule conditions (CLEANSESSION returns "true" or "false", SUBSCRIBEQOS returns an integer), though they are primarily populated for lifecycle action triggers.
Topic Segments (TOPIC POSITION)
On topic scopes (Publish, Subscribe, PublishSys, SubscribeSys), TOPIC POSITION n extracts the 1-based segment n of the topic being checked. Use it to bind a client to its own topic subtree:
sensor-1 may publish to devices/sensor-1/telemetry (position 2 is "sensor-1") and is denied on devices/sensor-2/telemetry.
Topic State (TOPIC EXISTS and GET TOPIC)
Rules can gate access on broker topic state—for example, a per-device provisioning or allow-list topic built dynamically from CLIENTID:
Bare
TOPIC EXISTS checks presence only, so a retained payload of "false" still satisfies it. Compare against a value (or use GET TOPIC) when the payload itself is the allow/deny flag:
Permission checks have no side effects: unlike
GET TOPIC in an Action, evaluating GET TOPIC inside a rule does not subscribe to or start tracking a missing topic. Write the allow-list value (via KEEP TOPIC or a retained publish) before the client requests access.MATCHES REGEX
REGEX is required. Plain MATCHES tests equality. Negate a pattern with NOT MATCHES REGEX.
Backslash escapes such as \d, \w, \s, and \. reach the regex engine as written, the same way they do in FILTER … USING REGEX. Use \" for a double quote inside the pattern. Anchor with ^ and $ when the whole value must match. An invalid pattern evaluates to false and the broker logs an error. The same operators work in an action IF.
Allow only client ids shaped like sensor-1:
[0-9] still work.
Combining Conditions
Implicit ELSE (Rules Never Abstain)
Omitting ELSE is valid, but a rule never abstains. Every rule in the winning priority band returns either ALLOW or DENY for every matching request: when the IF condition is false and there is no ELSE, the rule automatically returns the opposite verdict of its THEN branch:
IF <condition> THEN ALLOW(noELSE) compiles with an implicitELSE DENY— anyone not matching<condition>is denied at that priority band.IF <condition> THEN DENY(noELSE) compiles with an implicitELSE ALLOW— anyone not matching<condition>is allowed at that priority band.- An
IF … ELSE IF …chain without a finalELSElikewise returns the opposite of the branch verdict when no condition matches.
IF … THEN ALLOW rule at priority 100 denies all other users on that topic—it does not fall through to a priority 1000 rule. Combine multiple allowed principals with OR in a single rule, or use explicit ELSE branches to keep the behavior unmistakable:
Operation Scopes
Rules control different categories of operations. They split into two groups that behave very differently in practice. Topic scopes —Publish, Subscribe, PublishSys, SubscribeSys — are the scopes you write rules for. The only built-ins that compete with you are the permissive catch-alls in the weakest band, so your rules decide.
Connect — FOR Connect decides whether the broker accepts an MQTT CONNECT after authentication. It takes no TO TOPIC clause. See Connection admission.
Management scopes — everything below — are already covered by locked built-in rules in the reserved band (0–99) that key off permission flags. Because your rules are floored at 100 and only the lowest-numbered matching band decides, a rule you write on a management scope is never the deciding band.
The tables below name each scope and the flags its locked built-in accepts. In every case root is also accepted.
User Management
Entity Management
RouteManagementCreation and RouteManagementRemove remain supported aliases of the Connector scopes. A rule written with either spelling governs the same commands (-addConnector / -addRoute, -removeConnector / -removeRoute).
System Operations
Log Management
Topic Access Rules
Standard Topics
UsePublish and Subscribe with TO TOPIC:
1 000 000) that allow all connect, publish, and subscribe. Any rule you add in the user band already outranks them for its topic — see RBAC.
System Topics ($SYS)
$SYS topics use the PublishSys and SubscribeSys scopes. Most of this namespace is already locked down for you:
Because the locked
$SYS rules sit in the reserved band, a custom rule for $SYS/# subscribe never decides. Write PublishSys rules only for subtrees the built-ins do not already cover:
Permission Flags
Assign flags with
-changeUserSettings or in Coreflux HUB User Management (Full Access → AllowedSystemConfiguration).
Priority and Evaluation
Lower priority number wins — the same convention as BACnet write priority and ISA-18.2 alarm priority. Among rules that match the operation (and topic), only the lowest-numbered band decides:- If any rule in that band evaluates to DENY → deny (deny-wins)
- Else if any allows → allow
- If no rule matches → deny (default-deny)
IF has no ELSE, a false condition returns the opposite verdict (IF … THEN ALLOW returns DENY for non-matching requests in that band). Weaker priority bands are only consulted when no rule at a stronger priority matches the operation and topic.
For cookbook patterns, Visu RBAC, and default-rule tiers, see RBAC with LoT Rules.
Complete Examples
- Group-based topic access
- Device topic namespace
- Department isolation
Operators and supervisors share a plant namespace; only supervisors may emergency-stop:
Best Practices
Prefer groups for topic access
Prefer groups for topic access
Use
USER IN GROUP for data and panel access. Reserve permission flags for system-level capabilities.Any user-band rule overrides the catch-alls
Any user-band rule overrides the catch-alls
You do not need to remove
AllowPublishTopic / AllowSubscribeTopic / AllowConnect to deny a subtree (or a connection). They sit in the weakest band (1 000 000), so any rule you write for that pattern already wins.Leave room to carve out exceptions
Leave room to carve out exceptions
Exceptions need a lower number than the rule they override, and
100 is the floor. Place namespace-wide rules at 1000 or higher and keep 100 for the most specific case, so you never have to renumber deployed rules.Protect $SYS topics
Protect $SYS topics
Rely on the locked built-ins — they already gate
$SYS on permission flags and cannot be overridden. Keep those flags off device and operator accounts rather than writing your own $SYS rules.Name rules clearly
Name rules clearly
Prefer
DenyRawArea or OperatorControl over Rule1.Next Steps
RBAC with LoT Rules
Groups, precedence deep-dive, cookbook, and Visu access.
Broker Commands
Deploy rules and manage groups via MQTT commands.

