Platform support

What the agent does on Linux, Windows and macOS — including where it does nothing, and why.

84 capabilities across three operating systems. Every cell states how the platform reads or acts on the host, and every gap carries a written reason rather than a blank. The uncomfortable rows are the ones worth reading.

This release
v0.0.0-dev.0
Channel dev. Every cell below is scoped to this build.
Support window
540 days
From release, on the stable channel.
Minimum OS
Linux — kernel 3.2
Windows — Windows 10 / Server 2016
macOS — not stated
Below the floor the agent does not run at all — see the last row of the first group.
Releases cut
None yet
Listed below as they ship. Nothing has been invented to fill the table.
How to read the evidence grade
A support matrix normally answers one question: does the feature exist. That is the less useful question. The one that predicts whether it will work on your estate is how do you know — so every cell carries a grade for the strength of its own evidence, and the grades are visibly uneven.
PROVEN
A test runs on that operating system against the real mechanism. The strongest claim available without being in your datacentre.
COMPILED
The code is built for that platform and its shape is enforced at compile time, but no run on real hardware is cited. Honest middle ground.
DECLARED
A human asserted it and nothing checks the assertion. Kept visible so it can be checked and, where it is backlog, paid down — an absence that nothing verifies is a claim, not a fact.
How to read the state
● Supportedships and runs on this platform
◌ Not availablethe platform genuinely cannot produce this signal — not an omission on our side
◈ Agentlesscovered without installing an agent
◐ Not yetbuilt for, not shipped in this release
× Unsupportednot offered on this platform
SHOW
All 84 capabilities across three operating systems.
What the agent knows about the host
15 rows
Capability
Linux
Windows
macOS
Platform fingerprint
the agent reports its OS, flavor, version, kernel, libc and init at registration (D-AV5)
● Supported compiled
/etc/os-release (with the /usr/lib fallback), /proc/sys/kernel/osrelease, /proc/1/comm
● Supported compiled
RtlGetVersion (GetVersionEx lies by design since 8.1)Note · Reads the version from the kernel rather than the compatibility-shimmed API, and reports nothing unless the host identifies itself as Windows NT, so a reported version is one that passed that check.
● Supported proven
kern.osproductversion + kern.osrelease
Host resource metrics
CPU, memory and filesystem utilisation, swept on -metrics-interval
● Supported compiled
/proc and statfsNote · Needs a mounted /proc; without it nothing is reported, rather than zeros.
● Supported compiled
GlobalMemoryStatusEx + GetDiskFreeSpaceEx + GetSystemTimesNote · Disk space is reported for fixed drives.
● Supported proven
iostat, vm_stat and getfsstatNote · Volumes in one APFS container share one pool of space, so they are grouped by container.
Cumulative CPU time counters
per-mode cumulative CPU counters a consumer can difference itself
● Supported compiled
/proc/stat
● Supported compiled
GetSystemTimesNote · Cumulative counters; rates are computed from the difference between two readings.
◌ Not available declared
macOS exposes no cumulative CPU counter the agent can read without native bindings: kern.cp_time is not available through sysctl, and host_statistics64 needs C bindings. CPU is reported as a utilisation rate instead — a different field, not a filled-in one.
Load average
the 1/5/15-minute run-queue average
● Supported compiled
/proc/loadavg
◌ Not available compiled
The Windows scheduler has no run-queue length to average, so no load-average gauge is emitted rather than a synthesised one.Note · Windows has no run-queue load average, so no value is reported — never a synthesised one.
● Supported proven
vm.loadavg
Network interface throughput
per-interface byte counters the collector differences into a rate
● Supported compiled
/proc/net/dev
● Supported compiled
GetIfTable2Note · Counters are cumulative; rates come from the difference between two readings.
● Supported proven
netstat -ib
Disk throughput
per-device read/write byte counters
● Supported compiled
/proc/diskstats
● Supported compiled
IOCTL_DISK_PERFORMANCE per volumeNote · Virtual volumes on one physical disk are de-duplicated. The agent is not always granted the volume access this needs, so an empty disk list can be a legitimate answer.
◌ Not available declared
macOS publishes no cumulative per-device byte counter the agent can read; iostat -d reports a pre-averaged rate, which a collector that differences counters cannot use without inventing one.
Installed-software inventory
the installed package and application list that asset inventory and vulnerability assessment read
● Supported compiled
dpkg-query and rpm
● Supported compiled
the Uninstall registry views (both 32- and 64-bit)
● Supported proven
the application bundles unioned with the installer receipt database
Hardware inventory — processors, memory and storage
what the machine under investigation physically is, read without running a single vendor tool: the processor's own identity and how many of it there are, the installed memory, and the storage the platform will admit to
● Supported compiled
/proc/cpuinfo, /proc/meminfo and /sys/block/*/{size,queue/rotational,removable,device/model}, all through rooted handlesNote · Counts logical CPUs correctly on multi-socket servers and reports disk sizes in the kernel's fixed 512-byte units. ARM hosts report their implementer and part codes, as the kernel gives them, rather than a model name. Not yet verified on a Linux host.
● Supported compiled
GlobalMemoryStatusEx, GetActiveProcessorCount, GetLogicalDriveStringsW, GetDriveTypeW and GetDiskFreeSpaceExW, and the processor description under HARDWARE\DESCRIPTION\System\CentralProcessor\0 in the registry.Note · Reports both the machine's processor count and the count the agent may run on; a difference means the agent is confined. A drive that is not ready is named but not sized, so the read does not stall. The page-file total is reported as the commit limit (memory plus paging files), not as swap.
● Supported proven
The hw.* and machdep.* sysctls, and getfsstat(MNT_NOWAIT) for the filesystem table — nothing executed.Note · Reports mounted filesystems, not physical disks — disk devices need an interface this agent does not use. Each APFS volume shows its container's size, and unmounted or locked volumes do not appear. An unresponsive network mount does not stall the read.
Virtualisation identity — hypervisor, container, and the cloud the firmware names
whether the host under investigation is a machine, a guest or a container, and whose — decided from the strings the platform publishes about itself, with the limits of that evidence stated in the artifact rather than implied
● Supported compiled
the DMI strings under /sys/class/dmi/id matched against a shared signature table, plus /sys/hypervisor/type, the CPU's own hypervisor feature flag, and the container markers /.dockerenv · /run/.containerenv · pid 1's cgroup pathNote · Uses three independent signals — firmware strings, the hypervisor node and the CPU's hypervisor flag — and reports every match. Firmware vendors that also make physical hardware need a second matching field. The container check looks at process 1, not at the agent. Device serial numbers and UUIDs are not collected here.
● Supported compiled
The SMBIOS copy at HARDWARE\DESCRIPTION\System\BIOS, mapped onto the DMI attribute names and matched against the same signature table the Linux collection uses.Note · Uses the same firmware-string signatures as Linux. Whether the host is a Windows container is reported as unanswered rather than guessed. Paravirtual hypervisor interfaces are not probed.
● Supported proven
kern.hv_vmm_present for whether this is a guest, kern.hv_support reported beside it and labelled as the host question, and hw.model for Apple's own Virtualization framework guests.Note · Reports whether this Mac is a virtual machine — distinct from whether it can host one, which is reported beside it and labelled. Which hypervisor runs a virtual Mac is not reported; macOS does not publish it.
Firmware and boot integrity — Secure Boot, SIP, TPM, kernel lockdown
whether the platform's own protections are in force on the host under investigation: Secure Boot and the firmware's identity, System Integrity Protection and exactly which of its protections have been dropped, TPM presence and PCR values, and kernel lockdown — collected without running a single vendor tool
● Supported compiled
sysfs, through rooted handles: the two UEFI global variables in efivarfs (SecureBoot, SetupMode), the DMI firmware identity under /sys/class/dmi/id, /sys/kernel/security/lockdown, the TPM's sha256 PCR bank under /sys/class/tpm/tpm0, and the firmware's TCG event log under /sys/kernel/security/tpm0, parsed and REPLAYED against that bankNote · Reports Secure Boot, setup mode, kernel lockdown and the TPM's SHA-256 PCR bank from sysfs. Missing or short files are reported as unavailable, never as off. PCR values are the kernel's account, not a signed TPM quote, and the TPM event log (root-only) is not read.
● Supported compiled
GetFirmwareType for the firmware class, and the registry for the rest: the Secure Boot state value, the SMBIOS copy under HARDWARE\DESCRIPTION\System\BIOS, and the TPM driver's Plug and Play enumeration.Note · A missing Secure Boot value on a legacy-BIOS host is reported as legacy firmware, not as Secure Boot off. TPM presence means Windows bound a TPM device — not that it is healthy or measuring — and PCR values are not reported.
● Supported proven
the csrctl(2) syscall (483) called straight from Go: CSR_SYSCALL_GET_ACTIVE_CONFIG for the configuration word, and CSR_SYSCALL_CHECK per bit as an independent cross-check — no exec of csrutil, no cgoNote · Reads the System Integrity Protection configuration directly and checks it against Apple's csrutil. A partly disabled configuration is reported bit by bit, never rounded to "disabled". Macs have no TPM and Apple silicon has no UEFI; Lockdown Mode is reported as not determined. The Apple silicon secure-boot policy (Full, Reduced, Permissive) is not reported.
Boot state — when the host started, what it was told to boot with, and whether that weakened it
the boot instant and the boot session identity an investigator joins two artifacts on, whether this is a reduced boot (safe mode, single-user, rescue), and — the part that matters — the kernel command line decoded against a named vocabulary of weakenings, each carrying what it means for the host rather than a restatement of its own spelling
● Supported compiled
/proc through a confined handle: /proc/stat's btime and /proc/uptime as two independent paths to one instant, /proc/cmdline for the kernel command line, and /proc/sys/kernel/random/boot_id for the boot session identity.Note · Linux has no safe-boot mode, and the result says so; it reports instead whether this boot asked for a reduced environment (single-user, emergency or rescue). The boot time is read two independent ways, and a difference of more than two seconds is reported, since it means the clock was changed after boot.
● Supported compiled
GetTickCount64 for the uptime, and the registry for the rest: the loader's own record of this boot at Control\SystemStartOptions and safe mode at Control\SafeBoot\Option.Note · The boot time counts time spent asleep or hibernated, so it is exact unless the wall clock was changed. Safe-mode boots are detected from the loader's own record. The stored boot configuration (BCD), earlier boots' options and a per-boot identifier are not reported.
● Supported proven
The kern.* sysctls read directly — kern.boottime, kern.bootsessionuuid, kern.safeboot, kern.singleuser and kern.bootargs — with no sysctl command executed.Note · Reports the boot time, the boot session and the arguments this kernel actually started with — not the NVRAM setting for the next boot. The boot time matched last and uptime on a real Mac. The Apple silicon boot policy is not reported.
Agent privilege declaration
the agent reports the privilege its own PROCESS holds at registration, so a collection plan is compiled against what this host can actually serve rather than against an assumption
● Supported proven
geteuid() — the effective user id, because that is what the kernel checks on every open, and every collection is an open.Note · Reports the agent's effective user id. It never reports kernel-level privilege, even where the agent can load kernel programs.
● Supported compiled
OpenCurrentProcessToken + GetTokenInformation(TokenElevation)Note · Reports whether the agent's token is elevated, not whether its user is an administrator — under UAC an administrator's filtered token cannot open privileged resources. If the question cannot be answered nothing is declared, and no collection plan is compiled for that host.
● Supported proven
geteuid(), same as linux
Vulnerability assessment facts
the host facts a vulnerability definition evaluates: packages, patches, services, file versions
● Supported proven
the package database and systemd
● Supported compiled
QFE plus DISM, the service table, and file-version resourcesNote · Uses installed updates, DISM, services and file versions. A check that depends only on a missing KB abstains, because later cumulative updates supersede KBs. Its tests use simulated command output; it has not been verified against a real Windows host.
● Supported proven
bundles, receipts and launchd
Vulnerability reachability (is the component loaded?)
whether a finding's vulnerable package or file is mapped into a running process, and into how many — joined from the proc.modules enumeration
● Supported compiled
/proc/<pid>/maps joined to the package's owned files — dpkg's per-package lists, apk's installed database, pacman's local file lists, or the rpm database's own file tags (sqlite or Berkeley DB) — all read without executing anything.Note · Joins each process's loaded files to package ownership for dpkg, rpm, apk and pacman. Run as root on a real aarch64 Linux host, where rpm ownership matched rpm itself for every package; apk and pacman are tested on sample data only. A package upgraded while a process still runs the old file is reported as restart-required. Network exposure is counted in the host's own network namespace only. A non-root agent answers "unknown" rather than "not loaded".
● Supported compiled
the loader's Toolhelp module list, case-foldedNote · Package ownership comes from Windows Installer component records and the product's recorded install folder; a product with neither, or a folder of more than 50,000 files, answers "unknown". This has not yet been run on a real Windows host. A patched file still loaded by a running process is not detected. Kernel drivers are judged against the loaded-driver list, and a partial list never claims a driver is absent.
● Supported compiled
proc_info region paths, directory-resolved (/var → /private/var)Note · Package ownership comes from app bundles and installer receipts; bundles of more than 50,000 files answer "unknown". Without root, other users' processes cannot be read, so an absence there is "unknown". A patched file still in use is not detected, and kernel extensions answer "unknown".
Hosts below the toolchain floor
Windows 7 / 2008 R2 / 2012 R2 and RHEL 6 — where this agent cannot run at all
◈ Agentless declared
Go 1.24+ requires Linux 3.2+, so RHEL 6 (2.6.32) cannot run this binary. Covered agentlessly: SNMP HOST-RESOURCES-MIB for host metrics, and traces from the application's own OTel SDK, which never needed our agent
◈ Agentless declared
Go 1.21 and later require Windows 10 or Server 2016. The same agentless coverage applies. A second agent built on an older toolchain was considered and rejected: two toolchains, two patch streams, and still a reduced agent.
× Unsupported declared
no macOS release in support is below the toolchain floor, so the case does not arise
Processes and services
6 rows
Capability
Linux
Windows
macOS
Per-process metrics
the per-process table: rss, cpu, and the process identity behind it
● Supported compiled
/proc/<pid>
● Supported compiled
the toolhelp snapshot + per-process queriesNote · A non-elevated agent cannot read the details of roughly half of a typical host's processes; those entries are reported without them.
● Supported proven
one bounded ps for the whole tableNote · Collected with one ps run per sweep rather than a read per process, to stay within the agent's CPU budget.
Per-process thread count
how many threads each process is running
● Supported compiled
/proc/<pid>/status
● Supported compiled
the toolhelp snapshot's thread count
◌ Not available declared
BSD ps has no thread-count field and libproc's thread information needs C bindings; the field is omitted, never reported as zero.
Per-process share of host CPU
each process's CPU as a fraction of the whole host
● Supported compiled
/proc/<pid>/stat against /proc/stat
● Supported compiled
per-process kernel+user time against GetSystemTimes
◌ Not available declared
macOS supplies no host-wide CPU denominator the sweep can read, so the fraction has no honest numerator/denominator pair; absent beats a fabricated share
Service / unit health
which managed services are running, and which are dead
● Supported compiled
systemctl showNote · systemd hosts only; a SysV or Upstart host reports nothing rather than an invented list.
● Supported compiled
EnumServicesStatusEx over the Service Control ManagerNote · A stopped demand-start service (exit code 1077) is reported as resting, not failed.
● Supported proven
launchctl list
Service restart / flapping signal
the restart count that turns a crash-looping service into a signal
● Supported compiled
NRestarts from systemctl showNote · Best effort: an older systemd that does not report restart counts leaves the count unknown, not zero.
◌ Not available compiled
The Service Control Manager exposes no restart count, so the flapping signal is simply absent.Note · Windows does not report service restart counts, so the signal is absent rather than a zero that would read as "never restarted".
◌ Not available proven
launchd's list output carries no restart count, so the flapping signal is absent rather than reported as zero.
Host process-execution telemetry
every process that starts on this host, with its parent and a walkable ancestry chain — needing no auditd rule, no Sysmon and no osquery
● Supported compiled
/proc/<pid>/{stat,cmdline,exe,status,cwd,cgroup}, novelty-gated so only unreported processes pay for the detail readsNote · A poll, not a kernel hook: a process that starts and exits between two polls is not seen. Forward auditd where every execution must be captured.
● Supported compiled
CreateToolhelp32Snapshot, GetProcessTimes (the creation time is the identity) and QueryFullProcessImageNameW.Note · Parents are validated by creation time, because Windows reuses the process ids of exited parents. The command line and the owner are not reported here; Windows Security event 4688, collected from the event log, carries both.
● Supported compiled
ps -Ao pid=,ppid=,user=,lstart=,args= for the table, plus a pid-scoped ps -o pid=,comm= for new processes only.Note · A poll using ps: a process that starts and exits between two polls is not seen. A second, narrower call is made only when new processes appear, to recover program names that contain spaces.
Security telemetry
9 rows
Capability
Linux
Windows
macOS
Host logon-session telemetry
who is logged into this host, from where and since when — needing no auditd rule, no Windows audit policy and no Full Disk Access
● Supported compiled
the binary login-accounting file (/run/utmp, with the /var/run compatibility path), parsed from the documented POSIX record layoutNote · Needs no privilege. Records sessions, not failed logins — those are in /var/log/btmp, which is root-only and not part of this row.
● Supported compiled
WTSEnumerateSessionsW plus one WTSQuerySessionInformationW(WTSSessionInfo) per session, which carries station, domain, user and logon time together.Note · Needs no audit policy or event-log setup. Each session is read in one query, so a logoff part-way through cannot produce a session that never existed.
● Supported proven
/var/run/utmpx, parsed from the documented layoutNote · Parsed with a record layout measured on a real Mac and checked field by field against who. The file's own header record is never reported as a user.
Host persistence/autostart telemetry
what is configured to run on this host without anyone starting it — registry autostart entries, configured services, scheduled tasks and loaded kernel drivers — needing no Sysmon and no Windows audit policy
● Supported compiled
Cron tables, systemd units and timers with their enablement links, rc scripts, /etc/ld.so.preload, module auto-load settings, /etc/pam.d, udev rules, XDG autostart, shell startup files, Python startup hooks and authorized_keys, with per-user paths from /etc/passwd; plus the running kernel's loaded modules checked against the module index for the running release; plus one entry per account, per group and per sudoers file.Note · Reads cron, systemd units and their enable links, init scripts, preload files, PAM, udev, desktop autostart, shell startup files and authorised keys, plus loaded kernel modules, accounts and groups. A loaded module missing from the installed-module index, or hidden from /sys, is flagged; a rootkit that hides from both views is not detected. Reading sudoers needs root. Not yet verified on a Linux host.
● Supported compiled
Registry enumeration over a curated set of autostart roots in HKLM and every loaded user hive (including the per-user keys UAC-bypass techniques write to), the configured service list, the Task Scheduler's task definitions and the loaded kernel drivers. For the program each service, task and driver runs it adds the file's owner, who else can replace it (the file's and its folder's access lists), and who signed it (Authenticode, falling back to the system catalog).Note · Reports registry autostart locations, configured services, scheduled tasks and loaded kernel drivers, with each program's owner, who else can replace it, and its Authenticode verdict (revocation not checked). Service-DLL registrations and application-shim entries are not collected — use Sysmon where those matter. Driver records carry no hash. No detection rule uses the owner and replaceability fields on Windows yet.
● Supported proven
Launch agents and daemons, login items, the deprecated StartupItems and emond stores, periodic, cron, rc.common, /etc/pam.d, shell startup files, Python startup hooks, authorized_keys, sudoers, and every local account and group from the files and Open Directory; plus Gatekeeper and System Integrity Protection state, launchd's enable and disable overrides, and the code signature and team of the program every launch job runs.Note · Reads launch agents and daemons, login items, cron and other startup files; accounts and groups from both the files and the directory service; Gatekeeper, SIP, boot arguments, the launch environment, login authorisation plugins and launchd's override register; and each launch program's signature, owner and who can replace it. Apple's SIP-protected launch jobs are not collected, binary property lists are named but not parsed here, and reading sudoers needs root.
Inline-resolver DNS telemetry
every name this host resolved, and what it resolved to — needing no network tap and no Sysmon
● Supported proven
A query hook on the agent's own inline UDP resolver (the DNS sinkhole), plus an in-house RFC 1035 response parser for the response code, answer addresses and minimum TTL.Note · Sees only DNS queries sent to the agent's own resolver: the host must be pointed at it, and applications using DNS-over-HTTPS or their own resolver bypass it. Off by default and enabled separately, because query names reveal browsing history.
● Supported compiled
the same inline resolver and response parserNote · The same resolver code as on Linux and macOS, with the same limits; not yet verified on a Windows host.
● Supported proven
the same inline resolver and response parser — no OS facility is involvedNote · The same resolver as on Linux, with the same limit: only queries sent to the agent's resolver are seen, and it is off by default. Verified with a real resolver for forwarded, sinkholed and failed lookups.
Host connection telemetry
listening sockets and established connections, with the process behind each
● Supported compiled
/proc/net/{tcp,udp} joined to /proc/<pid>/fd
● Supported compiled
GetExtendedTcpTable and GetExtendedUdpTable (TCP connections and listeners; UDP bindings only — the UDP tables expose no peer column, a Windows limitation, so a UDP row can name a listening service but never a flow).Note · Each connection and listener is attributed to its owning process. UDP rows show bound ports only — Windows exposes no remote address for UDP.
● Supported proven
lsof, cross-checked against netstat
Packet-capture detection (T1040)
detecting that something on this host has opened a capture handle
● Supported compiled
/proc/net/packet, with protocol-bound sockets excluded structurallyNote · Reads packet sockets from /proc, excluding sockets bound to a single protocol. Not yet verified on a Linux host; the check needs raw-network privilege to test.
● Supported compiled
system handle enumeration over packet-capture driver device objects (Npcap and NDIS capture devices)
● Supported proven
lsof over /dev/bpf*Note · BPF capture devices carry no protocol binding, so telling an expected capture tool from an unexpected one rests entirely on an allowlist of known capture processes.
Removable-media detection
which mounted volumes are removable, for data-loss prevention and device control
● Supported compiled
/sys/block removable flags
● Supported compiled
one PowerShell shell-out joining Get-Volume (which knows DriveType) to Get-Disk (which knows bus and serial) through the partitionNote · Joins volume and disk information through one PowerShell command, which is what lets a USB device be told apart from other removable media.
● Supported proven
the /Volumes mount table, per-volume diskutilNote · Mounted disk images are excluded, even though they raise every flag a USB stick does — found on real hardware.
Raw host-log forwarding
tailing the OS's own audit/event log forward to the brain, decoded server-side
● Supported compiled
-collect-auditd tails the audit log; -collect-journald reads the systemd journalNote · Forwards the audit log and the systemd journal. Adding the connect system call to the audit rules costs about 520 bytes per event; bind costs nothing extra.
● Supported compiled
-collect-winlog forwards a chosen event-log channel through wevtutil; the Security and Sysmon channels each have their own decoder.
● Supported compiled
-collect-eslogger streams Endpoint Security eventsNote · Streams Endpoint Security events through eslogger, which requires superuser.
On-agent OTLP receiver
accepting an application's own OTLP metrics, traces and logs at the edge (-otlp-addr)
● Supported proven
An HTTP/protobuf OTLP endpoint whose data is buffered on disk while the platform is unreachable.
● Supported compiled
An HTTP/protobuf OTLP endpoint whose data is buffered on disk while the platform is unreachable.Note · The same platform-neutral receiver as on Linux and macOS; not yet verified on a Windows host.
● Supported proven
An HTTP/protobuf OTLP endpoint whose data is buffered on disk while the platform is unreachable.
UDP receiver transport-loss visibility
every native UDP listener (syslog, SNMP traps, flow exports) reports what the OS discarded on its receive queue before the agent saw it — the loss no counter inside the agent can observe
● Supported proven
/proc/net/udp's drops column, matched on the listening socket's local address; the agent sizes that socket's receive buffer itself.Note · Reports UDP datagrams the kernel dropped before the agent could read them, so loss is visible rather than silent.
◌ Not available declared
Windows exposes no per-socket receive-queue drop counter: GetPerTcpConnectionEStats has no UDP equivalent, and the datagram counters in MIB_UDPSTATS are host-wide, so a figure from them would blame this listener for another process's loss. No transport-loss value is reported here rather than a zero, because a zero would read as no loss.
◌ Not available declared
macOS has no /proc, and the netstat -s UDP drop counters are host-wide for the same reason as Windows. Reported as absent rather than zero
Containers
2 rows
Capability
Linux
Windows
macOS
Running-container inventory
which containers are running on the host, from the kernel's own cgroup paths — no runtime socket (charter E17 phase 1)
● Supported compiled
/proc/<pid>/cgroup + /proc/<pid>/comm, runtime-agnostic across docker, containerd, CRI-O, podman and both Kubernetes cgroup driversNote · Reports the container id, runtime and Kubernetes pod id — not the image, which the host does not record. On Kubernetes the platform adds the image from the API server's audit records; on a plain Docker host containers stay without an image.
● Supported compiled
Host Compute Service compute-system enumeration and server-silo job-object inspection
◌ Not available declared
macOS has no container primitive. Docker Desktop's containers belong to a Linux VM's kernel and are the business of an agent inside that VM; an agent on the Mac can only see the hypervisor process
Container-escape detection
a process whose cgroup says container while its MOUNT namespace is the host's — the runtime half of T1611, needing no image, no CRI socket and no cluster (charter E17 phase 3)
● Supported compiled
/proc/<pid>/ns/* compared against /proc/1's, over the processes /proc/<pid>/cgroup places in a containerNote · Flags a containerised process that shares the host's mount namespace. Host PID and host network settings are reported as context, never as the trigger. Needs root; without it the check is refused by name rather than reported clean, and if the agent's own view of process 1 is containerised nothing is reported.
◌ Not available declared
Windows containers are isolated by a server silo, not by namespaces, so there is no mount namespace to compare and no equivalent of this check. When Windows container inventory is built, escape detection there will be a different mechanism, not this one ported.
◌ Not available declared
macOS has no container primitive, so there is nothing to escape from — the same answer as container inventory, for the same reason.
Evidence the agent can collect
30 rows
Capability
Linux
Windows
macOS
Targeted file collection
an investigator can ask a host for a named file's digest, a bounded directory listing, or the file's bytes — no agent-side script, and a symlink cannot make an artifact describe a different file
● Supported proven
Opens confined to the requested folder; bounded streaming reads with SHA-256 hashing and a bounded directory walk.
● Supported compiled
Opens confined to the requested folder; bounded streaming reads — the same portable code path as Linux and macOS.Note · Collection stays inside the requested folder: symbolic links that escape it and Windows reserved device names (such as NUL or COM1) are refused.
● Supported proven
Opens confined to the requested folder; bounded streaming reads.
NTFS $MFT and USN change journal
the two structures a deleted file leaves behind, read from the raw volume so in-use files are obtainable — the producer the shipped $MFT and USN parsers never had
× Unsupported declared
A Linux host's own system volume is not NTFS, and this collection reads the host's own volume by drive letter. An NTFS partition attached to a Linux machine (a dual-boot or evidence disk) can be parsed by the same reader, but collecting a foreign disk is disk imaging, with a different privacy class — a separate collection, not this one.
● Supported compiled
A raw, read-only open of the volume by drive letter and sector-aligned reads, then an in-house NTFS parser: boot sector, file-record fixup, runlists including attribute-list extents, the standard-information and file-name attributes, and version 2 and 3 records from the tail of the change journal.Note · Needs an elevated agent; a non-elevated agent declines before reading. Returns a stated selection — the 1,024 most recently changed file records and the 2,048 newest change-journal records — never the whole table. The parsing is tested on every platform against a synthetic volume; opening a real volume has not yet been verified on a Windows host.
× Unsupported declared
The same scope decision as Linux: macOS runs APFS or HFS+, and an attached NTFS disk is a foreign volume to be imaged, not the host's own.
The running process table, collected without running a program
every process with the same per-instance identity the live sensor derives, so a collection can be joined to the stream — and, on Linux, whether the image a process is running from is still on disk
● Supported proven
/proc: stat (field 22, the start time the process identity is keyed on, located from the last ')' so a crafted process name cannot shift the field numbering), cmdline, status, and the exe link — whose ' (deleted)' suffix reveals a process running from a deleted file, which no live stream can report.Note · The most complete of the three platforms: image path, command line, owning user, and whether the executable was deleted while the process still runs.
● Supported compiled
CreateToolhelp32Snapshot for the table, then OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION) + GetProcessTimes for the creation stamp that is the identityNote · Uses the limited query right, which also works against protected processes. The image path and command line are not reported on Windows.
● Supported proven
sysctl kern.proc.all for the table (pid, parent pid, start time, command name) and KERN_PROCARGS2 per process for the executable path and command line — the same source ps reads, with nothing executed.Note · The owning user is not reported on macOS. Process start times were checked against the live process list on a real Mac and match the identity the live process stream uses.
Local and directory accounts, and who can actually elevate
every account and group the host knows — from the POSIX files and from the directory, with the divergence between them reported, because a local account that a directory-joined host does not know is how a backdoor is added
● Supported proven
/etc/passwd and /etc/group, combined with the system's name-service directory (nsswitch), whose effective group membership resolves what a group file alone cannot.Note · Authoritative for local accounts. A host joined to SSSD, LDAP or Active Directory can resolve accounts that appear in neither file; coverage of those has not been measured on a joined host.
× Unsupported declared
Windows keeps its accounts in the SAM and LSA, keyed by security identifier rather than user id, with no passwd-style file to read — a different mechanism rather than a missing path. Windows accounts are covered by the Windows account database row.Note · Windows keeps accounts in the SAM, keyed by security identifier — a different mechanism from the Unix files. The request is refused with that reason rather than answered with an empty list; see the Windows account database row.
● Supported proven
The same two files combined with the Open Directory answer the system library returns — nothing executed, and no dscl.Note · On macOS the account files hold only system accounts, so the collection combines them with the directory service and a user-id sweep, and marks itself partial. On a measured Mac it reached 132 of the 133 accounts the directory lists.
Interactive and remote sessions, collected without running a program
every session-accounting record the host kept — who, from where, on which line and when it was recorded — with the open sessions distinguished from the records the file kept after a logout
● Supported compiled
/var/run/utmp, parsed with the glibc record layout for the agent's own architecture — 384 bytes (x86-64, i386, 32-bit ARM, riscv64, ppc64, mips) or 400 bytes (aarch64, loongarch64, s390x, where a 64-bit time moves the login-time field), in the host's byte order. Only an ARM agent falls back to the other width, and only when the file contradicts its own.Note · Reads both glibc record sizes (384 bytes, and 400 bytes on aarch64 and similar), chosen by the agent's architecture. Verified against a real aarch64 host; the 384-byte x86-64 layout has not yet been checked against a real file. The remote address is not reported on Linux.
● Supported compiled
the Terminal Services session table (WTSEnumerateSessionsW plus a per-session WTSQuerySessionInformationW), PROJECTED from the logon sensor's exec-free reader rather than re-implementedNote · Reports who is signed in now, from the live Terminal Services session table; unlike Linux and macOS it does not report sessions that have already ended. Not yet verified on a real Windows host.
● Supported proven
/var/run/utmpx, parsed with a record layout measured on this platform (628-byte records) rather than taken from a header.Note · The record layout was measured on a real Mac and checked against the system's own who command, and login times outside 1980–2100 are rejected rather than reported. This is an accounting table: a session that ended without a clean logout can still appear and one that wrote no record will not, so rows are not a count of people logged in.
Interfaces and proxy configuration, collected without running a program
every interface with its promiscuous state, and the host's system, user and environment proxy configuration — the two ends of one question: is anything sitting on this host's traffic that should not be
● Supported compiled
The standard interface list plus /sys/class/net/<if>/flags for IFF_PROMISC (the same 0x100 bit the macOS ioctl reports), and the shell-wide environment files.Note · An interface whose flags cannot be read (for example, in a container without /sys) is reported as not determined, never as clean. Per-user GNOME and KDE proxy settings are not read.
● Supported compiled
The standard interface list, and the WinINET Internet Settings registry keys in both the user and machine hives.Note · Windows does not expose promiscuous mode through an ordinary read, so it is reported as not determined for every interface rather than as off. The machine-wide WinHTTP proxy is not read; the WinINET settings are.
● Supported proven
The standard interface list plus an SIOCGIFFLAGS ioctl for IFF_PROMISC, the SystemConfiguration preferences (a binary property list, parsed in house) and the shell-wide environment files.Note · Promiscuous mode is reported as a fact, not scored: the Thunderbolt bridge macOS ships with sets it on its member interfaces by default. Proxy settings are reported whether enabled or not, since a disabled proxy that still names a destination is a configured interception path. Interface flags matched ifconfig exactly on a real Mac.
The forwarding table and the neighbour cache, collected without running a program
where this host sends packets and which machines it believes are on the wire beside it — with every route carrying its ORIGIN, so a route somebody configured and a host route the kernel cached on contact are different evidence
● Supported compiled
the kernel's own /proc/net/route, /proc/net/ipv6_route and /proc/net/arp tables, read as filesNote · Declared partial: policy routing (ip rule and its extra tables) and the IPv6 neighbour cache are not reported. Incomplete ARP entries are flagged so their all-zero hardware address is not read as real.
● Supported compiled
The IP Helper API — GetIpForwardTable and GetIpNetTable through iphlpapi.dll, loaded from the absolute system directory.Note · IPv4 only, declared partial: the dual-stack tables are not read because their layout could not be verified, and a wrong layout would return plausible but wrong addresses.
● Supported proven
The BSD routing socket — a NET_RT_DUMP sysctl decoded as routing messages; the ARP cache is the same table under the kernel's RTF_LLINFO filter.Note · Matched arp and netstat exactly on a real Mac. Every route carries its origin, including host routes the kernel created on first contact, which netstat does not print — these reveal recent traffic and are classed as metadata. Cached routes legitimately change between collections.
Who can elevate on this host, and every key that can log into it
the sudoers rule table across its whole include graph, and every SSH key at whatever path sshd is actually configured to read — with no key material and no password field, ever
● Supported compiled
the same two include graphs and the same account projection; /etc/sudoers plus the /usr/local and /opt variants a source-built sudo readsNote · Declared partial: a host using AuthorizedKeysCommand cannot be fully enumerated by reading files. The configuration parsing is shared with macOS and tested there; the Linux file locations have not yet been verified on a Linux host.
● Supported compiled
%PROGRAMDATA%\ssh\sshd_config and its Include graph, plus the profile directories under %SYSTEMDRIVE%\UsersNote · Windows has no sudoers file, so that half is refused and points to user rights instead. Authorised SSH keys are read, including administrators_authorized_keys, which grants every member of Administrators at once. Declared partial: user profile folders are a lower bound on accounts, not a count.
● Supported proven
The sudoers include graph (#include, #includedir, @include and @includedir, relative paths resolved against the including file as sudo resolves them) and sshd's own configuration for the AuthorizedKeysFile patterns, then those paths under each account the account directory lists — with nothing executed.Note · Follows sshd's own configuration for where authorised keys live, including key files moved out of home folders; a host that delegates key lookup to AuthorizedKeysCommand is named rather than reported as having no keys. Key fingerprints match ssh-keygen. Reading sudoers needs root: an unprivileged agent reports insufficient privilege, never zero rules.
The credential stores, ticket caches and rights tables — by presence, never by content
the PAM stack and its include graph, the platform's privilege-assignment table, and the EXISTENCE and last-write of every credential store and ticket cache — opened by stat(), never by read()
● Supported compiled
the same /etc/pam.d read; /etc/security/capability.conf for pam_cap; the gnome-keyring, kwallet, browser and cloud-credential paths; and both the /tmp and /run/user Kerberos cache locationsNote · File capabilities set on binaries are not collected — finding them needs a filesystem walk, which is a separate file collection. Kerberos caches held in the kernel keyring or a daemon are not files and are not seen; both the /tmp and /run/user cache locations are read.
● Supported compiled
The LSA privilege-assignment table (the same reader host hardening uses), and file-status checks over the DPAPI credential, Vault, Protect and browser stores per profile.Note · Reports the privilege-assignment table, keeping the rights it could read even when others fail. Kerberos tickets live in the LSA with no cache file, so that request is refused rather than answered with zero. Windows has no PAM; the privilege table is its equivalent.
● Supported proven
the /etc/pam.d service directory read as text; Lstat over the keychain, browser and cloud-credential paths per account; and the TCC consent databases by presenceNote · Credential stores are checked by presence and metadata only — never opened. A PAM include that points at a missing file is reported, since that is where a passwordless-sudo change would hide. The privacy (TCC) databases are reported by presence only; their grants are not read. Zero file-based Kerberos caches does not mean no tickets: macOS keeps them outside files by default.
The Windows account database — the SAM and the LSA, keyed by SID
local accounts, local groups and their members, and the live session table — read natively, with nothing executed, and with every account's SID classified by its SHAPE rather than by its name
× Unsupported declared
Linux has no SAM either: its accounts are the POSIX files plus the name-service directory, which the account database collection already reads. Its remaining gap — a host joined to SSSD or LDAP whose accounts appear in no file — is a limit still to be measured, not a mechanism to port.
● Supported compiled
netapi32's NetUserEnum / NetLocalGroupEnum / NetLocalGroupGetMembers for the SAM, advapi32's LookupAccountNameW for the machine SID, and the logon sensor's own WTS reader for the session tableNote · Accounts are classified by security identifier, never by name, so a renamed built-in Administrator is still recognised. The SAM hive file itself is not read. The classification logic is tested; the Windows API calls have not yet been verified on a Windows host.
× Unsupported declared
macOS has no SAM: its accounts are the POSIX files plus Open Directory, which the account database collection already reads. This row describes the Windows mechanism, and nothing on macOS is waiting for it.
A declared log path, and the rotated files beside it
a bounded read of a named log and of its rotated predecessors, ordered newest-first so the bound cuts the OLDEST lines — decompressing gzip and bzip2 in-process, and listing what it cannot open
● Supported compiled
the same directory scan and shared byte budget; logrotate's numbering and its dateext form are both covered because the ordering never reads a filenameNote · The rotation logic is platform-independent and tested; it has not yet run on a Linux host. The binary systemd journal is not read here — see the journal row.
● Supported compiled
the same scan; Windows applications that write plain text logs rotate them by the same sibling conventionsNote · For application text logs such as IIS or a service's own log file. The Windows Event Log is a binary format covered by the event-log row, not this one.
● Supported proven
A directory scan for the named file's rotated copies, ordered by modification time and read newest-first under one shared byte budget, with gzip and bzip2 decompressed in process.Note · Rotated files are ordered by modification time, not by name, so the newest lines come first whatever the naming scheme. gzip and bzip2 rotations are read; xz and zstd rotations are listed with their size but not read. A coverage ratio is given only when no rotation is compressed.
Which subsystems the macOS unified log recorded — the tracev3 catalog, never the messages
the subsystem and category vocabulary every .tracev3 under /var/db/diagnostics carries, with a per-compression census of the message chunks that are not readable, and nothing executed
× Unsupported declared
The unified log is a macOS format and Linux has none; the Linux equivalent is the systemd journal, collected by the systemd journal row. This is an absence by design, not a missing implementation, and the request is refused with that reason.
× Unsupported declared
Windows has no unified log; its equivalent is the Windows Event Log, whose record frames the Windows event log row reads. An absence by design, and the refusal names the equivalent rather than a privilege an operator could grant.
● Supported proven
A direct in-process walk of the unified log's .tracev3 chunk stream: the plaintext catalog chunks are read, and every compressed chunk set is identified by its compression signature and skipped. Nothing is executed and nothing is decompressed.Note · Reports which subsystems and categories the unified log recorded — never the messages, which macOS compresses in an unpublished format this agent does not decode. Checked against macOS's own log tool: 22,577 of 22,582 names matched; a name that never became a catalog entry cannot be seen. It does not say which process used which subsystem. Needs read access to the log store (root or the admin group); without it the read is refused, not reported empty.
The systemd journal, read as bytes in process
every entry in every .journal file the host keeps — persistent and volatile, abandoned files included — assembled from the data objects each entry points at, with nothing executed
● Supported compiled
The journal's on-disk binary format, read by an in-house parser — object headers, entry objects and the data objects they reference — over /var/log/journal and /run/log/journal.Note · Reads journal files directly, including the compact format of systemd 252 and later and abandoned .journal~ files. Payloads compressed with XZ, LZ4 or ZSTD are not decompressed: those entries are flagged as missing a field, never shown as empty. Ships the newest entries that fit the size budget and says how many older ones remain. Checked against journalctl on real systemd 255 files.
× Unsupported declared
Windows has no systemd journal; its equivalent is the Windows Event Log, whose record frames the Windows event log row reads. An absence by design, and the refusal names the equivalent rather than a privilege an operator could grant.
× Unsupported declared
macOS has no systemd journal; its equivalent is the unified log, whose catalog the unified log row reads. An absence by design, not a missing implementation, and the request is refused with that reason.
The firewall policy a host is CONFIGURED with
pf, nftables, iptables, firewalld and ufw configuration — every file their include and anchor-load directives name — and the Windows Defender Firewall policy store (local and Group Policy), with the artifact stating that a configuration is not an enforcement claim
● Supported compiled
the saved nftables, iptables, firewalld and ufw configurations across the common distribution paths, and the files their include directives nameNote · Reports saved configuration, not live rules — live nftables and iptables rules are held by the kernel and are not read. The default chain policy is reported as its own line, and firewalld's vendor defaults are not presented as this host's policy. Wildcard includes are listed, not followed. The file locations have not yet been verified on a Linux host.
● Supported compiled
the Windows Defender Firewall policy store in the registry — HKLM\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy (local) and HKLM\SOFTWARE\Policies\Microsoft\WindowsFirewall (Group Policy): each profile's switches and logging, and every FirewallRules value parsed from its v2.x Action/Dir grammar — read through the registry API with nothing executedNote · Reports the Windows Defender Firewall policy store, local and Group Policy, labelled separately because Group Policy overrides the local setting. It is configuration, not live enforcement: a stopped firewall service, a pending Group Policy refresh or a rule added directly through the filtering platform is not visible. Not yet verified on a real Windows host.
● Supported proven
/etc/pf.conf and every file its load-anchor directives name, read as files with nothing executed.Note · Reports the configured policy, not what is enforced: macOS ships pf disabled, and rules loaded by hand change enforcement without changing any file. The running state is not read. Anchor files named by pf.conf are followed. The separate Application Firewall is not listed.
The Windows event log's record frames, identifiers and checksums
every record's frame — its identifier, timestamp, size and the size of the content not read — plus the format's own CRC32 verdicts and every gap in the identifier sequence
× Unsupported declared
The same absence by design; the Linux equivalent is the systemd journal, which the systemd journal row already reads.
● Supported compiled
The .evtx container read in process by an in-house parser — file header, 64 KiB chunks and 24-byte record frames — over %SYSTEMROOT%\System32\winevt\Logs.Note · By default ships each record's identifier, time and size — enough to spot gaps suggesting records were removed, though a rolled or aged-out log has gaps too. With the content option it also renders each record as Windows event XML, which carries command lines and account names, and that content is decoded onto the forensic timeline. Works on copied files and disk images as well as live hosts. Not yet verified on a Windows host.
× Unsupported declared
The .evtx format is a Windows artifact, so there is nothing here to read; the macOS equivalent is the unified log. An absence by design, not a permission an operator could grant.
The socket table, collected without running a program
every internet socket with its endpoints, its state and its owning process — the listening set and the connected set as separate answers, because 'what is this host exposing' and 'what is it talking to' are different questions
● Supported compiled
/proc/net/{tcp,tcp6,udp,udp6} with owners resolved through /proc/*/fd — the sweep's own reader, which was already exec-free and is reused rather than rewrittenNote · Uses the same reader as the agent's background network sensor, which is verified on Linux; the collection request itself has not yet run on a Linux host.
● Supported compiled
GetExtendedTcpTable and GetExtendedUdpTable through stdlib syscall — the sweep's own reader, already exec-free and reusedNote · Windows' UDP table has no remote address, so every UDP row is reported as a listener.
● Supported proven
the proc_info syscall — proc_listpids, then PROC_PIDLISTFDS and PROC_PIDFDSOCKETINFO per descriptor — decoded from struct offsets measured on this platformNote · Collected without running lsof, through a system interface whose layout was measured on a real Mac; every listener matched lsof. The owning process name and the socket inode are not reported.
The open-handle inventory of every process
which files, sockets, pipes and named objects each process currently holds open — what a process is doing rather than what it is
● Supported compiled
/proc/<pid>/fd — one readlink per descriptor, never an open: the link target carries both the kind and the name (socket, pipe, anonymous inode, memfd), and opening the descriptor would change what is being observed.Note · In-memory files with no path on disk (memfd) are reported as their own kind. Kernel placeholder names such as socket:[12345] are not presented as file names.
● Supported compiled
NtQuerySystemInformation(SystemExtendedHandleInformation) for the system-wide table; each handle duplicated and classified by GetFileType, and NtQueryObject called for disk files only.Note · Declared partial: names are looked up only for disk files. Pipe, socket, device and unclassifiable handles are counted but not named, because asking Windows for some pipes' names can hang the caller permanently.
● Supported proven
proc_info(PROC_PIDLISTFDS) for the descriptor table and PROC_PIDFDVNODEPATHINFO for a file's path — the same walk the socket table uses.Note · No Full Disk Access needed, but an unprivileged agent can read only processes its own user owns: on a measured Mac, all of those, 5 of 119 other users' processes and none of 173 root-owned ones.
The thread inventory of every process
what is running inside each process — thread id, name and run state — and, where the platform can say so, where each thread started and whether a file maps that address
● Supported compiled
/proc/<pid>/task/<tid> — the thread's name and its state from stat, whose field is found after the last ')' because a thread may give itself a name containing one.Note · No start addresses: Linux does not expose a thread's entry point, and approximating one would produce false injection findings.
● Supported compiled
CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD) for the inventory and NtQueryInformationThread(ThreadQuerySetWin32StartAddress) for each thread's start address, checked against that process's own region map, so whether a start address is file-backed is answered rather than assumed.Note · The only platform that reports whether each thread started inside a file-backed module — the signal for injected threads. Where a protected process withholds a start address, none is reported, rather than a zero or a verdict.
● Supported proven
proc_info(PROC_PIDLISTTHREADS + PROC_PIDTHREADINFO) — no task_for_pid, giving each thread's id, its 64-byte name and its run stateNote · Lists thread ids, names and run states without special entitlements, but only for processes the agent's user owns; root-owned processes answer nothing. macOS does not expose thread start addresses here, so the injected-thread question is not answered on this platform.
The loaded-module list of every process
which shared objects and DLLs each process has mapped, with the base address and whether any mapping of the file is executable — the inventory an analyst reads beside the process table and the region map
● Supported compiled
derived from /proc/<pid>/maps — the distinct file-backed mappings, deduplicated per (pid, path) so three mappings of one library are one module and one library in forty processes is forty factsNote · Derived from each process's file-backed memory mappings. Module signature verdicts are not included; use the code-signature request for that.
● Supported compiled
CreateToolhelp32Snapshot(TH32CS_SNAPMODULE|TH32CS_SNAPMODULE32) — the loader's own module list, with each module's base address and full path, so this platform answers from the loader rather than inferring from mappingsNote · Reads the Windows loader's own module list. A process that refuses the snapshot, such as a protected anti-malware service, is counted rather than left out.
● Supported proven
derived from the same proc_info(PROC_PIDREGIONPATHINFO) walk the region map uses — no task_for_pid, no Full Disk AccessNote · Partial by ownership: a process the agent's user does not own is reported as not determined, never as a process with no libraries. Whether running as root widens this has not been measured.
Process memory region maps (memory Tier 1)
where each region of a process's address space is, what it is allowed to do, and what file backs it — the unbacked-executable and W^X tells, collected without reading a byte of memory content
● Supported compiled
/proc/<pid>/maps, parsed by field position rather than by splitting on whitespace (a mapping's path may contain spaces), with file backing decided by the inode, never by whether a path came back.Note · Private/shared flags and per-region memory use are not reported. A file whose real name ends in "(deleted)" cannot be told apart from a deleted file at this level.
● Supported compiled
VirtualQueryEx across each process's user address space, with GetMappedFileNameW naming the backing file; the region type decides backing (MEM_IMAGE and MEM_MAPPED are backed, MEM_PRIVATE is not), so a failed name lookup does not turn a backed region into an unbacked one.Note · Backing file paths are reported in NT device form (\Device\HarddiskVolumeN\…) rather than with drive letters.
● Supported proven
proc_info(PROC_PIDREGIONPATHINFO) — no task_for_pid and no Full Disk Access; the structure layout is taken from the published <sys/proc_info.h> header rather than guessed.Note · Partial by ownership: macOS names backing files only for processes the agent's user owns. Other processes are counted separately and their regions are not shipped, rather than being reported as unbacked. Paths are fully resolved (/private/var, not /var). Whether running as root widens coverage has not been measured.
The autostart surface, collected without running a program
every configured autostart entry with the same per-entry identity the live persistence watcher derives, so a collection can be joined to the change stream — and with the binary property lists the watcher reports as unparsed actually parsed
● Supported compiled
The file-backed surfaces the persistence watcher declares — systemd units including .timer, .socket and .path, cron in all its locations, init scripts, udev, PAM, ld.so.preload, shell configuration and /etc/profile.d — read through confined handles, with systemd units also parsed for what they run.Note · Parses systemd services, timers, sockets and path units, alongside cron, init scripts and the other autostart files. Whether a unit is enabled, and units generated at boot under /run, are not reported — an entry means installed, not necessarily active. Not yet verified on a Linux host.
● Supported compiled
the registry autostart roots (Run/RunOnce/RunOnceEx/RunServices in both views, the policy Run key, Winlogon and its Notify packages, Image File Execution Options, SilentProcessExit, User Shell Folders and Active Setup, across HKLM and every loaded user hive), the service control manager and the scheduled-task store — the persistence watcher's own exec-free collectors, reusedNote · Covers the registry autostart keys, configured services and scheduled tasks. Service-DLL registrations and application-shim entries are not included, and the result says so. An entry means configured to start, not running now; program signatures and owners are not included in this collection.
● Supported proven
The file-backed surfaces the persistence watcher declares — launch agents and daemons, login items, cron, periodic, rc, PAM, shell configuration, sudoers, authorized_keys, Python hooks and the deprecated startup items — read through confined handles, with both property-list encodings parsed in house.Note · Reads launch agents and daemons in both property-list encodings, login items, cron and the other file-based autostart locations. Apple's own SIP-protected launch jobs are skipped, and the result says so. A job switched off with launchctl disable still appears here as installed.
Installed software, collected without running a package manager
every installed package with its identifier, version and location, read out of the package database's own files — so an investigator can ask what is installed on a host under investigation without that host running a program an attacker may have replaced
● Supported compiled
The package databases read directly: dpkg's /var/lib/dpkg/status, apk's /lib/apk/db/installed, pacman's per-package desc files under /var/lib/pacman/local, and rpm's sqlite and Berkeley DB databases. The ndb format is not read and is refused by name.Note · Reads the dpkg, apk and pacman databases, and rpm databases in the sqlite or Berkeley DB format. The ndb rpm format is not read and such a host is told so by name; a host with no readable package database is refused rather than reported as having no software. Install time and publisher are mostly not recorded by these databases.
● Supported compiled
The registry: the Uninstall keys in all three views (HKLM 64-bit, HKLM WOW6432Node, HKCU) and the per-user Appx package repository, read through the same enumeration as the scheduled inventory.Note · Read from the registry's Uninstall keys in all three views and the per-user app-package list. WMI's Win32_Product is never queried, because enumerating it makes Windows Installer reconfigure every MSI package on the host. The per-package file list is not included.
● Supported proven
The installer receipt database (/var/db/receipts/*.plist) and the application bundles (/Applications, /System/Applications), read through confined handles and parsed in house — both property-list encodings.Note · Reads installer receipts and application bundles and keeps them separate: a product with different versions in each points to an update that bypassed the installer. Publisher, install size and bundle install dates are not reported, because macOS does not record them reliably.
Declared dependencies — the libraries a package manager cannot see
the language and runtime dependency manifests as found on disk — npm package-lock.json, Go go.mod, Rust Cargo.lock, Python requirements.txt, Ruby Gemfile.lock, PHP composer.lock, Java pom.xml, gradle.lockfile and .jar/.war/.ear archives — so "is this library anywhere on the estate" is answerable on a host under investigation without running anything
● Supported compiled
The same walk and the same readers — the collection takes a root as an argument, and nothing in a directory walk, a lockfile format or a manifest parser differs by platform.Note · The same platform-independent readers as on macOS. A manifest the agent cannot open — common when it runs as non-root — is reported, never silently skipped.
● Supported compiled
The same portable walk; the readers are byte-level formats indifferent to the host, and paths are reported with forward slashes rather than the platform's separator.Note · The same platform-independent readers; paths use forward slashes on every platform so results join consistently.
● Supported proven
A bounded directory walk from an investigator-named root through seven in-house readers — six text formats plus the jar's own META-INF/MANIFEST.MF inside its zip container — skipping node_modules, vendor, target, .git and virtual-environment directories by name.Note · Reports what lockfiles and manifests in a folder you name declare — not installed software, and not proof the code runs. Version ranges are never reported as installed versions. Dependency folders such as node_modules are not walked; the lockfile beside them is read instead. Java archives are read directly, and because many carry no identity of their own, their two identity sources are reported separately. Versions a pom.xml inherits from a parent are left empty rather than guessed.
Snapshot enumeration — where a copy of the file the attacker deleted might still be
which of this host's mounts are snapshots, which of its volumes could hold one, and — on Windows — which shadow copies answer; the enumeration only, because reading a file out of a snapshot is file content and belongs to a collection declared at that privacy class
● Supported compiled
/proc/self/mountinfo for mounted ZFS snapshots, btrfs subvolumes and overlay mounts, and /sys/block/dm-*/dm/{name,uuid} for the device-mapper view — both through rooted handlesNote · Reports mounted ZFS snapshots, btrfs subvolumes, overlay mounts and device-mapper volumes. From these files it cannot tell a btrfs snapshot from an ordinary subvolume, or which LVM volumes are snapshots, and it says so.
● Supported compiled
A bounded, read-only open probe of each \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopyN, plus the System Restore configuration under SOFTWARE\Microsoft\Windows NT\CurrentVersion\SystemRestore in the registry.Note · A bounded probe, not a full listing: shadow copies are checked up to a stated number, a copy numbered above it is not seen, and the ceiling is reported beside the count. The probe opens read-only and creates nothing. Also reports whether System Restore has been turned off.
● Supported proven
getfsstat(MNT_NOWAIT) for the mount table and its MNT_SNAPSHOT/MNT_ROOTFS flags, and getattrlist(ATTR_VOL_CAPABILITIES) per mount for VOL_CAP_INT_SNAPSHOT — both published in the platform's own SDK headers, neither destructive, no exec and no cgoNote · Reports snapshot mounts and which volumes support snapshots. On every modern Mac the system volume is itself a snapshot mount, and it is labelled as such rather than raised as a finding. Unmounted APFS snapshots are not listed: the only direct interface also carries destructive operations, and the listing tools would mean running a program.
Application configuration and logs — how they got in, what went out
where the remote-access tools, cloud-sync clients, browsers, servers and credential stores that matter to an investigation keep their configuration and logs — located against a curated table, with the table's own denominator published beside every answer
● Supported compiled
the same catalogue Lstat, 5 entries on this platformNote · Every location in the built-in list comes from vendor documentation and none has yet been seen on a real Linux host, so a miss is weaker evidence of absence than on macOS.
● Supported compiled
the same catalogue Lstat, 5 entries on this platformNote · Every location in the built-in list comes from vendor documentation and none has yet been seen on a real Windows host.
● Supported proven
an Lstat of each path in a compiled-in catalogue (12 entries on this platform), resolved against the collecting user's home and the system locations; no file is opened, no directory is walkedNote · Checks a built-in list of known application locations for presence only; nothing is opened. Each result says whether that location was seen on a real host or taken from vendor documentation, and an installed application whose locations all miss is reported as installed but not located. Coverage is the list's, not the platform's.
Windows Prefetch execution evidence
the artifact that proves a program ran after the program has been deleted — read out of the compressed container Windows 10+ wraps every .pf in
× Unsupported declared
A Linux host keeps no Windows Prefetch directory. A .pf file taken from an attached disk parses with the same reader, but collecting a foreign disk is disk imaging, with a different privacy class — a separate collection, not this one.
● Supported compiled
A confined read of %SystemRoot%\Prefetch, then an in-house Prefetch parser: the compressed MAM container unwrapped (LZ77 plus Huffman), the SCCA header, the per-version file information (versions 17, 23, 26, 30 and 31), the file-metrics array and the filename strings; plus the disk-state check the anti-forensic marker needs, made only for a local volume device path.Note · The program's current disk state is checked only when the recorded path is on a local volume — never for a network path, which would make the agent authenticate to another host; otherwise it is reported as not determined. Prefetch files in an unrecognised layout are counted, not guessed at. Reading a real Prefetch folder has not yet been verified on a Windows host.
× Unsupported declared
The same scope decision as Linux: a Mac keeps no Windows Prefetch directory, and macOS records program execution in its own formats rather than in Prefetch files.
Windows registry hives, read while the system holds them locked
SYSTEM, SOFTWARE and a logged-off user's NTUSER.DAT, obtained through the volume rather than opened — the persistence surface without a remote shell and without reg save
× Unsupported declared
A Linux host has no Windows registry of its own to collect. A hive file on an attached disk parses with the same reader, but collecting a foreign disk is disk imaging, with a different privacy class — a separate collection, not this one.
● Supported compiled
A raw, read-only open of the volume by drive letter, then the NTFS directory index to the hive's file record (every entry checked against the record it names), its data stream, and an in-house hive parser: base block, hive bins, cells, key and value records, and the parent's subkey list as confirmation that a key is a key.Note · The SAM and SECURITY hives are refused, because they hold credentials. Returns a stated selection — the 512 most recently written keys — not the whole hive. A hive with pending log writes is read as it is on disk, and the result says so. Reading a real volume has not yet been verified on a Windows host.
× Unsupported declared
The same scope decision as Linux: a Mac's configuration lives in its preference files, covered by the application configuration and autostart rows, and an attached Windows disk is a foreign volume to be imaged rather than the host's own configuration.
Code-signature verdict for a named file
who vouched for an executable, and whether its bytes are still the bytes that were signed — rendered without running codesign
× Unsupported declared
ELF has no standard embedded code signature, so there is no verdict to give for a Linux executable. The same reader does check a Mach-O file found on a Linux host, and an ELF file is reported as unreadable with that reason — never as unsigned.
● Supported compiled
WinVerifyTrust under the Authenticode policy, then the system catalog store. The catalog stage is essential: most Windows system binaries and drivers carry no embedded signature, so an embedded-only check would call ntoskrnl.exe and a dropper equally unsigned. Both stages work from the already-opened file handle, never the path, so the file cannot be swapped between the confinement check and the verification.Note · Checks the embedded signature and falls back to the system catalog, which is how most Windows system files are signed. Revocation is not checked — a certificate revoked after issue reads as trusted — and the signer's name is not reported.
● Supported proven
An in-house Mach-O signature verifier: fat or thin binary, the code-signature load command, the SuperBlob, every CodeDirectory's page and special-slot hashes checked against the file's own bytes, the CMS signature over the bound CodeDirectory (BER or DER), and a chain to the pinned Apple Root CA.Note · Verifies the page hashes, the signature and the chain to Apple's root. Not checked: revocation, notarisation tickets, the secure timestamp, and a bundle's external resources.
Build hardening of a named executable
what an executable's headers say about how it was built — PIE, NX, RELRO, stack canary, Fortify, forward/return-edge CFI, ASLR, hardened runtime — and what it is (format, arch, build-id, linked libraries, toolchain, declared signer), read without running anything
● Supported compiled
The same portable reader; no platform-specific code beyond the confined file open.Note · The same platform-independent reader as on macOS, tested on committed sample binaries; not yet verified on a Linux host.
● Supported compiled
The same portable reader; no platform-specific code beyond the confined file open.Note · The same platform-independent reader as on macOS, tested on committed sample binaries; not yet verified on a Windows host.
● Supported proven
A confined file open, then an in-house executable reader: ELF program headers, dynamic section and GNU notes; PE optional header and load config; Mach-O (thin and fat) header flags, imports and code directory; and Go build information.Note · Reports build-hardening properties of ELF, PE and Mach-O files, with "unknown" and "not applicable" kept distinct from "off". No disassembly, and signatures are read rather than verified (use the code-signature request). Checked against the platforms' own inspection tools over 22 test binaries.
File metadata and extended attributes
the timestamps, ownership and extended attributes a portable FileInfo does not carry — the fields that say whether a file's own story is consistent
● Supported proven
stat for access and inode-change times, owner, group, inode and link count; listxattr and getxattr for extended attributes.Note · Creation (birth) time is not reported on Linux. Change time is, and a modification time older than the change time is the classic sign of a back-dated file (ATT&CK T1070.006).
● Supported compiled
Win32FileAttributeData for atime/btime (creation) and the attribute word; a reparse-point-safe handle for FILE_BASIC_INFO.ChangeTime (GetFileInformationByHandleEx), GetFileInformationByHandle for link count and file identity, and GetSecurityInfo for the owner and group SIDs; NTFS Alternate Data Streams (FindFirstStreamW/FindNextStreamW) as the attribute surface, each named stream read boundedNote · Reports all four NTFS timestamps, the owner, and every named alternate data stream, with a summary of the Mark-of-the-Web zone record showing where a downloaded file came from. Not yet verified on a real Windows host.
● Supported proven
stat including the file's birth time; the listxattr and getxattr system calls invoked directly for extended attributes.Note · Reports all four timestamps and the quarantine attribute, which records where a downloaded file came from. macOS adds a provenance attribute to ordinary files, so a non-empty attribute list is normal rather than a finding.
Acting on the host
13 rows
Capability
Linux
Windows
macOS
Network containment (block / isolate)
enabled with -enforce: block an indicator, or isolate the host so it can reach only the platform
● Supported proven
nftables, falling back to iptablesNote · Verified on a real aarch64 Linux host (kernel 6.12) inside an isolated network namespace, on nftables and on the iptables fallback: block, isolate, re-isolate, lift, loopback kept, and an empty allowlist refused.
● Supported compiled
netsh advfirewallNote · The firewall state is saved before isolation and never overwritten, so lifting isolation always has a prior state to restore.
● Supported compiled
a pf anchor and tableNote · Needs root. Verifying it means changing a live host firewall, so it waits for a disposable test machine.
Microsegmentation enforcement
enabled with -enforce-segment: program this point's compiled ruleset into the host packet filter (shadow mode counts, block mode enforces)
● Supported proven
nftables (one atomic table replace), falling back to iptables/ip6tablesNote · On nftables the whole ruleset is replaced in one transaction, with no unprotected window. The iptables fallback has a brief interval with no rules while it refills, and the agent reports which is active. Verified on a real aarch64 Linux host (kernel 6.8) in an isolated network namespace, on both backends: traffic a rule allows passes in each direction, traffic a rule denies and traffic no rule covers are dropped, loopback keeps working, and the counting mode blocks nothing while still counting.
● Supported proven
Windows Filtering Platform filters on the connection-authorization layers, IPv4 and IPv6, in the agent's own sublayer — the whole set replaced in one transaction.Note · Built and awaiting its first run on a real Windows host. The rules are replaced in one Filtering Platform transaction, so there is no unprotected window, and they survive an agent restart but not a reboot, as on Linux and macOS. The counting mode is built from the platform's allow events, so its numbers are a lower bound, and it turns on a host-wide logging setting that is restored when the mode is switched off.
● Supported compiled
a pf anchor whose ruleset is replaced on each load, with per-rule labels carrying the shadow countersNote · pf only evaluates anchors the main ruleset references, so applying a policy first adds a marked hook line to /etc/pf.conf.
In-kernel execution block
refusing a binary before the image runs (-enforce-exec)
● Supported proven
an eBPF LSM deny map (-EPERM on execve), keyed by device+inodeNote · Needs the eBPF LSM program loaded first (deploy/linux/ebpf/load-lsm.sh). Where the filesystem provides dm-verity, its digests are used.
● Supported compiled
the code-integrity driver deny-set (STATUS_ACCESS_DENIED at process creation)Note · Needs the code-integrity driver installed first (deploy/windows/execblock/install-execblock.ps1).
● Supported compiled
an Endpoint Security daemon denying ES_EVENT_TYPE_AUTH_EXECNote · Needs the Endpoint Security daemon installed and granted Full Disk Access (deploy/macos/execblock/install-execblock.sh).
Process-tree kill
enabled with -enforce-kill: terminate a process and its children
● Supported proven
signal delivery to the process groupNote · Kills the whole process group. Verified on a real aarch64 Linux host (kernel 6.12).
● Supported compiled
taskkill /T /F, resolved from System32, with single-process TerminateProcess as the fallbackNote · Kills the whole process tree with taskkill; if that fails, the fallback ends only the one process, not its children.
● Supported proven
signal delivery to the process groupNote · Kills the whole process group; verified by checking that a child process dies too.
Service restart
enabled with -enforce-restart: restart the service that supervises a pid, then verify the old pid exited — a process no service manager supervises is refused, never killed
● Supported proven
the pid's systemd unit from /proc/<pid>/cgroup (v2 unified line, v1 name=systemd fallback) → systemctl try-restart; a session/container .scope or a user@ manager is refusedNote · Restarts the service that supervises the process and then checks the old process is gone; a process no service manager supervises is refused rather than killed. Verified on a real aarch64 Linux host (kernel 6.8, unified control groups) with a throwaway service: the old process exited and the service came back under a new process id, and a process in a transient scope or under a user's own session manager was refused and left running. The legacy control-group layout has not been verified on a host that uses it.
● Supported compiled
the pid's service from tasklist /svc → net stop + net start (synchronous); a shared svchost hosting several services, or a service with dependents, is refused
● Supported compiled
the pid's system-domain job from launchctl list → launchctl kickstart -k system/<label>; com.apple.* platform daemons are refused (SIP)
Reversible file quarantine
enabled with -enforce-quarantine: a quarantine-file command moves the named file into the agent's own vault, and its rollback puts the file back
● Supported proven
An atomic rename into a private (0700) vault under the agent's state folder (a streamed copy-then-rename when the vault is on another filesystem); restore reverses it using a sidecar that records the original path.Note · Moves the file into a private vault on the host and can restore it to its original path. Verified on a real aarch64 Linux host (kernel 6.12).
● Supported compiled
The same rename-into-vault design as Linux and macOS.Note · Whether a file another process holds open can be moved has not been tested on Windows; a failed move is reported as a failure, never a success.
● Supported proven
An atomic rename into a private (0700) vault under the agent's state folder, restored from a sidecar on rollback.Note · Quarantine works per file. A request naming a whole host has no file to move: it records a marker only, although the action still reports as enforced. The cross-filesystem copy never writes through a symbolic link.
DNS sinkhole
enabled with -dns-addr: a sinkhole-domain command makes the agent's own resolver answer a contained domain locally, so the rendezvous never resolves; rollback lets it resolve again
● Supported proven
a clean-room RFC 1035 UDP forwarder on -dns-addr that answers a sinkholed name (and its subdomains) with the sinkhole address and forwards every other query to -dns-upstreamNote · Enforces only on queries sent to the agent's resolver. Verified on a real aarch64 Linux host (kernel 6.12).
● Supported compiled
the same in-agent UDP forwarderNote · The same resolver code as on Linux and macOS, with the same limits; not yet verified on a Windows host.
● Supported proven
the same in-agent UDP forwarder — no OS facility is involvedNote · Enforces only on queries sent to the agent's resolver: the agent does not repoint the host's DNS, and applications using DNS-over-HTTPS or their own resolver bypass it.
Virtual patching (inline IPS)
enabled with -ips-addr: a virtual-patch command arms a CVE shield on the agent's inline proxy in front of a protected origin, and the next exploit request is refused with a 403 before it reaches the unpatched asset
● Supported proven
a userspace HTTP forwarding proxy on -ips-addr that parses every request head (RFC 9112) and the body prefix, blocks a request matching an armed shield, and forwards the rest to -ips-upstreamNote · Shields only HTTP traffic routed through the proxy. Verified on a real aarch64 Linux host (kernel 6.12).
● Supported compiled
the same userspace proxyNote · The same proxy code as on Linux and macOS, with the same limits; not yet verified on a Windows host.
● Supported proven
the same userspace proxy — no OS facility is involvedNote · Protects only traffic routed through the proxy, and only against vulnerabilities in its built-in catalogue. Requests that are not HTTP or cannot be parsed are passed through, so a virtual patch never causes an outage; request smuggling is the one pattern refused.
Brokered-session termination
a terminate-session command stops a brokered session's recording and kills its host process — the edge half of the privileged-access broker's kill switch
● Supported proven
Stop the session recorder, then signal the process group whose pid the session wrapper recorded — the same mechanism as process kill.Note · Ends sessions started through the session wrapper, independently of the host-wide kill setting, because the session broker has already authorised it. Verified on a real aarch64 Linux host (kernel 6.12).
● Supported compiled
stop the session recorder, then taskkill /T /F on the pid in <session-dir>/<id>.pid (single-process TerminateProcess as the fallback)
● Supported proven
Stop the session recorder, then signal the session's process group — the same mechanism as process kill.Note · Kills only a session the wrapper registered; otherwise the recording still stops and the result says no host process was killed.
Brokered-session recording
a record-session command makes the agent tail a brokered session's transcript and stream it to the broker as strictly-sequenced chunks, reporting the close on the session's done sentinel — the recording half session-termination does not grade
● Supported proven
A polling tail of the session transcript file (written by the agent's session wrapper through script(1), or by an sshd ForceCommand), sent to the platform in chunks with retry, stopping on any client error.Note · Records the transcript written by the session wrapper or an sshd ForceCommand. Verified on a real aarch64 Linux host (kernel 6.12).
● Supported compiled
the same tail of <session-dir>/<id>.castNote · No transcript writer ships for Windows, so the transcript must come from a writer the host provides. For Windows the platform's main path is its server-side jump proxy, which needs no agent.
● Supported proven
the same tail of <session-dir>/<id>.cast, written by -wrap-session's script(1)Note · Records only what the session wrapper writes — it does not capture a terminal itself, so a session not started through the wrapper produces nothing. Without a configured session folder the request is refused. A jump-host agent can record sessions for the hosts it brokers.
Host hardening (apply + verify)
actuating a signed hardening baseline and verifying it against the agent's own compiled catalog
● Supported proven
sysctl, file mode and systemd-unit controlsNote · Only the part of the hardening catalogue expressed as sysctl, file-permission and systemd-unit controls can be applied on Linux.
● Supported compiled
registry values (RegSetValueEx), audit policy (AuditEnumerateSubCategories + AuditQuerySystemPolicy/AuditSetSystemPolicy) and user-rights assignments (LsaOpenPolicy + LsaEnumerateAccountsWithUserRight/LsaAddAccountRights/LsaRemoveAccountRights)Note · Registry, audit-policy and user-rights controls can be applied on Windows. Exercised only by a manual test harness, not yet in an automated Windows run.
● Supported proven
the defaults preference systemNote · Only the catalogue's macOS preference controls apply on macOS; other controls are refused because they would configure nothing here. Reading current state is verified on Apple hardware; applying changes is not yet verified.
On-demand data-at-rest DLP sweep
a sweep-dlp command runs the -dlp-paths classification pass NOW rather than at the next -dlp-every tick, and reports what it found; a read, so rollback is an honest no-op
● Supported proven
The in-agent classification engine over every file under the configured -dlp-paths folders, forwarding findings at or above the configured tier as masked reports.Note · Scans only the folders the agent was configured with. Verified on a real aarch64 Linux host (kernel 6.12).
● Supported compiled
the same in-process classification passNote · The same code as on Linux and macOS, with the same limits; not yet verified on a Windows host.
● Supported proven
the same in-process classification pass the interval loop runs — literally the same functionNote · Scans only the folders the agent was configured with — a request cannot widen that. An agent with no folders configured fails the request rather than reporting no findings, and a request addressed to another host is refused. Findings are forwarded masked.
On-demand YARA file sweep
a scan-files command runs the -scan-paths YARA sweep NOW under the agent's current signed rule set, and reports files read, matches and skips; a read, so rollback is an honest no-op
● Supported proven
The in-agent YARA engine walking the configured -scan-paths folders, with matches forwarded to the platform.Note · Scans only the folders the agent was configured with. Verified on a real aarch64 Linux host (kernel 6.12).
● Supported compiled
the same in-agent YARA sweepNote · The same code as on Linux and macOS, with the same limits; not yet verified on a Windows host.
● Supported proven
The same scan the scheduled sweep runs, serialised by one lock against rule updates.Note · A second scan of an unchanged host reads 0 files by design: files unchanged since the last scan under the same rules are skipped, and there is no forced re-scan. An agent with no rules fails the request rather than reporting clean, and a request addressed to another host is refused.
Not yet placed in a group
9 rows
Capability
Linux
Windows
macOS
TPM attestation — the firmware measurements, signed by the TPM
a TPM 2.0 quote over the firmware PCRs, made for one request and bound to a fresh nonce from the platform, so the measurements the kernel reports can be checked against what the TPM itself signed — with the endorsement key certificate and a credential-activation round that can bind the quoting key to a genuine, manufacturer-certified TPM
● Supported compiled
TPM 2.0 commands written to the kernel's resource manager /dev/tpmrm0 (raw /dev/tpm0 only without it): a fixed-template ECC P-256 restricted signing key under the endorsement hierarchy, PCR_Read and Quote over SHA-256 PCRs 0-7 with the platform's nonce; the endorsement key certificate read from its TCG NV index and the endorsement key from the TCG default template; in a second round, the endorsement key's policy and ActivateCredential — every handle flushed, no external toolsNote · Verified against a software TPM implementation. The platform checks each quote over its own fresh challenge, checks the endorsement certificate against the shipped TPM manufacturer roots and binds the quoting key to that TPM in a second round, automatically for an enrolled Linux host with collection enabled. Certificate revocation is not checked. Needs root or the tss group. Covers PCRs 0 to 7 in the SHA-256 bank only.
● Supported compiled
TPM 2.0 commands submitted through TPM Base Services (tbs.dll, a virtualised TPM 2.0 context at locality 0, cancelled on timeout) — the same command layer as Linux: a fixed-template ECC P-256 restricted signing key under the endorsement hierarchy, Quote over SHA-256 PCRs 0-7 with the platform's nonce, the endorsement key certificate from its TCG NV index, and in a second round ActivateCredential — every handle flushed, no external toolsNote · Built but not yet run against a real Windows TPM. A host without a TPM reports that plainly. The platform does not yet start rounds on Windows hosts by itself; an operator can. An endorsement certificate that the TPM does not store itself is reported as absent. Covers PCRs 0 to 7 in the SHA-256 bank only.
◌ Not available declared
a Mac has no TPM: the Secure Enclave exposes no PCR bank and no quote command, so there is nothing to attest with
Per-peer TCP health
worst round-trip time, retransmits and zero-window count per remote peer, swept with the host metrics
● Supported compiled
sock_diag netlink (INET_DIAG_INFO tcp_info), the interface ss -ti readsNote · The zero-window count needs Linux 5.4 or later; on older kernels it is reported as unknown, never as zero.
◌ Not available declared
not built: GetPerTcpConnectionEStats returns RTT only for connections whose extended statistics were switched on beforehand (SetPerTcpConnectionEStats, administrator), so a sweep would read nothing for every existing connection. Reported as absent rather than zero
◌ Not available declared
not built: macOS exposes per-socket TCP_CONNECTION_INFO only to the socket's owner, and no unprivileged table of other processes' connections carries RTT. Reported as absent rather than zero
Event-driven process-execution telemetry
each exec read within milliseconds of the kernel announcing it, so a process that starts and exits between two sweeps is still reported, with its image, command line and parent
● Supported compiled
the kernel's netlink process-events channel (NETLINK_CONNECTOR, CN_IDX_PROC, PROC_EVENT_EXEC), then the same /proc reads the sweep usesNote · Needs the agent to run with network-administration rights in the host's own network namespace; without them, processes are still found by the periodic sweep. Reports an execution after it happens rather than blocking it, and under an extreme burst of executions some of the shortest-lived processes can be missed.
● Supported compiled
a private real-time ETW session with Microsoft-Windows-Kernel-Process enabled for WINEVENT_KEYWORD_PROCESS (advapi32 + tdh loaded from System32 by absolute path), ProcessStart/ProcessStop read by property NAME through TDH; then the same OpenProcess reads the sweep uses, kept only when the live creation stamp equals the event's CreateTimeNote · Needs the agent to run with administrator rights; without them, processes are still found by the periodic sweep. A process that exits before the agent can open it is still reported with its program path and parent, but without its command line or user. Not yet verified on a real Windows host.
● Supported compiled
EndpointSecurity NOTIFY_EXEC/FORK/EXIT from the signed exec-control daemon (a second ES client beside its AUTH_EXEC veto) over a root-only Unix socket; the record carries the image path and argv, so no per-exec read is neededNote · Needs the EventLake exec-control helper installed, signed with Apple's Endpoint Security permission and approved on the Mac; without it, processes are found by the periodic sweep. Not yet verified on a Mac with that permission.
Event-driven file-integrity re-sweep
a changed directory under a watched path is re-checked within seconds of the OS naming it, instead of at the next scheduled walk
● Supported compiled
inotify(7), one watch per directory, re-armed on each new directory
● Supported compiled
one recursive ReadDirectoryChangesW per root
● Supported compiled
kqueue EVFILT_VNODE over the directories and files (FSEvents needs cgo)
File-integrity writer attribution
a created or modified file under a watched path names the process and user that last wrote it, so the detectors that need a writer can fire
● Supported compiled
fanotify(7) close-write marks on the mounts that hold the watched paths, each write filtered to those paths, with the last writer of each file kept in a bounded cache the integrity check readsNote · Naming the process and user that wrote a changed file needs the agent to run with the CAP_SYS_ADMIN capability, which the standard service does not grant; without it, file changes are still reported, without the writer.
× Unsupported declared
Windows names the process that wrote a file only through a filesystem minifilter, which is a signed kernel driver; file changes are still reported, without the writer
× Unsupported declared
macOS names the process that wrote a file only through Endpoint Security, which needs an Apple-granted permission and a signed client; file changes are still reported, without the writer
Canary file tampering
a decoy credential file the agent planted is checked on an interval, so a write, attribute change, deletion or rename of it is reported and a removed decoy is put back
● Supported compiled
inotify on the planted file for writes, attribute changes, deletion and rename, with a metadata-only interval sweep (size, modification time, mode) as the safety net; the agent never opens a decoy after planting it
● Supported proven
a metadata-only interval sweep of each planted file (size, modification time, attributes); the agent never opens a decoy after planting it
● Supported compiled
a metadata-only interval sweep of each planted file (size, modification time, mode); the agent never opens a decoy after planting it
Canary file reads
someone merely OPENING or reading a decoy credential file the agent planted is reported within moments, with repeated reads folded into one report per interval
● Supported compiled
inotify open and access notifications on each planted file — a watch on the file itself, so the owner's ordinary use of the same directory is never reportedNote · Every read is reported; naming who read the decoy (process, user and program) additionally needs the agent to run with the CAP_SYS_ADMIN capability on a 64-bit system, which the standard service does not grant.
● Supported compiled
Security event 4663 object-access audit notifications paired with the decoy stat sweep
● Supported compiled
Endpoint Security open notifications from the signed helper daemon paired with the decoy stat sweep
Execution-block events
reporting each exec the in-kernel block refused (-enforce-exec), folded per binary with a count
● Supported compiled
The kernel program writes each refused start to a ring buffer the agent reads directly; if the ring fills, the number of unreported refusals is counted and reported.Note · Repeated attempts to start the same blocked program are reported once every few seconds with a count. Needs the kernel program reloaded from the current release; an older loaded program still blocks, but reports nothing.
◐ Not yet declared
The driver change that reports each refused start is written, but no signed build of the driver carries it yet. Until one is installed, programs are still blocked on Windows; the agent reports that the driver cannot yet tell it about each block.
● Supported compiled
The Endpoint Security service reports each refused start over its local connection to the agent.Note · Reported only while the agent's process-start stream from the Endpoint Security service is connected, and needs the service rebuilt from the current release.
Local account disable and reset
disable a local account, or force its password change, on the host itself; each can be undone
● Supported compiled
usermod and chage, with the prior shadow state recorded first and read back afterNote · Undo puts back the account's earlier state; an account that was already locked stays locked. Sessions already open are not ended.
● Supported compiled
net user /active and /logonpasswordchg
● Supported compiled
pwpolicy -disableuser and the password-change policy
Distributions and appliances

The grid above is per operating system. This is where the agent goes: each distribution or appliance, whether the agent runs there, and whether it should be installed there at all. Where it should not, the platform is covered without an agent. Most rows are graded declared: a statement about what an operating system is.

Ubuntu / Debian
proven
Distribution · Linux (glibc, systemd, dpkg)
AgentRuns nativelyInstallNo install restriction
● Supported
the ordinary Linux agent; dpkg inventory, OSV Debian/Ubuntu vulnerability definitions, os-release fingerprint
What it collects: the Linux column above.
Note · The Linux automated test runs on Ubuntu, so this is the distribution every Linux cell marked proven in the capability matrix was proven on.
RHEL / Rocky / AlmaLinux
compiled
Distribution · Linux (glibc, systemd, rpm)
AgentRuns nativelyInstallNo install restriction
● Supported
the ordinary Linux agent; rpm inventory via the BDB and sqlite container readers, OSV Red Hat/Rocky/AlmaLinux definitions
What it collects: the Linux column above.
Note · The rpm readers were proven against real package databases; what is missing for proven status is a Red Hat–family automated test run, not a reader.
Amazon Linux 2023
declared
Distribution · Linux (glibc, systemd, rpm/dnf)
AgentRuns nativelyInstallNo install restriction
◐ Not yet
The agent runs and identifies the host correctly. What is missing is a vulnerability feed: Amazon Linux has no advisory source yet, so every package would be assessed against nothing and still reported as assessed.
What it collects: the Linux column above.
What is left
  • an ALAS advisory source mapped to the rpm comparator
  • a CIS/hardening profile or an explicit declaration that none exists
VMware Photon OS (standalone)
declared
Distribution · Linux (glibc, systemd, rpm via tdnf)
AgentRuns nativelyInstallNo install restriction
◐ Not yet
Nothing blocks the agent: it reads the distribution from os-release without an allowlist, so a Photon host already registers with the correct kernel, libc and init, and the release build is fully static. What is missing is everything around the agent: no Photon advisory feed, no hardening profile, and no run on a real Photon machine.
What it collects: the Linux column above.
What is left
  • Prove the rpm reader against an rpm database written by tdnf — a reader proven on one producer's database has proven nothing about another's
  • A Photon security advisory source with the rpm version comparator
  • A hardening profile, or an explicit statement that Photon has no CIS benchmark
Note · Standalone Photon OS only. Photon is also the base of the vCenter Server Appliance, NSX Manager and the Aria appliances, which are a different row with the opposite answer — see the vCenter appliance row.
Azure Linux (CBL-Mariner)
declared
Distribution · Linux (glibc, systemd, rpm/tdnf)
AgentRuns nativelyInstallNo install restriction
◐ Not yet
same shape as Photon — the agent runs and fingerprints; no vulnerability feed row and no hardening profile exist for it
What it collects: the Linux column above.
What is left
  • a Microsoft advisory source mapped to the rpm comparator
  • shares Photon's tdnf-written rpmdb question
Alpine Linux
declared
Distribution · Linux (musl, OpenRC, apk)
AgentRuns nativelyInstallNo install restriction
◐ Not yet
The two pieces that usually block a musl distribution are already built — musl is identified by its dynamic loader path, and the apk database is read — but Alpine has no advisory source yet, so vulnerability assessment would refuse the host.
What it collects: the Linux column above.
What is left
  • An Alpine secdb source with an apk version comparator (apk's ordering is not close enough to rpm's, and guessing it would buy coverage with false positives)
SUSE Linux Enterprise / openSUSE
declared
Distribution · Linux (glibc, systemd, rpm with the ndb container)
AgentRuns nativelyInstallNo install restriction
◐ Not yet
The only distribution here blocked on a missing reader rather than missing data: SUSE stores its rpm database in the ndb format, which the agent recognises but cannot yet read, so package inventory — and with it vulnerability assessment — is not available on SUSE hosts.
What it collects: the Linux column above.
What is left
  • An rpm ndb reader, proven against a real SUSE package database
  • A SUSE advisory source
FreeBSD / OpenBSD (pfSense, OPNsense, TrueNAS)
declared
Distribution · BSD Unix — a supported Go target, with no backend files in this tree
AgentRuns nativelyInstallNo install restriction
◐ Not yet
The Go toolchain targets FreeBSD and OpenBSD, so the agent builds and runs — but every collection falls back to a placeholder that refuses by naming the missing mechanism, so the agent would register and then collect almost nothing.
What is left
  • A BSD implementation of each collection family — which would also add BSD as a column in the capability matrix, the one item in this table that widens the platform axis
Note · The most valuable real port in this table: it is the only row blocked on code rather than data, and it reaches the open-source firewall and NAS estate.
Talos Linux
declared
Immutable OS · Linux, read-only root, NO shell and no package manager — an API and Kubernetes only
AgentRuns in a hosted containerInstallInstall through the platform's own route
◐ Not yet
the binary runs, and there is no filesystem location to install it into and no shell to install it from. Talos is reached as a privileged DaemonSet or as a system extension baked into the image; neither packaging exists yet
What it collects: the Linux column above.
What is left
  • A privileged DaemonSet manifest with the host mounts the collections need
  • A state folder that survives an image upgrade, since the usual guarantees for /var/lib/eventlake-sensor do not hold on an immutable root
Note · The agent's fallback to /usr/lib/os-release was written for stateless and read-only-root hosts like this one, so host identification already works here.
Bottlerocket / Flatcar / Fedora CoreOS / RHCOS
declared
Immutable OS · Linux, read-only root, ostree or dm-verity images
AgentRuns in a hosted containerInstallInstall through the platform's own route
◐ Not yet
same blocker as Talos and the same fix — these are reached through host-containers (Bottlerocket), systemd-sysext images (Flatcar) or a layered ostree commit (CoreOS/RHCOS), never through a package install
What it collects: the Linux column above.
What is left
  • one container packaging shared with the Talos row — this is a single piece of work that unlocks the whole class
vCenter Server Appliance / NSX Manager / Aria
declared
Appliance · Photon OS — technically IDENTICAL to the `photon` row above
AgentRuns nativelyInstallNot an install target
◈ Agentless
vCenter's own event and task stream, appliance syslog forwarded to the agent's -syslog-addr receiver, and SNMP; the platform assesses the result without an agent.
Note · The platform already detects abuse of this estate from outside it: its hypervisor guest-execution detection (ATT&CK T1675) and its VIB signature-bypass detection rest on guest and log evidence, never on an agent living on the appliance.
VMware ESXi
declared
Other platform · vmkernel — not Linux, and not a Go target
AgentCannot run hereInstallNot an install target
◈ Agentless
ESXi syslog to the -syslog-addr receiver, SNMP traps to -snmp-trap-addr, and the vSphere API; agentless assessment deliberately refuses to treat an ESXi host as Linux.
PAN-OS / FortiOS / F5 TMOS / NetApp ONTAP
declared
Appliance · vendor-sealed Linux or BSD derivatives with read-only or verified root filesystems
AgentCannot run hereInstallNot an install target
◈ Agentless
Each vendor's own management API, plus syslog or CEF to -syslog-addr, SNMP to -snmp-trap-addr and flow records to -netflow-addr — the agent's three built-in receivers.
Arista EOS
declared
Appliance · Fedora Linux, genuinely — with a supported RPM install path
AgentRuns nativelyInstallInstall through the platform's own route
◐ Not yet
The instructive counter-example to the row above: EOS runs a full Linux underneath and accepts RPM extension packages, so installing an agent is possible in principle. What stops it is that nobody has built or tested the extension packaging.
What it collects: the Linux column above.
What is left
  • An EOS extension (RPM) package
  • A decision on which collections are meaningful on a switch, since most host-centric ones are not
Cisco IOS-XE / NX-OS (app-hosting, Guest Shell)
declared
Appliance · vendor Linux with an officially sanctioned container runtime
AgentRuns in a hosted containerInstallInstall through the platform's own route
◐ Not yet
The platform provides an on-box container runtime for hosted applications, so an agent is possible in principle; the resources on a switch supervisor are far below this agent's footprint budget, and what a reduced build would need has not been measured.
What it collects: the Linux column above.
What is left
  • Measure what the agent needs against the platform's app-hosting limits before promising anything — a switch is not a server
z/OS · IBM i · HP-UX
declared
Other platform · non-Linux enterprise operating systems with no Go port
AgentCannot run hereInstallNo install restriction
◈ Agentless
SMF and syslog forwarding to -syslog-addr, and the application's own OTel SDK where one exists — which never needed our agent
AIX · Solaris / illumos
declared
Other platform · supported Go targets (aix/ppc64, solaris/amd64, illumos/amd64) with no backend files in this tree
AgentRuns nativelyInstallNo install restriction
◐ Not yet
These are not below the toolchain floor: Go targets all three, so the agent builds and runs. Every collection falls back to a placeholder, so the agent would register honestly and collect almost nothing — a more tractable problem than having no compiler.
What is left
  • per-family backends, as for the BSD row
  • a prior demand signal — this is the row most likely to be answered agentlessly forever, and saying so is cheaper than a port nobody asked for
QNX · VxWorks · bare-metal RTOS · OT controllers
declared
Other platform · real-time and embedded operating systems; PLCs and field devices
AgentCannot run hereInstallNot an install target
◈ Agentless
Passive industrial-protocol observation, NetFlow to -netflow-addr, and the cell or line controller's own historian.
Releases

No release has been cut yet, so there is nothing to list. This table fills itself from the release ledger when the first one ships — it is not hand-maintained, and nothing has been invented to make it look occupied.

Scope & Honest Limits Honest limits of this matrix Expand · Full ledger →
Compiled is not proven
A compiled cell is enforced at build time without a cited run on real hardware. That is the true state of that cell, and publishing it as a tick would be the lie.
A capability is not a detection
Reading a signal on a platform is a precondition for detecting something with it. What is actually detected, and where that stops, is on the proof page.
Old hosts are refused, not degraded
Operating systems below the toolchain floor get no agent. Collecting from them through another route is possible; pretending the agent runs there is not.
Your build is the authority
This is a snapshot of one build. Each build can generate its own matrix, and where this page and your build differ, your build is right.
The rows that matter are the ones about your operating systems.

Install it on a representative host in a trial and compare what it reports against this table. That is a shorter path to certainty than any matrix.

Request a trial licence See which sources it reads