Skip to main content

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.
Like writing house rules on a whiteboard. Each rule says “IF you are on the approved list, THEN you may enter the room—ELSE the door stays locked.” LoT rule syntax works the same way: you name the rule, pick the door (scope), and write the condition.

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:
Keep the entire header on one line. Indent the body one level (4 spaces); nest ALLOW/DENY under IF/ELSE another level. A single-line THEN ALLOW ELSE DENY body is rejected.
Unconditional forms are valid too:

Conditions

Rules evaluate conditions to decide whether to ALLOW or DENY an operation.

User Identity Checks

Group Membership

Group lookup is case-insensitive. See RBAC with LoT Rules for group management commands and patterns.

Permission Flags

These are the three broker permission flags. Prefer groups for fine-grained topic access rather than inventing custom flag names.

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:
With this rule, client 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:
Character classes such as [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 (no ELSE) compiles with an implicit ELSE DENY — anyone not matching <condition> is denied at that priority band.
  • IF <condition> THEN DENY (no ELSE) compiles with an implicit ELSE ALLOW — anyone not matching <condition> is allowed at that priority band.
  • An IF … ELSE IF … chain without a final ELSE likewise returns the opposite of the branch verdict when no condition matches.
Because the winning priority band decides the request and lower-priority bands are not consulted once a stronger band matches, an 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.
Do not try to tighten or loosen a management gate with a custom rule. The locked built-in always wins, and -addRule rejects both a priority below 100 and any attempt to reuse a built-in rule name. Change who can perform these operations by setting permission flags with -changeUserSettings instead.
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

Use Publish and Subscribe with TO TOPIC:
The broker ships catch-alls at the weakest priority (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:
System topics ($SYS/#) contain sensitive broker information and command interfaces. Rely on the locked built-ins rather than writing your own $SYS subscribe rules, and never grant $SYS access to untrusted clients.

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:
  1. If any rule in that band evaluates to DENY → deny (deny-wins)
  2. Else if any allows → allow
  3. If no rule matches → deny (default-deny)
A rule never abstains: if its 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.
Use a lower priority number than the rule you intend to override. Because the seed catch-alls sit at 1 000 000, any rule in the user band is already enough to restrict a subtree — start broad rules at 1000 or higher so you have room to carve out exceptions later.
For cookbook patterns, Visu RBAC, and default-rule tiers, see RBAC with LoT Rules.

Complete Examples

Operators and supervisors share a plant namespace; only supervisors may emergency-stop:

Best Practices

Use USER IN GROUP for data and panel access. Reserve permission flags for system-level capabilities.
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.
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.
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.
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.
Last modified on October 25, 2026