Skip to main content
PathMon

Chapter 16 of 26

Compliance Results and Remediation

Updated Read the full guide

Once a compliance scan completes, results appear in three layers of the web UI: the fleet-wide dashboard, the per-host Compliance tab, and the per-rule Rule Detail page. This page walks through each layer in operator terms, then covers the optional auto-remediation paths and the compliance trends view.

You need can_view_reports to see any of this; can_manage_compliance to trigger remediation.


Fleet-Wide Dashboard

The Security Compliance landing page opens on the Overview tab, which is the fleet-wide dashboard. It's designed to answer "how is my overall compliance posture, and where do I look first?" in a single glance.

The five summary cards

Across the top of every Compliance page view sit five identical cards:

Card What it counts Derived from
Total hosts total_hosts + unscanned: every host with compliance visibility, scanned or not summary.total_hosts + summary.unscanned
Compliant Hosts whose latest scan score is ≥ 80% summary.hosts_compliant
Warning Hosts whose latest scan score is between 60% and 79% summary.hosts_warning
Critical Hosts whose latest scan score is < 60% summary.hosts_critical
Never scanned Hosts that have never successfully submitted a scan summary.unscanned

The Never scanned card is clickable, it toggles a filter on the Hosts tab to show only never-scanned hosts, which is the fastest way to find coverage gaps.

Six charts

The Overview tab grid has five charts:

  • Failures by Severity: stacked doughnut of critical / high / medium / low failed rules across the fleet. Clicking a slice deep-links into the Scan Results tab filtered to that severity.
  • OpenSCAP Distribution: split of pass / fail rules across OpenSCAP scans.
  • Compliance Profiles: pie of scans by profile type (OpenSCAP vs Docker Bench). Clicking drills into the matching filter.
  • Last Scan Age: distribution of when hosts were last scanned (today / this week / this month / older).
  • Host Compliance Status: bar chart of hosts by Compliant / Warning / Critical / Never Scanned.

