Compliance
The Compliance view lets the operator detect and remediate configuration drift on this rXg or across a fleet. A compliance rule ties a known-good configuration source either a config template or a backend script to a schedule and a set of target nodes. Each time a rule runs, the rXg evaluates the rule against each target and records whether the node is compliant (matches the expected state) or non-compliant (has drifted).
Compliance rules work on any rXg. On a standalone rXg, a rule evaluates the local machine. On a fleet node, a rule created locally evaluates just that node on its own schedule. On a fleet manager, a rule can target remote fleet nodes and drive checks across the fleet from a single place.
Compliance Rules
The Compliance Rules scaffold is where rules are defined. Navigate to System::Compliance to open it.
The name field is a unique identifier for the rule. It appears in health notices, notification events, and the compliance dashboards. Choose a name that reflects what the rule enforces.
The config template field selects a config template whose test-mode run determines compliance. When the template reports zero changes, the node is compliant. Any created, updated, deleted, or failed action on test-mode apply counts as drift. Pick either a config template or a backend script not both.
The backend script field selects a backend script whose standard-output lines are parsed for compliance markers. Pick either a backend script or a config template not both. See Backend Script Compliance Syntax below.
The severity field selects the health-notice severity raised when the rule fails. Options are notice, warning, and critical. Severity does not affect how the check runs, only how failures are reported.
The enabled checkbox, when unchecked, causes the scheduler to skip this rule and the Check Now action to refuse to run. Disable rules to temporarily pause them without deleting the record.
The create health notice checkbox controls whether a failing check raises a health notice at the severity above. Regardless of this setting, a passing check always clears any existing notice for the rule+node pair so leaving notices off for noisy rules still lets pass/fail transitions clear stale alerts.
The check interval field controls how often the scheduler runs the rule. The compliance checks job fires every 30 minutes and skips any rule that has been checked within its interval. Intervals match the config template recurring options (hourly, daily, weekly, etc.).
The fleet nodes field (fleet manager only) selects specific fleet nodes to check. Leave empty to fall back to the config template's own node targeting (for config_template rules) or to self-check the manager (any rule).
The fleet groups field (fleet manager only) selects fleet groups to check. A node that belongs to a selected group is included. Combined with fleet nodes a node selected either way is checked once per evaluation.
The note field is a free-form description shown in the rule list. Use it to record the purpose of the rule, the customer or site context, or links to related documentation.
Check Now and Check All
The Check Now action on each rule forces an immediate evaluation, bypassing the check interval. Each remote node is enqueued as its own background job, so the action returns immediately with a queued message and the per-node results trickle into the Current Status dashboard as each job completes. Refresh the page to watch results land. The same flow applies whether the rule targets a single node or a hundred fan-out scales with the number of available DelayedJob workers rather than an in-process thread pool.
The Check All button at the top of the rule list (shown only when at least one enabled rule exists) fans out a Check Now to every enabled rule at once. It is guarded by a short cache-keyed cooldown so a double-click can't enqueue two sweeps, and the confirm dialog gates the deliberate action. Disabled rules are skipped to include a paused rule in a bulk sweep, enable it first.
A built-in rate limit (default 30 seconds between manual checks of the same rule, plus a per-admin window of 20 manual checks per 5 minutes across all rules) protects against accidental hammering. Scheduled checks via the compliance scheduler are not subject to this limit.
Operator Portal Dashboard
The admin scaffold at System::Compliance is the configuration surface where rules are defined and remediations are launched. The day-to-day operational view lives in the fleet operator portal under Compliance, at /admin/operator_portal/fleet/compliance_rules. That dashboard renders summary cards across the top (overall fleet status, node-by-node pass/fail breakdown, warnings), a sortable and filterable rule list with the per-rule pass/fail pill, and an expand row beneath each rule that drills into the per-node snapshots. The same actions (Check Now, Remediate, Hide/Show Details, Export to CSV) are available without having to leave the dashboard. Per-rule snapshots in the expand row also expose Remediate for individual non-compliant nodes and Remediate All Non-Compliant Nodes for batch remediation. The dashboard is themed for both dark and light operator-portal modes.
Config Template Compliance vs Backend Script Compliance
Config template rules are the preferred mechanism when you want to enforce a concrete configuration specific records existing with specific values. Test-mode execution tells you exactly what would change if the template were applied live, giving you a per-attribute view of drift in the Review & Remediate page. If the template produces zero changes, the node is compliant.
Backend script rules are the right tool when compliance is a computed property something that isn't expressible as records managed by a config template (for example, filesystem state, service status, or a composite rule that inspects multiple subsystems). Because scripts run arbitrary Ruby in the rXg's binding, they can check anything the admin API can see.
Backend Script Compliance Syntax
Backend script rules parse each line of the script's standard output for a prefix. Only prefixed lines count toward the result; other output is ignored.
| Prefix | Effect |
|---|---|
Pass: or OK: |
Counts as a passing test |
Error:, Failure:, or Fail: |
Counts as a failing test (makes the rule non-compliant) |
Warning: |
Informational does not affect compliance but is recorded |
A backend script is compliant when it emits no Error:, Failure:, or Fail: lines. An uncaught exception in the script also fails the check, with the exception text recorded as a failure. The script runs with fleet_node and node (an alias) bound to the rXg being checked, so scripts can query the node's own configuration.
Version Requirements for Remote Checks
When a rule targets a remote fleet node, the required node build depends on the rule type:
| Node Build | Config Template Rules | Backend Script Rules |
|---|---|---|
| >= 16.621 | Fully supported via the native compliance endpoint | Fully supported |
| 16.381 16.620 | Supported via a legacy fallback using the existing execute_config_template endpoint and the audit-trail read API slightly slower but produces the same detailed results |
Not supported; upgrade the node to build >= 16.621 to enable remote backend-script compliance |
| < 16.381 | Not supported; upgrade the node to build >= 16.381 to enable remote compliance | Not supported; upgrade the node to build >= 16.621 to enable remote backend-script compliance |
Nodes whose version limits a rule are indicated in the UI with a yellow (legacy) or red (unsupported) triangle icon next to the node name, with a tooltip explaining the limitation and the minimum version required. The Check Now flash also names any targeted nodes that can't be checked remotely due to their version.
When a check targets a node that cannot run the rule type at its current version, the compliance engine records the result with status set to unsupported rather than error. The Compliance Status dashboard renders these rows with a yellow info icon and the version-floor message inline, and they are excluded from the rule's compliant / non-compliant tally they sit in a separate N unsupported counter so a rule reading "5/5 nodes compliant 1 unsupported" makes clear that the unchecked node hasn't been factored into the pass/fail score. Unsupported results do not raise health notices and do not fire the compliance_check_failed notification event; the operator's only action is to upgrade the node.
The compliance engine itself is part of build 16.621, so creating a rule "locally on the node" is only an option once the node is on at least that build below 16.621 the node has no Compliance Rules scaffold at all, and remote checking (where available) is the only way to evaluate it. The workaround for unsupported nodes is to upgrade them.
Remediation
The Remediate action appears on a rule when at least one node is non-compliant and the rule uses a config template. Backend script rules are not remediable their output determines compliance but doesn't describe what change would fix it.
On a fleet manager with multiple non-compliant nodes, Remediate opens a batch review page that lists the non-compliant nodes, shows the changes each one would receive if the template were applied live, and lets the operator pick which nodes to remediate. Each node panel starts collapsed under the node name click the header to inspect that node's pending changes. On a standalone rXg or a single non-compliant node, Remediate opens a single-node review page.
Before applying the fix, the remediation flow compares the reviewed change set against the most recent compliance check result. If the template's output has drifted since the review because the manager or node configuration has changed in the meantime the remediation is blocked with a drift error and the operator is prompted to re-review.
Applying a remediation always enqueues the work as background jobs one per (rule node) and immediately redirects the operator to a status page that polls every few seconds. Each node's row updates as its job completes, so the operator can watch fleet-wide remediation progress without refreshing manually. After every node finishes, the compliance check service re-runs automatically to refresh the Current Status dashboard, so a successful remediation flips the rule's nodes from red to green within a sweep or two.
Results and History
Each rule evaluation produces a compliance check result row capturing the outcome, test counts, change summary, and any warnings or failures. The Check History nested link on a rule shows all historical results. The Current Status nested link shows the latest result per node use it for dashboard-style views.
The compliance node detail page, reached by clicking a node name in the compliance dashboard, shows every rule targeting that node with its latest result, test score, and any failures or warnings. If the node is version-limited, a banner at the top explains what's unavailable and how to work around it.
A background job (PurgeComplianceCheckResultsJob, runs daily) trims result history older than 90 days so the table doesn't grow unbounded. The job always preserves the results that the dashboard's current-status snapshots currently reference, so the dashboard stays accurate regardless of how far back the history has been trimmed.
For operator-tunable retention, a Database Purger named Compliance History is seeded automatically on first install (default 3 months). It covers both compliance_check_results (the per-evaluation history) and compliance_check_invocations (the node-side async-flow status table) keyed on each row's created_at. Edit it under System::Database Purgers to change retention, or disable purging entirely by setting age to zero. The hardcoded 90-day backstop above is independent keeping at least one of them in place is a good idea so the tables can't grow without bound if the configurable purger is misconfigured.
Notifications and Health Notices
When a rule has create health notice checked, a non-compliant result raises a health notice named compliance_<rule_id>_<node_name> at the rule's severity. A later passing result clears the notice, so the health-notice list is a live roll-up of currently-failing rules. Regardless of the create health notice setting, a failing check also fires the compliance_check_failed notification event wire it into email, Slack, or webhook notifications via the standard Notification Events scaffold. There is no paired "passed" event: passing results clear any prior notice but are not broadcast as notification events, since success of a routine check is rarely actionable.