Restrict non-compliant devices with endpoint posture
When you need this
Section titled “When you need this”You run an endpoint agent (everwas, formerly OpenRMM) that assesses each machine’s compliance (disk encryption, firewall, antivirus) and you want a device that fails a check you care about to be moved to a remediation VLAN at 802.1X time instead of joining the network normally.
This builds on 802.1X in monitor mode: the RADIUS decision path already knows how to assign a remediation VLAN, and the security model covers how these access-control decisions fail safe. Posture ingress supplies the missing input, which check results a machine is reporting, so that path can act.
The whole feature is off by default and gates nothing until you name the checks that should restrict access. Turning it on changes no behavior until you opt a check into gating, and enforcement is per-switch on lab gear first, exactly like the rest of the access-control plane.
Before you start
Section titled “Before you start”- 802.1X monitor mode working against a lab switch.
- A remediation VLAN id on that switch (a network with enough reach to fix the device: patch server, agent endpoints, DNS).
- The everwas agent publishing posture reports to your NATS bus. The agent owns identity (a device UUID) and the checks; l2trace owns which failures restrict access.
1. Decide which checks gate, starting with none
Section titled “1. Decide which checks gate, starting with none”A check gates when its name or its category is named in
POSTURE_GATING_CHECKS (comma-separated). Matching on the category means a policy
written against encryption keeps covering the machine when the agent adds a
fifth encryption check.
Start empty and observe. With no gating checks named, ingress records every report but restricts nothing:
POSTURE_INGRESS_ENABLED=truePOSTURE_GATING_CHECKS= # empty: nothing gates yet (fail-open)Once you have watched real reports land (step 4), name the checks or categories that should restrict access:
POSTURE_GATING_CHECKS=encryption,firewallAn absent or not-assessed gating check never gates. Only a present,
fresh fail on a gating check remediates. A newly added gating check therefore
has no effect until machines report it, which is correct: it must not remediate
the fleet the instant you edit the policy.
2. Set the remediation VLAN
Section titled “2. Set the remediation VLAN”RADIUS_REMEDIATION_VLAN=999 # the "fix me" network on your lab switchIf this is unset, a failing device is simply accepted with no VLAN change (fail open, no move), so a missing VLAN never cuts a device off by accident.
3. Point the agent at the posture subject
Section titled “3. Point the agent at the posture subject”l2trace consumes reports from a dedicated NATS subject, deliberately off the per-device event bus (posture is keyed on the agent’s device UUID, not l2trace’s integer device id):
POSTURE_NATS_SUBJECT=l2trace.posture # the defaultConfigure the everwas publisher to send each report, as the agreed JSON envelope, to that subject on the same NATS the reconciler uses. l2trace derives an idempotency key from the report content, so an at-least-once bus redelivering the same report is a no-op.
4. Restart and confirm reports are landing
Section titled “4. Restart and confirm reports are landing”Ingress runs as part of the reconciler service (single-host) when enabled:
docker compose up -d reconcilerdocker compose logs -f reconciler | grep postureYou want lines like posture ingest running: subject=l2trace.posture gating=...
and, per report, posture: device=<uuid> macs=N checks=M ingested. Nothing is
enforced yet: monitor mode records the move it would make on the auth event
(would remediate ...) and changes nothing on the wire.
5. Set the freshness window
Section titled “5. Set the freshness window”A posture assessment older than this reads as “not assessed”, which never gates. Set it comfortably wider than the agent’s collection cadence so a laptop that sleeps over lunch does not flap:
RADIUS_POSTURE_FRESHNESS_SECONDS=7200 # 2h over a 30m cadence tolerates 3 missesErring long is the safe direction: a slightly old posture still informs, a too-tight window just produces needless not-assessed.
6. Enforce, on lab gear first
Section titled “6. Enforce, on lab gear first”Only after you have watched the monitor-mode discrepancies match what you expect, turn a lab switch’s port to enforcing 802.1X. A device failing a gating check now receives the remediation VLAN; a device that passes, or whose posture is stale or absent, is unaffected. Never enforce on a production port until the lab behaviour is proven.
How it fails safe
Section titled “How it fails safe”Every layer is arranged so a fault under-permits rather than cutting a device off or, worse, silently letting a failing one through unremediated:
- Off by default. With
POSTURE_INGRESS_ENABLED=falsethe store stays empty and the seam returns “no assessment”, so remediation never fires. - Empty gating set gates nothing. Gating is opt-in per deployment.
- Absence and not-assessed never gate. Only a present, fresh
faildoes. - Unknown status degrades to not-assessed. If a wire regression ever emits a status l2trace does not recognise, it is read as not-assessed, never a gating fail, so a machine is never remediated for a check that never ran.
- Stale posture reads as not-assessed (the freshness window).
- A posture-store read error fails open: the RADIUS decision proceeds as if no assessment were held, rather than breaking the auth.