All charts refetch every 2 minutes (or every 30 seconds when there's at least one active scan) so the dashboard stays useful for an operator who leaves the page open during a rollout.

Profile-type filter

Above the charts is a profile type filter with three values: All Scans (default), OpenSCAP, Docker Bench. Switching to OpenSCAP or Docker Bench reveals additional profile-specific panels:

  • OpenSCAP Analysis: Rule Results doughnut, Failures by Severity bar, Score Distribution, Scan Freshness.
  • Docker Bench Analysis: Rule Results doughnut (pass vs warning), Warnings by Section bar (broken down into the CIS Docker Benchmark sections), Score Distribution, Scan Freshness.

The Docker Bench view intentionally uses "Warnings" instead of "Failures" because Docker Bench's status model is pass-or-warning for most checks, not pass-or-fail.


Hosts Tab: Per-Host Fleet View

The Hosts tab shows a row per compliance-enabled host. This is your work list, sort and scan from here.

Column What it shows
Run Green Play button (trigger scan) or red Stop button (cancel scan).
Host name Friendly name (clickable, opens Compliance Host Detail).
Status Shield icon colour-coded: green ≥80%, yellow 60-79%, red <60%, grey never-scanned.
Last activity Friendly date of last scan and activity label ("Scan", or "Scanning…" while active).
Passed / Failed / Skipped Click the count to deep-link into the Scan Results tab, filtered by this host and that status.
Scanner status Scanned, Enabled, or -; whether the agent has actually produced a scan, has the scanner enabled without results, or has no scanner integration active.
Mode Scheduled, On-demand, or Disabled: this host's compliance_mode.
Scanners Which scanners are enabled per host: OpenSCAP, Docker, OpenSCAP, Docker, or -.

Clicking any Passed / Failed / Skipped number pivots you straight into the Scan Results tab with the host and status filters applied, so "click the 12 Failed for hostA" gets you a filtered rule list for that host's latest scan.

The page also respects the tableFilter override driven by the Never scanned summary card, click that card and the table filters to hosts with no scan records.


Scan Results Tab: Rule Drill-Down

The Scan Results tab (also reachable via the per-host clicks described above) is where you investigate specific rules across the fleet. It shows every rule that has been evaluated by any scanned host, with:

  • Rule title, rule reference (e.g. xccdf_org.ssgproject.content_rule_...), section (CIS section number for OpenSCAP, bench section for Docker Bench).
  • Severity badge (critical / high / medium / low / unknown).
  • Profile type badge (OpenSCAP / Docker Bench).
  • Hosts passed / failed / warned / total across the fleet.

Filters above the table: status (pass / fail / warn / error / skipped), severity, profile type, specific host, and full-text search. These all push down to GET /api/v1/compliance/rules so the filtering is server-side and consistent with the dashboard drill-down links.

Click any rule to open Rule Detail.


Rule Detail: Single Rule Across the Fleet

The Rule Detail page (/compliance/rules/{ruleId}) is what you open when you want to understand "what is this rule, why is it failing, how do I fix it, and which hosts does it affect?".

It has four sections:

1. Summary cards

Four cards at the top: Affected Hosts, Passing, Failing, Warnings, counts across the fleet for the rule's latest scan per host.

2. Description

The human-readable explanation from the benchmark, expanded in full. For OpenSCAP rules this is the SCAP <Description> element; for Docker Bench it's the rule prose from the benchmark.

3. Why this failed (Rationale)

The benchmark's rationale for why this rule exists, why it matters, what risk it mitigates. Shown as plain text.

4. What the fix does + Remediation

The right column contains two panels that help operators act on a failure:

  • What the fix does: a short plain-English explanation of the remediation, derived heuristically from the remediation text (for example, "This fix will update file permissions or ownership…" when the script uses chmod / chown; "This fix will update SSH daemon configuration…" when the script touches /etc/ssh). This is UI scaffolding, not audit-grade. Always read the actual remediation script below.
  • Remediation: the exact script the scanner would run. For OpenSCAP rules this is the shell fix pulled from SSG. For Docker Bench it's the benchmark-prescribed command. A Copy button copies the script to your clipboard so you can paste into a change ticket or runbook.

If the benchmark doesn't ship a remediation script (common for high-level "document this" rules), the panel reads "No remediation steps available."

5. Affected Hosts table

Every host that has evaluated this rule shows up here with:

  • Host name (click to open Compliance Host Detail).
  • Status for this rule on this host (Pass / Fail / Warning / N/A / Skipped / Error).
  • Why (this host): either the scanner's finding text, or a Current: X → Required: Y string built from actual + expected. This is the concrete reason why this host failed, which is usually enough to diagnose without opening a shell.

Use this view to scope impact: "this rule fails on 14 hosts; is it the same root cause on all of them?" Sort by the status column, look for clusters of identical finding text, and fix them as a batch.


Compliance Host Detail

The per-host compliance view (/compliance/hosts/{hostId}) is reached by clicking any host name across Compliance. Its layout:

  • Header: back link, Shield icon, host name as H1, Run Scan button with connection-status pill, link to Full Host Details.
  • Five summary cards: Passed, Failed, Warning, N/A, and Score (or recent scan metadata).
  • Scan Results table: paginated at 25 rows per page, drilled into the most recent scan for this host by default, filterable by status and severity.
  • Inline rule actions: each failed rule row has an expand button that shows the Why / Rationale / Remediation inline, plus a "Remediate this rule" button (see below).

Filters on the five summary cards: click the Passed rules card to filter results to pass-only, click Failed for fail-only, etc. The card selected gets a coloured ring so you know the active filter.

The scan shown is the latest per-profile. A profile-type filter above the table lets you flip between the latest OpenSCAP scan and the latest Docker Bench scan for the host. If the latest scan is older than a week, a soft warning reminds you that the results may be stale.


Auto-Remediation

There are two remediation paths, each driven from a different part of the UI.

1. Per-rule on-demand remediation

Fix a single failed rule without running a full scan.

  1. Open Compliance Host Detail for the host.
  2. In the Scan Results table, expand a failed rule.
  3. Click Remediate this rule.
  4. The UI calls POST /api/v1/compliance/remediate/{hostId} with { "rule_id": "<rule-ref>" }. The server validates that the agent is connected and sends a remediate_rule WebSocket message to the agent.
  5. The agent runs oscap xccdf eval --remediate --rule <rule> against the SSG datastream, that runs OpenSCAP's targeted remediation script for just that one rule.
  6. The UI shows a toast "Remediation triggered". The next scan (manual or scheduled) should show that rule flipping from Fail to Pass if the fix was successful.

Per-rule remediation is limited to OpenSCAP rules today. Docker Bench does not ship executable remediation scripts in the benchmark. The UI greys out the Remediate button on Docker Bench rules for this reason.

2. In-scan remediation

Apply remediation scripts for every failing rule as part of a scan.

  • From the Run Scan dialog on Host Detail, tick Enable Remediation before starting the scan.
  • From the Bulk Compliance Scan modal (Compliance page), tick Enable Remediation before triggering the batch.

When enable_remediation=true is set on the trigger, the agent runs OpenSCAP in --remediate mode, which attempts the remediation fix for every rule that fails. The scan results submitted back to the server include a remediation_applied / remediation_count summary so you can tell the difference between a regular scan and a remediating scan.

When to use which

  • Per-rule: tightly-scoped changes, especially on production where you want to see exactly one thing change at a time. Safer, slower.
  • In-scan: bulk cleanup on a newly-built host, or a lab environment you just rebuilt and want to harden in one pass. Faster, but applies every fix, review the affected rule set first.

Warning: Some OpenSCAP remediation scripts are destructive. They can change SSH configuration, disable protocols, modify PAM settings, or set kernel parameters that break unrelated tooling. Always test in-scan remediation on a non-production host before rolling it across the fleet. Per-rule remediation is safer because you've read the script first.

Release-note lineage

Auto-remediation was introduced in 1.4.0 ("Optional auto-remediation of failed rules during scans"). In 2.0 it remains under the Compliance module, it did not move into the Patching module. If you're reading older release notes, per-rule remediation still runs through POST /api/v1/compliance/remediate/{hostId}, not through a patch run.


GET /api/v1/compliance/trends/{hostId}?days=30 returns the host's scan history as a time series: completed_at, score, profile_name, profile_type for each scan in the window. The UI uses this to show trend lines on Compliance Host Detail.

The API supports days between 1 and 365. Typical use is the default 30 days for day-to-day monitoring, or 365 when writing an annual compliance report.


History Tab: Chronological Scans

The History tab is a flat list of every scan the system has ever recorded, newest first. Paginated at 25 per page, filterable by status, profile type, and host.

Each row shows:

  • Host name.
  • Profile (e.g. level1_server OpenSCAP, or Docker Bench for Security).
  • Started at and duration.
  • Totals: total rules, passed, failed, warnings, skipped, not applicable.
  • Score and any error message.

Scans that were auto-cancelled after the 3-hour stall threshold appear here with the error message "Scan terminated automatically after running for more than 3 hours" and a status of cancelled, useful for spotting hosts that consistently time out.

There is no export endpoint for scan history. To archive scans for regulators, call GET /api/v1/compliance/scans/history directly and write the JSON to disk.


Notifications for Scans

Every completed scan emits a compliance_scan_completed notification event. The notification body includes:

  • Fleet-friendly title: Compliance Scan - <hostname> (- N Failed Rules suffix when failures are present).
  • Per-profile summary lines: profile name, score as a percentage, passed count, failed count.
  • Structured metadata for downstream processing: host ID, host name, failed count, passed count, total rules, profile summaries.

Default severity is informational, escalated to warning when there's at least one failed rule. The per-event alert settings let you override severity or suppress these if you already have a dashboard.

A separate compliance_scan_failed event is emitted for each sub-scan that errored during a multi-scanner run (e.g. OpenSCAP succeeded but Docker Bench failed). Default severity is error. Metadata includes the profile name, profile type, and the captured error.


Practical Workflow

A typical compliance cycle in PatchMon looks like:

  1. Baseline, turn compliance on across the fleet (Default Compliance Mode = On-Demand, then enable per host) and bulk-scan everything once to build the baseline. Expect a lot of failures; that's the starting point.
  2. Triage, open the Overview tab. Use Failures by Severity to find critical failures; click through to the Scan Results tab filtered to critical.
  3. Investigate, on each rule, open Rule Detail. Read the rationale, read the remediation, pick a handful of identical-finding hosts and fix them manually or via per-rule remediation.
  4. Rescan, on each fixed host, click Run Scan. Confirm the rule flipped to Pass.
  5. Enable scheduling, once the baseline is clean, switch compliance_mode=enabled on the hosts that care, set the scan interval to 24h (or whatever suits your SLO), and leave it running. The dashboard becomes your ongoing signal for drift.
  6. Revisit: the Scan Freshness chart on the OpenSCAP / Docker Bench tabs tells you which hosts haven't scanned recently; bring those back into the loop.

  • Compliance Overview: scanner architecture, permissions, module gate.
  • Running Compliance Scans: triggering, cancelling, scheduling, stuck-scan handling.
  • Docker Monitoring: the Docker integration prerequisite for Docker Bench scans.
  • Alerts and Notifications: routing compliance_scan_completed and compliance_scan_failed events to your destinations.
  • Release Notes - 1.4.0: introduction of auto-remediation.