45. Agent 2.1.10.s: hardening telemetry, host inventory and audit setup
This guide describes Lawliet 1.5.14.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.
Agent 2.1.10.s (Linux and Windows) adds what the hardening program reads from the hosts:
| What | Used by |
|---|---|
| Hardening telemetry: who still uses what a control would remove (NTLM, SMB1, LDAP binds, old TLS, Kerberos RC4, PowerShell 2.0, logons by type, ...) | The planner's breakage prediction (41.3) and its guards (41.4) |
| Change records: policy, registry, Group Policy and file changes, with the account that made them | Drift attribution: who changed an enforced control (23.3) |
| Host inventory: processes, services, packages, ports, flows, tasks | The do-not-disrupt baseline (chapter 42) |
| Cloud and VM identity | Linking hosts to AWS instances and vSphere VMs (chapter 46, chapter 47) |
A 1.5.14.s server works with 2.1.9.s agents (they ignore the new settings) and offers them 2.1.10.s through the signed upgrade (10.8). macOS agents collect nothing new.
The agent collects only the signals the server's signed heartbeat policy names. Nothing is collected for a signal you switch off (45.6).
45.1 What the agents collect#
Windows (counted per hour over a few fields; never document names, file names or values that are secrets):
| Signal | Events |
|---|---|
| NTLM use | NTLM 8001-8004 (outgoing, incoming, domain) |
| SMB1 use | SMB server 3000 |
| LDAP signing and channel binding (DCs) | Directory Service 2887, 2889, 3039 |
| Kerberos | 4769 service tickets (RC4/DES ones on DCs; all tickets only while an audit step needs them), 4768 RC4/DES, ticket caches of logon sessions (hourly, other hosts) |
| TLS (SChannel) | 36880, 36874 |
| PowerShell | 4104 script blocks (hash and size only; the text only with HARDENING_TELEMETRY_POWERSHELL_CONTENT=true on the server), PowerShell 2.0 engine starts 400 |
| Who changed policy (no values) | Security 4719, 4739, 4907, 4657, 5136, 5137, 5141; Group Policy 1502, 1503 |
| Logons | 4624 per account, logon type, source and package; whether the token was an administrator's |
| Attack Surface Reduction, Defender | 1121, 1122; controlled folder access and network protection audit hits 1124, 1125 |
| Code integrity | 3076, 3077 |
| Devices and storage | 6416 device installs, 4663 removable storage access (account and program, never the file name) |
| Coercion RPC calls | 5712 (efsrpc, dfsnm interfaces) |
| Others | Computer account creation 4741, vulnerable Netlogon channels 5829-5831, print jobs 307 (user, client, printer - never the document name), Windows LAPS 10018/10020, browser extensions, local firewall rules, Thunderbolt/USB4/FireWire devices, macro-enabled Office files in user folders (daily, only while an audit step needs it), DNS zone transfers and non-secure updates, SMB client dialects (every 10 minutes) |
| Guard facts | An hourly snapshot of the facts the Windows guards read (replication, domain, BitLocker, print, IIS, WINS, SNMP, DNS, network profiles, devices, Defender exclusions, ...), and the holders of the user rights the controls narrow |
For the planner and drift, Windows agents also ship the NTLM, SMB1, Directory Service and PowerShell channels for those event ids only (script text and PowerShell command lines left out).
Linux: SSH logins by method and outcome (the name typed for an account that does not exist is never kept), sudo use (the program only, no arguments), su sessions, auditd records for the lawliet-* keys and the common CIS keys, kernel module loads, connections by service, class and port, listening sockets, filesystem types, PAM failures, password ages (ages only), new set-uid programs, programs run from /tmp, user namespaces, USB storage attach, SCTP, rsyslog errors, martian and forwarded packets, audit record and loss rates, AppArmor events, SSH forwarding channels, and changes to system program and library directories.
Coverage. For every signal the agent collects it sends a coverage marker at least every 6 hours. A signal whose audit setting is off is reported as audit_off, so "no events" never reads as "nobody uses it".
Limits. Counts are kept per hour, at most 500 field sets per signal and hour, held up to 48 hours on the host while the server is unreachable, sent at most 500 records per request. The server refuses any field a signal does not have, answers 429 (Retry-After) under load, and keeps telemetry for 90 days (RETENTION_HARDENING_TELEMETRY_DAYS).
Host inventory. A full report at start and every 24 hours, changes at most every 5 minutes, bounded per kind (42.1).
Cloud and VM identity. The agent reports which cloud instance or VM it is: AWS through IMDSv2 only, with the signed instance identity document; Azure with the attested document; GCP metadata; VMware, Hyper-V and KVM from SMBIOS. Detection runs in the background with short timeouts and is cached for a day. An AWS instance id is believed only from a document whose AWS signature verifies, never from the agent's own claim.
45.2 Viewing what is collected (API)#
| Call | Permission | Returns |
|---|---|---|
GET /api/v1/hardening/telemetry/signals | View hardening | Every signal, its platform, fields, purpose and whether it is on |
GET /api/v1/hardening/telemetry/aggregates | View hardening | The hourly counts per host and signal |
GET /api/v1/hardening/telemetry/coverage | View hardening | Per host and signal: collecting since, state (ok, audit_off, partial) |
In the console the same data shows up in the planner's breakage prediction and guard explanations.
45.3 Audit setup for drift attribution (what the agent changes on the host)#
To say who changed an enforced control, the host must log the change. With HARDENING_TELEMETRY_AUDIT_SETUP=true (the default) the agent sets up that audit coverage, for the controls enforced on its host only:
| Platform | What the agent changes |
|---|---|
| Windows | An audit entry (SACL: Everyone, Set Value / Create Subkey / Delete, success) on each registry key an enforced control writes, so changes produce event 4657; the policy-change audit subcategories (Audit Policy Change; Directory Service Changes on DCs; Registry) |
| Linux | An auditd watch on each file an enforced control writes (-w <path> -p wa -k lawliet-hardening), reloaded when the set of enforced controls changes; log_format=ENRICHED so records carry the user name |
Only the agent's own entries are ever removed; an entry someone else made is left alone. Risk: slightly more events in the Security log (Windows) or the audit log (Linux). To turn it off for every agent: set HARDENING_TELEMETRY_AUDIT_SETUP=false in .env and run sudo ./lawliet start. Drift records then cannot name who made a change ("No change event recorded for this setting in the window").
45.4 Audit settings the agent switches on for an audit step#
Some signals need an audit setting that is off by default. While an audit step that names the signal is open on the host (41.5), the agent switches the setting on, records what it found, re-checks it daily (switching it on again if a Group Policy took it away) and switches it back when the step closes.
| Setting | Log | Notes |
|---|---|---|
| Audit Kerberos Service Ticket Operations | Security | Domain controllers only; high volume |
| Audit Kerberos Authentication Service | Security | Domain controllers only; high volume |
| Audit Computer Account Management | Security | Domain controllers only |
| Audit PNP Activity | Security | |
| Audit Removable Storage | Security | |
| Audit RPC Events (+ the RPC audit filters of the coercion audit control) | Security | |
| NTLM auditing: outgoing, incoming | NTLM/Operational | |
| NTLM auditing in the domain | NTLM/Operational | Domain controllers only; high volume |
| LDAP interface diagnostics | Directory Service | Domain controllers only; high volume |
| SChannel event logging | System | High volume |
| SMB1 access auditing | SMBServer/Audit | |
| Print Service operational channel | PrintService/Operational |
PowerShell script block logging is never switched on this way (script text would land in the event log).
When the agent refuses (nothing changed; the signal stays audit_off, and the planner names the reason):
- the log keeps its events (retention or auto-backup on): new events would be lost once it is full;
- for a Security setting, CrashOnAuditFail is on: a full Security log would halt the host;
- the domain controller log-volume rule: a high-volume setting (every ticket, TLS handshake, LDAP bind or domain NTLM authentication) is refused while its log is smaller than 1 GiB, unless a second administrator accepted the volume for that audit step (41.5). The retention and CrashOnAuditFail refusals hold in every case. Enlarging the log is the better fix:
wevtutil sl Security /ms:1073741824(or the Group Policy event log size), and the agent switches the setting on at its next daily check.
Switching back happens when the step is cancelled, the control is enforced, the step is 30 days old, collection or the audit setup is turned off, the agent is uninstalled, or the server no longer knows the agent. For each setting the agent reports:
| Result | Meaning |
|---|---|
restored | The setting was exactly as the agent left it and no Group Policy sets it: the audit bits it added are cleared (bits someone else set stay), a registry value goes back to its prior value (or is removed), SMB1 auditing or the channel is switched off |
left: changed since | Someone changed it after the agent; left alone |
left: managed by Group Policy | A GPO sets it; left alone |
gone | Someone already switched it off |
preexisting | It was already on before the agent; never touched |
A switch that someone turned on by hand after the agent, without a Group Policy, cannot be told apart from the agent's own and is switched off.
On uninstall both installers and the console's uninstall command run the agent's audit teardown before the agent's folders are removed. What could not be put back is kept with a revert script and the installer says so:
- Linux: "Some audit settings could not be put back (see /var/lib/lawliet/telemetry.json.audit)."
- Windows: "Some audit settings the agent switched on could not be put back. They are recorded in HKLM\SOFTWARE\Lawliet\AuditRevert; as an administrator run: C:\Program Files\Lawliet Audit Revert\revert-audit.ps1". Every Windows install places
revert-audit.ps1in the agent's folder (the installer and the MSI); the uninstall keeps a copy under%ProgramFiles%\Lawliet Audit Revert, where only administrators can write. Run it in an elevated Windows PowerShell (powershell -ExecutionPolicy Bypass -File "C:\Program Files\Lawliet Audit Revert\revert-audit.ps1"): it checks that only SYSTEM and Administrators can change the record key, puts back each recorded setting that is still as the agent left it and not set by a Group Policy (one line per setting:restored,left: ...), and prints "Nothing recorded." when there is nothing to do. A later agent installed on the host also takes the record back.
45.5 Server settings#
Set in .env in the installation directory, then sudo ./lawliet start (10.5 explains host-side settings).
| Setting | Default | Meaning |
|---|---|---|
HARDENING_TELEMETRY_ENABLED | true | false: no agent collects hardening telemetry. Breakage predictions become unknown |
HARDENING_TELEMETRY_POWERSHELL_CONTENT | false | true: agents send PowerShell script block text (at most 4096 characters, obvious secrets masked). Script text can hold credentials: it is the host operator's decision |
HARDENING_TELEMETRY_AUDIT_SETUP | true | false: agents change no audit setting, neither for drift attribution nor for audit steps |
RETENTION_HARDENING_TELEMETRY_DAYS | 90 | How long hourly counts are kept |
PLANNER_ENFORCE_WINDOW_DAYS | 30 | The usage window every enforce reads (never below 30) |
HARDENING_PENDING_EXPIRY_HOURS | 24 | A hardening run still waiting for approval after this expires |
HARDENING_NTLM_AUDIT_MIN_DAYS / HARDENING_NTLM_AUDIT_MAX_AGE_DAYS | 7 / 14 | NTLM restriction needs this many days of NTLM auditing, from data no older than the max age |
FRAMEWORK_RESULT_MAX_AGE_DAYS | 30 | Passes older than this count as not assessed in framework scores |
Maximum telemetry while Under Attack (1.5.14.s)#
Not available in this release. No agent in this build applies it, so an Under Attack plan cannot turn it on and a plan stored with it on is treated as off; it is sent only to agents that report they support it, and none does yet. What follows describes it for a later agent.
A host in the scope of a live Under Attack activation whose plan has maximum telemetry on collects every signal of its platform, the on-demand ones included, every 30 seconds, and sends every minute - even when HARDENING_TELEMETRY_ENABLED is false (the plan was approved by two people). It never overrides the licence, and HARDENING_TELEMETRY_POWERSHELL_CONTENT still decides whether script block text is sent. It is one change per host in the activation's ledger; when the activation ends (or that change is rolled back) the host returns to the signals the settings give it.
45.6 Switching signals on or off (API)#
Permission: Manage compliance. Four-eyes: no - except that switching off a signal drift attribution relies on also takes down the audit setup on the hosts, so it needs Run hardening too and a second administrator ("Execute remediation"). Sandbox accounts cannot change it. Every change is audited and reaches the agents with their next heartbeat.
PUT /api/v1/hardening/telemetry/settings
{"signals": {"<signal name>": false}}Risk: a signal switched off makes the planner's predictions that need it unknown, which blocks or needs acknowledgement on enforce. Rollback: switch it on again.

