57. Hardening batches: many controls on many hosts, one approval
This guide describes Lawliet 1.5.15.2.s (the current release). Screens, commands and procedures may change in later versions; the usage guide is updated with each release. Check the version your server runs under Settings > Platform or with ./lawliet version, and see the Releases page for what changed.
A batch hardens a set of hosts with a set of controls in one request. It is approved once, under exactly the approval policy of a single live run, and every host then starts at the same time. Each host runs an ordinary hardening run (chapter 26): the same checks when the batch is created and again when it is approved, the same validation (a control is marked compliant only after the host passes the check again), the same rollback. One host failing never stops the others.
A batch is started from two places:
- Hardening > Planner, after Plan N hosts (57.2);
- a completed scan's Fix plan (57.3).
It is followed, approved, cancelled and rolled back on the Hardening page, under Batches (57.4 - 57.6).
| Task | Permission | Four-eyes |
|---|---|---|
| Create a batch (live or dry run) | Run hardening | no - a live batch waits for approval; a dry run needs none |
| Approve a batch | Run hardening | as a single run: yes when dual control is on for "Execute remediation"; with a lockout risk accepted, never the person who requested it |
| Roll back a batch, or one host of it | Run hardening | yes - "Execute remediation" |
| Cancel a batch | Run hardening | no |
| See batches and their hosts | View hardening | - |
Limits: up to 500 hosts and 1000 controls in one batch (a whole profile fits: the largest built-in profile has 533 controls).
57.1 What a host runs, and what it skips#
You choose controls and hosts; each host runs only what applies to it. Every control a host does not run is listed under that host as skipped, with the reason - nothing is dropped silently:
| Reason shown | Meaning |
|---|---|
| "no result for this host in scan N (another OS or benchmark)" | The scan has no result for the control on that host - for example a Windows control on a Linux host |
| "not in this host's results (another OS or benchmark, or not scanned yet)" | Planner batch: the host's latest results do not include the control |
| "does not apply to this host: ..." | The catalog says the control is not for that role or OS version |
| "already passing on this host" | The control passes there; a batch runs only the failing ones on each host |
| "not assessed on this host: nothing measured to fix" | The scan could not read the control on that host |
| "GUARD_BLOCKED: ...", "ORDER_BLOCKED: ...", "AUDIT_STAGE_REQUIRED: ...", "BREAKAGE_PREDICTED: ...", "ALREADY_REQUESTED: ..." | The planner's checks refuse it on that host now (41.4). Fix the cause, or work on that host in the planner (stage the audit, acknowledge breakage, override with approval) |
| "refused by the access guards: ..." | The change would cut how Lawliet reaches the host, or needs per-host input it was not given (26) |
| "No remediation script available", "Control status 'compliant' not eligible for hardening" | The run could not build a step for it on that host |
A control that can lock an operator out, or one that breaks how Lawliet reaches a host, is not skipped: the whole batch is refused until you accept the risk (57.2 step 6).
57.2 Procedure: enforce from the planner#
- Open Hardening > Planner, click the hosts (up to 500) and press Plan N hosts (41.1).
- Under the summary line, the picker lists every control failing on at least one of the hosts, grouped by section (the catalog family: ssh, auditd, kernel, ...). Each row says "fails on K/N".
- Choose the controls with any of:
- Select all failing - every control failing on any chosen host (each host runs only the ones failing there);
- a section checkbox - ticks or clears the whole section; it shows a dash when only part of the section is ticked;
- the Filter controls box, any severity and any section lists, then Select all visible (N) - adds what the filter shows (what is ticked and hidden stays ticked);
- Standard profile / Strict profile - every control of that catalog level (40.2); the buttons appear only when the controls carry the level;
- single control boxes; Clear to start again.
The count on the right reads "N controls x M hosts".
- Press Enforce on M hosts, or Audit on M hosts (dry run) to see what each host would run without changing anything (a dry run needs no approval).
- What you see: "Batch #id: waiting for approval - K of M hosts have work, S control(s) skipped with a reason." and one line per host, "host: N to run, S skipped", then Open Hardening to approve. Nothing has changed on any host.
- If the batch is refused:
- a control that can lock you out: the lockout box names each control, its risk, the hosts and the recovery to take first; issue the recovery artifacts (26.5), type the phrase and confirm;
- "These controls break how Lawliet reaches some hosts": each control and host with what breaks and what to change first; change it first, or tick I accept that these changes break how Lawliet reaches those hosts. and press Go ahead;
- "No selected control can run on any chosen host." with the reasons per host: nothing was created.
57.3 Procedure: start hardening from a scan's Fix plan#
- Open the completed scan. Fix plan says "N fixable here, K need a manual change".
- Hosts (M of M): every host the scan covered is chosen. Click a host to leave it out.
- Choose the controls with the same tools as 57.2 step 3. Every fixable control of the scan is listed (by section); the quick fixes failing on a chosen host are ticked to start with.
- For an NTLM deny control, type the servers that may keep NTLM on every chosen host; for the WinRM address filter, the addresses WinRM may still accept (both apply to every chosen host). To review the NTLM uses each host saw, use One host in detail below the Fix plan (22.4).
- Press Start hardening on M hosts (or Dry run on M hosts). The result and refusals are as in 57.2 steps 5 and 6.
57.4 Procedure: approve a batch (four-eyes)#
- Open Hardening. Batches lists each batch: number, live or dry run, its state, "N controls x M hosts", the applied / failed / skipped counts and where it came from.
- Press Approve batch, then Confirm: change M hosts now.
- The same policy as a single run (26.2): with dual control on for "Execute remediation", the request is held - give the reason, a second officer signs it in Approvals, and the person who asked presses Execute now there (appendix B). With dual control off, your confirmation starts it. A batch whose lockout risk was accepted is never approved by its requester alone: "This batch accepts a lockout risk and needs a second administrator: it cannot be approved by the person who requested it."
What you see: every host starts at once; the state becomes executing, then completed, partial, failed, or applied, awaiting restart while changes wait for a host restart. "N hosts need a restart before the changes are validated." counts those hosts; each such host shows restart pending. The changes are validated after the host restarts.
A host whose checks refuse at the moment of approval (the host changed since the batch was created), or whose wait expired, is cancelled and shows why; the other hosts run.
57.5 Reading the hosts of a batch#
Press Batch #id to open it. One row per host: its state, "N applied, N failed, N skipped", "N waiting for approval" before the approval, restart pending when it applies. Press the host name for every control: its step state (and error), and each skipped control with the reason.
57.6 Procedure: roll back or cancel a batch#
- Roll back batch > Confirm: roll back M hosts: every host's applied changes are rolled back (four-eyes, as above). Roll back host on a host row (press it twice) rolls back that host only. "Nothing to roll back" when no host has a change that can be reverted.
- Cancel batch > Confirm cancel: stops every host's commands not yet delivered; a command already on a host cannot be recalled, and its result is recorded but not acted on.
Rollback works as for single runs (26.3): the host reads rolled back only once its agent confirms; a later scan shows the actual state.
57.7 API#
| Call | What it does |
|---|---|
POST /api/v1/hardening/batches | Create: source (scan with scan_id, or planner), control_ids, agent_ids, selection (failing or explicit), is_dry_run, accept_lockout_risk, accept_dependency_risk, optional ntlm_exceptions, winrm_ip_ranges |
GET /api/v1/hardening/batches, GET .../batches/{id} | List, and one batch with every host's steps and skips |
POST .../batches/{id}/approve | Approve (four-eyes) |
POST .../batches/{id}/rollback | Roll back; body {"agent_ids": [...]} for chosen hosts, {} for all (four-eyes) |
POST .../batches/{id}/cancel | Cancel |
GET .../batches/scan-options/{scan_id} | The hosts of a scan and its fixable controls with where each fails |
Each create, approval, rollback and cancel is in the audit trail (hardening_batch, hardening_batch_rollback). A run of a batch cannot be approved on its own: "Execution N is part of batch M: approve the batch."



