1. The xz-utils moment for defenders
On 29 March 2024, Andres Freund posted to oss-security that liblzma, an upstream dependency of OpenSSH, contained a stage-loading backdoor planted by a maintainer who had spent the better part of two years building social trust before shipping the payload. CVE-2024-3094 was caught by accident: a 500-millisecond login latency that nobody else had thought to investigate. The lesson was not that one library got compromised. The lesson was that the trust gradient inside open-source software had become an exploitable structural property.
Every conference talk and threat-intel briefing for the next twelve months focused on the productive software stack: build pipelines, language registries, container base images, transitive dependencies. SBOMs became a board-level conversation. SLSA went from acronym to procurement clause. And while every one of those programs was correct and necessary, almost none of them turned the same lens on the defensive stack.
This is the asymmetry that should be keeping security architects awake at night. The customer's defender deployment, the thing whose entire job is to detect the attacker, runs the same kind of open-source code, pulled from the same kind of registries, signed (or not) with the same kind of keys, on the same kind of branch-protection-optional GitHub repositories. AIDE, Samhain, OSSEC, Wazuh, Falco, CrowdSec, Velociraptor, OpenEDR, GRR, Fail2Ban, auditd: every single one of them is open-source, and several of them are sustained by maintainer counts that would make the xz situation look well-staffed.
If liblzma taught us anything, it taught us that adversaries who care about persistence will infiltrate the suppliers of widely-trusted code. The defenders are widely-trusted code. The same attack surface applies. The threat model is symmetric, but the defensive posture, in almost every customer environment we audit, is not.
This post walks through what we now consider the field-grade approach to auditing the defender supply chain: which eleven tools to track, which signals matter, how the DTSCA engine scores them, and what to do this quarter to close the gap.
2. Eleven defenders, eleven supply chains
The CelvexGroup endpoint coverage program tracks eleven open-source defenders in production. Each ships through a distribution channel of its own, with its own signing posture, its own branch-protection state on the upstream GitHub repository, and its own release cadence. The table below is the snapshot as of May 2026, drawn from the DTSCA fingerprint pass and cross-checked against core.wave3_scanning.architecture.dtsca_engine.DEFENDER_TOOLS_TRACKED.
| Defender | Primary distribution channel | Signing posture | Branch protection on main | Last release / commit | |--------------|-------------------------------------------|-----------------------|-----------------------------|-----------------------| | Wazuh | packages.wazuh.com apt/rpm + GHCR | GPG (apt) + Cosign (containers) | Enforced | Active (2026) | | Falco | falco.org/repo apt/rpm + GHCR + falcoctl | GPG + Cosign (rules via falcoctl) | Enforced | Active (2026) | | Velociraptor | GitHub Releases binaries + MSI | GPG *.asc sidecar; selective Cosign | Enforced | Active (2026) | | OSSEC | GitHub Releases + Atomicorp tarballs | GPG sidecar | Partial | Stale (CVE backlog) | | Samhain | la-samhna.de tarball + Beltane CGI | GPG (manual fingerprint) | N/A (self-hosted) | Maintenance only | | AIDE | aide/aide GitHub Releases + distros | GPG 0xDB5E6D3B (expired 2025-06-27) | Partial | Releases ongoing | | auditd | distro packages (Red Hat, Debian, SUSE) | distro signing chains | N/A (kernel + userland) | Active | | CrowdSec | cscli hub floating branch + apt | GPG (apt) + hub branch unpinned by default | Enforced | Active | | Fail2Ban | distro packages + fail2ban/fail2ban | GPG sidecar | Enforced | Active | | GRR | grrdocker/grr Docker Hub | Cosign optional, often unverified | Enforced | Active | | OpenEDR | Comodo / Xcitium MSI + ComodoSecurity/openedr | Authenticode (vendor switch in flight) | Unenforced | Dormant (Jan 2024) |
A few of these rows deserve their own paragraph.
The AIDE row is the canonical example we use in customer briefings. The upstream signing key fingerprint 0xDB5E6D3B carries an expiry date of 27 June 2025. Any downstream distribution that has not refreshed its keyring beyond that date silently degrades to trust-on-first-use verification: the package signature still validates against a key the package manager already has cached, but the chain of trust to the upstream maintainer is severed. A man-in-the-middle on the mirror path can ship a tampered aide binary and the customer will not see a failure.
The OpenEDR row is the second-class warning. The most recent meaningful commit on ComodoSecurity/openedr lands in January 2024. The MSI distribution URL has been quietly transitioning from a Comodo signing CN to an Xcitium signing CN, which means an Authenticode-policy GPO that pins the publisher CN will silently start rejecting endpoint installs the day the rotation completes. Worst case, a tampered MSI is delivered with the new CN before the customer has updated their policy.
The OSSEC row exists because Wazuh forked from OSSEC in 2015, and OSSEC has not consistently backported the CVEs that Wazuh has fixed. Any customer running an OSSEC HIDS manager built before 2023 is carrying CVE-2021-26731 (analysisd remote code), CVE-2022-21215 (rootcheck path injection), and the rest of the inheritance backlog. They are paying for a HIDS that cannot defend itself.
3. Where the trust breaks
The Wave 3 catalog ships ten probes under the ENDPOINT-SUPPLY-DEFENDER-001 through -010 prefix. Every one of them is a metadata-only audit: no exploit payload, no agent footprint, no filesystem write. They route through core.wave3_scanning.supply_defender_scanner and gate to ServiceTier.ENTERPRISE. What follows is each probe, the evidence it surfaces, and what an attacker would do with the gap.
ENDPOINT-SUPPLY-DEFENDER-001 is the per-tool GPG signing-key expiry probe. It reads Release.gpg over apt-secure, runs rpmkeys -l against the customer's mirror metadata, and inspects container-image Cosign attestations. The cross-reference list is curated from our internal expired-key map, anchored on the AIDE 0xDB5E6D3B 2025-06-27 expiry. Falco and Wazuh upstream keys both have rotation windows that get missed in roughly 30% of audited customer environments. The CWE coverage maps to CWE-295 (improper certificate validation), CWE-345 (insufficient verification of data authenticity), and CWE-1357 (reliance on insufficiently trustworthy component); the MITRE technique is T1195.002. Blast radius: the entire detection stack.
ENDPOINT-SUPPLY-DEFENDER-002 is Falco rule-pack signature pinning. The probe reads the running Falco config endpoint and the falcosidekick /metrics snapshot to confirm cosign.verify_signatures: true, allowed_types: [rulesfile, plugin], and a pinned ghcr.io/falcosecurity/rules index URL. Without these, a compromised rule index registry ships a relaxed rule-set with high-value detections silently disabled, and the Falco daemon happily loads it. T1562.001 applied to the rule-supply-chain layer, not the endpoint kernel.
ENDPOINT-SUPPLY-DEFENDER-003 is the CrowdSec hub commit-pin probe. The default CrowdSec installation pulls cscli hub upgrade from the floating master branch of crowdsecurity/hub. One PR merged into master, with downgrade-the-rate-limit logic, ships to every CrowdSec deployment that runs cscli hub upgrade on a cron without commit pinning. This is the same shape as the xz-utils attack: trust placed in a moving branch with no integrity gate.
ENDPOINT-SUPPLY-DEFENDER-004 is the Velociraptor artifact provenance probe and is the most severe in the family. The probe queries /api/v1/GetArtifacts, hashes the YAML body of every installed artifact, and diffs against the public Velocidex exchange manifest. Velociraptor artifacts run as SYSTEM or root on every monitored endpoint. A tampered Generic.Client.VQL or Windows.Sys.Programs artifact is fleet-wide remote code execution with full DFIR-tool authority. The exchange model has no signing requirement; the customer's only defense is the hash check this probe automates.
ENDPOINT-SUPPLY-DEFENDER-005 is the Wazuh decoder regex ReDoS audit. The probe greps the customer-mirrored decoder XML corpus (/var/ossec/etc/decoders.d/.xml and /var/ossec/ruleset/decoders/.xml) for nested-quantifier shapes: (a+)+, (a)+, (a+), (?:a+)+, (a|a)+. It never compiles the regex against real input. A single hit is a SIEM blackout primitive: one crafted log line per minute pegs analysisd at 100% CPU and drops every other agent's events for the duration. T1499.001 plus T1562.001 in the supply-chain layer. CWE-1333.
ENDPOINT-SUPPLY-DEFENDER-006 is the OSSEC inheritance probe. The TCP/1514 banner read maps the customer's OSSEC manager version against the Wazuh CVE backlog. CVE-2021-26731 is the analysisd remote-code-execution case that Wazuh patched but OSSEC HIDS never reliably backported. CVE-2022-21215 is the rootcheck path-injection case. Both still hit OSSEC HIDS builds older than 2023. The remediation guidance is migration-grade: OSSEC HIDS at this point is a planned end-of-life component dressed up as a supported HIDS.
ENDPOINT-SUPPLY-DEFENDER-007 is Beltane CGI legacy exposure. CVE-2017-6444 and the rest of the Beltane class are unauthenticated SQL injection and command injection on the Samhain front-end. The probe sends a benign GET to /cgi-bin/beltane.cgi, /cgi-bin/beltane2.cgi, and /beltane/ from a non-management network. Reachable from anywhere outside the management VLAN is direct unauth RCE on the Samhain manager: defender-stack management plane compromise, attacker controls FIM truth, T1190 to T1078 to T1565.001. We still find Beltane in production in 2026.
ENDPOINT-SUPPLY-DEFENDER-008 is GRR Docker image signing. The probe queries Docker Hub or GHCR for the digest of the grrdocker/grr image and the rekor transparency log to confirm a verified Cosign signature. Unsigned GRR Rapid Response Docker means a compromised registry account ships a fleet-wide DFIR agent with attacker payload. GRR runs with broad endpoint authority on hunt servers; T1195.002 on the response platform itself.
ENDPOINT-SUPPLY-DEFENDER-009 is the OpenEDR MSI Authenticode chain probe. HEAD plus PE ImpDirectory range read against download.xcitium.com or the GitHub release URL. Cross-reference the Authenticode chain against the curated known-good fingerprint set. Report expired cert, broken chain, missing timestamp counter-signature, or vendor switch (Comodo to Xcitium). The dormant-vendor angle is what elevates this from medium to high: a tool that has not shipped a meaningful commit since January 2024 is a leading-indicator candidate for supply-chain abandonment.
ENDPOINT-SUPPLY-DEFENDER-010 is the per-channel auto-update audit. Composite trust-posture report across every defender the customer runs, with auto-update channel, signature-verification flag, last-update timestamp, and known typo-domain DNS hits. Auto-update is the single largest attacker-leverage surface in the defender stack: a compromised channel ships malicious code with full pre-existing trust. The probe also checks the customer's resolver for typo-domain hits like falco-security.com, wazuhh.com, and crowdsec-security.com.
4. DTSCA — measuring the trust posture
The Defense-Tool Supply-Chain Auditor lives at core.wave3_scanning.architecture.dtsca_engine. It is a stateless engine with three deliverables: fingerprint, compute_drift, and score_trust. The point of the engine is to reduce a defender's supply-chain posture to a single per-channel number in [0.0, 1.0] with a transparent component breakdown that operators can argue with.
The score is a weighted sum of five components. The weights are tuned to favor signing-key freshness and attestation -- the two foundational signals of an actively-maintained supply chain -- with secondary weight on drift and tertiary weight on branch protection and dormancy. We do not publish the exact coefficients; the operational point is the dimensions we measure, not the parameter set we ship. Every component returns a health value in [0.0, 1.0], and the contribution to the score is weight * health. The weights sum to 1.0.
key_freshness maps signing-key expiry to health on a piecewise ramp: zero on already-expired or unknown-expiry, a steep ramp through the near-term-expiry band, and saturation at 1.0 once the key is comfortably forward-dated. The AIDE example collapses to 0 the day after 27 June 2025.
branch_protection is a binary GitHub API check on whether required_pull_request_reviews or required_status_checks is enforced on main. Unauthenticated 404s are treated as unknown-equals-unenforced; we will not fabricate a signal we cannot prove.
attestation is binary: 1.0 if Cosign / sigstore-shaped attestation is present on a release asset, 0.0 otherwise. Authenticode-only chains are scored as non-Cosign attestation -- a deliberate choice to bias toward transparency-log-anchored trust roots.
dormancy ramps off the last release date with a year-scale grace window followed by a year-scale linear decay to zero. OpenEDR, with last meaningful activity in January 2024, is well into the decay region as of May 2026.
drift reduces the list of DriftRecord entries from compute_drift to a single health value, weighted by severity class. A single critical drift collapses the drift component to 0.
Worked example, qualitative: Falco on the stable channel scores in the upper-90s -- Cosign attestation present, branch protection enforced on falcosecurity/falco, recent release inside the dormancy grace window, signing key forward-dated nearly a year, and only minor cosmetic drift. That is what a healthy supply chain looks like in DTSCA terms.
Run OpenEDR through the same machinery and the score collapses into the lower third of the range. Authenticode is present but scored as non-Cosign. Branch protection on ComodoSecurity/openedr is unenforced. The last release is well past the grace window. Signing-key freshness is unknown. Only the drift component remains clean. That is a tool a security architect should be on a migration plan for.
The engine emits the score plus the component breakdown so the customer can see exactly which leg is dragging. We do not collapse the breakdown into a letter grade; we have found that the per-component contribution drives better remediation conversations than a single composite number.
5. What customers should do today
Five concrete actions cover the highest-leverage gaps. None of them require a procurement cycle; all of them can be in production within a sprint.
First, pin commit hashes for hub upgrades. cscli hub upgrade on the floating master branch of crowdsecurity/hub is supply-chain risk on the same shape as xz-utils. In /etc/crowdsec/config.yaml:
hub_branch: 1f4a3c8e2b9d # specific commit SHA, not 'master'
Falco rule-pack pulls go through falcoctl and benefit from the same discipline. In falcoctl.yaml:
allowed_types:
- rulesfile
- plugin
follower:
cosign:
verify: true
public_key: /etc/falco/falcosecurity-public.key
indexes:
- name: falcosecurity
url: ghcr.io/falcosecurity/rules
digest: sha256:9a1b2c... # pin
Second, verify Cosign signatures pre-deploy. Every defender container image and signed binary should pass a cosign verify invocation in the deployment pipeline before it is allowed to run. For GRR:
cosign verify \
--certificate-identity 'https://github.com/google/grr/.github/workflows/release.yml@refs/tags/v3.4.7.4' \
--certificate-oidc-issuer 'https://token.actions.githubusercontent.com' \
ghcr.io/google/grr@sha256:<digest>
For Falco rule packs:
cosign verify \
--key /etc/falco/falcosecurity-public.key \
ghcr.io/falcosecurity/rules:<tag>
For OpenEDR MSIs the Windows-side equivalent is:
signtool verify /pa /v /tw openedr.msi
Third, audit signing-key expiry monthly. Subscribe to the upstream key-rotation mailing lists for AIDE, Wazuh, Falco, CrowdSec, Fail2Ban, OSSEC, and Samhain. Add an automated job that runs gpg --list-keys --with-colons against the customer mirror's keyring and alerts on any expiry inside 90 days. The AIDE 2025-06-27 case would have been a 90-day warning shot.
Fourth, freeze defender artifacts at known-good digests. For Velociraptor specifically, maintain an internal manifest of approved artifact SHA256 hashes and gate every server upgrade on a diff against that manifest. Block deploy if any installed artifact contains an unsigned upload() or http_client() call. The exchange model has no signing requirement, which means the customer is the only line of defense.
Fifth, kill the legacy management planes. Beltane should not be on the customer perimeter in 2026. Move Samhain reporting to the modern yule server with TLS and restrict to the management VLAN behind a VPN. Decommission OSSEC HIDS in favor of Wazuh 4.9+ where the same ruleset runs against a CVE-patched manager. Plan an OpenEDR migration to a maintained EDR; the dormant-vendor signal has been red for over a year.
A useful operational metric: track the DTSCA composite score per defender per quarter and require the median across the customer's installed stack to stay in the upper band (we set the published gate so that a single weak component cannot drag a tool below it without operator visibility). Anything that falls below the gate is a procurement conversation, not a tuning conversation.
6. Closing
The xz-utils incident reframed open-source supply-chain risk as a structural property of trust gradients. Every argument that justified the SBOM mandate, the SLSA adoption push, and the procurement-clause rewrites applies, with full force and identical urgency, to the open-source defenders. The detection stack is software, the software has suppliers, and those suppliers are exactly as compromisable as liblzma was. Anyone who has read this far should already have a list of the eleven defenders running in their environment, the AIDE expiry status memorized, the Velociraptor artifact hash discipline scheduled for next sprint, and a plan to migrate off OpenEDR before the Authenticode rotation forces the issue. The defender supply chain is the next frontier, not because anyone wants it to be, but because the adversaries already know it is.