Docs Getting started
Compatibility
What each release runs on and what it can assess. "Assessed" means installed packages are matched against vulnerability advisories; everything else listed under hosts is inventoried and shown as an evaluation gap, never as clean.
Server
| Supported | |
|---|---|
| Install | Docker Engine 24+ with the Compose plugin, or Kubernetes with the Helm chart in deploy/helm |
| Images | ghcr.io/stackurity/stackurity for linux/amd64 and linux/arm64 |
| Database | PostgreSQL 16 or later (Compose ships 17). Row-level security is used for workspace isolation; on managed databases where the login role cannot create roles, the table owner's FORCE ROW LEVEL SECURITY applies instead |
| Replicas | One or more against one database (0.2+). Upgrade by stopping every replica first; the Helm chart's default Recreate strategy does this |
| Minimum size | 2 CPU, 2 GB memory, 10 GB disk for a few hundred assets |
Agent
Release binaries: linux/amd64, linux/arm64, windows/amd64, darwin/amd64 and darwin/arm64 (darwin for stackurity scan in CI and on laptops; the host collector reads Linux and Windows).
| Host | Inventory | Vulnerabilities assessed | Source |
|---|---|---|---|
| Debian | dpkg | Yes | OSV (Debian) |
| Ubuntu | dpkg | Yes, Ubuntu Pro fixes labelled; FIPS builds matched against the FIPS channels | OSV (Ubuntu) |
| Alpine | apk | Yes | OSV (Alpine) |
| Rocky Linux, AlmaLinux | rpm | Yes (Rocky by source package) | OSV |
| Red Hat Enterprise Linux | rpm | Yes, main stream of each major release (0.2+), each minor release from RHEL 10 | OSV (Red Hat) |
| SUSE Linux Enterprise | rpm | Yes, LTSS fixes labelled (0.2+), and fixes only published for SAP or HPC products | OSV (SUSE) |
| openSUSE Leap | rpm | Yes (0.2+) | OSV (openSUSE) |
| Amazon Linux 2023 and 2 | rpm | Yes (0.2+); Amazon Linux 2 extras topics with a version line | ALAS from Amazon's repositories |
| CentOS, Oracle Linux, Fedora, Amazon Linux 1 | rpm | No: evaluation gap | |
| Windows 10, 11, Server 2016, 2019, 2022, 2025 | Registry (installed programs, OS build) | Operating system vulnerabilities through cumulative updates: the build and update revision against Microsoft's fixed builds, one finding per missing CVE naming its update (KB); see Windows missing updates. Lifecycle for the operating system (see Windows end of life). Installed programs are not matched; installed KBs and Store apps are unsupported coverage; hotpatched hosts, .NET Framework, Office and servicing stack updates are not evaluated | Microsoft Security Update Guide (MSRC CVRF); endoflife.date windows-server, windows |
| Windows Server 2012 R2 and older, Windows 7, 8, 8.1 | Registry | No: lifecycle only; paid Extended Security Updates are not evaluated (unsupported coverage) | endoflife.date |
| Runtimes outside a package manager | Detected | No: lifecycle only | endoflife.date |
| Packages from a vendor's own repository (MongoDB, Docker, Elastic, Grafana, PGDG, NodeSource, Redis, nginx.org, MariaDB, MySQL, HashiCorp, Kubernetes and others, see below) | dpkg, rpm | No: evaluation gap; lifecycle with upstream dates | endoflife.date |
The same rules apply to container images scanned through the bundled Syft and to imported SBOMs: the purl's distro qualifier selects the source.
Clusters and cloud
| Source | Inventory | Assessed | Notes |
|---|---|---|---|
Kubernetes 1.25+ (kind, kubeadm, k3s, RKE2, EKS, GKE, AKS) through the kubernetes plugin |
Workloads, the images they run (by digest), exposure, control plane, kubelet, container runtime and node OS versions | Images: as container images above. Versions: lifecycle only (endoflife.date kubernetes, amazon-eks, google-kubernetes-engine, azure-kubernetes-service, containerd, node OS) |
Read-only RBAC in deploy/kubernetes. Kubeconfig with an embedded token or client certificate, a token, or the in-cluster service account; exec credential plugins are not supported. See kubernetes.md |
AWS managed services through the aws-managed plugin |
RDS, Aurora, ElastiCache, EKS, Lambda, OpenSearch engine and runtime versions | Lifecycle only |
Application dependencies
| Ecosystem | Lockfiles read | Vulnerabilities | Latest releases |
|---|---|---|---|
| npm, yarn, pnpm | Yes | OSV | npm (0.1+) |
| Composer | Yes | OSV | Packagist (0.1+) |
| PyPI (Poetry, Pipenv, pinned requirements) | Yes | OSV | PyPI (0.2+) |
| Go modules | Yes | OSV | proxy.golang.org (0.2+) |
| RubyGems (Bundler) | Yes | OSV | rubygems.org (0.2+) |
| NuGet | Yes | OSV | nuget.org (0.2+) |
| Dart and Flutter (pub) | Yes | OSV | pub.dev (0.2+) |
| Maven, Gradle | Java stack pack | OSV | Maven Central (0.2+) |
| Cargo | Rust stack pack | OSV | crates.io (0.2+) |
Swift Package Manager (Package.resolved v1-v3) |
Swift stack pack | OSV (SwiftURL: GitHub's Swift advisories, a few dozen packages, mostly SwiftNIO, Vapor and server libraries). Packages pinned to a branch or commit, and registry packages without their source URL: not checked | No: SwiftPM has no central registry |
CocoaPods (Podfile.lock) |
Swift stack pack | No: OSV publishes no CocoaPods advisories. Pods are inventoried and shown as unsupported | No |
Elixir and Erlang (mix.lock) |
Hex stack pack | OSV (Hex: GitHub and the Erlang Ecosystem Foundation, the best-covered of these three). Git dependencies and private organisations' packages: not checked | hex.pm |
Conan (conan.lock, Conan 1 and 2) |
C and C++ stack pack | No: OSV has no ConanCenter data. Inventory only | No |
vcpkg (vcpkg.json, installed ports' vcpkg.spdx.json) |
C and C++ stack pack (vcpkg.json exact only for ports pinned under overrides) |
No: no public advisory source covers vcpkg ports. Inventory only | No |
Remediation (Pro)
| Target | Manager | Rollback |
|---|---|---|
| Debian, Ubuntu | apt | Best effort |
| RHEL, CentOS and Oracle Linux 8 or later, Rocky, AlmaLinux, Fedora, Amazon Linux 2023 | dnf | Best effort |
| Amazon Linux 2, RHEL, CentOS and Oracle Linux 7 | yum | Best effort |
| SLES, SLES for SAP, SLED, openSUSE Leap | zypper | Best effort |
| Alpine | apk | Manual |
| openSUSE Tumbleweed, Amazon Linux 1, other rpm systems | Not supported: findings and fix plans only | |
| npm, Composer repositories | Renovate pull requests | Revert the pull request |
Kernels
A host keeps several kernels installed, and each kernel version is several
packages built from one source package (on Ubuntu: linux-image-<v>,
linux-modules-<v>, linux-modules-extra-<v>, linux-headers-<v>,
linux-headers-<v>-generic, linux-tools-<v>). Every kernel advisory
applies to all of them alike, so they are reported per kernel version:
| Package | Findings |
|---|---|
Kernel code of one version: Debian and Ubuntu linux-image-*, linux-modules-*, linux-tools-<version> and other packages named with the kernel ABI; RPM kernel, kernel-core, kernel-modules* and flavours (kernel-rt-*, kernel-debug-*, kernel-64k-*, kernel-uek*, SUSE kernel-default*) |
One finding per CVE per installed kernel version, on the package that boots (linux-image-*, kernel-core, kernel, kernel-default). The other packages of that version are listed in the finding's evidence (kernel_packages) and their inventory rows say "its findings are reported once, on ...". Matching is unchanged: findings from every package are merged, a free fix wins over a paid-channel one and the highest fixed version is kept |
No running code: linux-headers-* (and linux-<flavour>-headers-*), linux-libc-dev, linux-tools-common, linux-source*, linux-doc; RPM kernel-headers, kernel-devel, kernel-*-devel, kernel-macros, kernel-source, kernel-doc, kernel-syms |
None. They are checked (coverage evaluated) with the reason "kernel headers or build files, not running code" |
kernel-tools, kernel-tools-libs, kernel-firmware, linux-firmware, metapackages (linux-image-generic) |
Matched like any package: userspace code, firmware or a different source |
A kernel version that is installed but not the one running (from the agent's
kernel_running) keeps its single finding per CVE, marked
not_running_kernel: the risk engine scores it down to P4, it is never SOS,
and the action plan puts it under Remove old kernels
(sudo apt autoremove --purge, dnf remove --oldinstallonly, zypper purge-kernels). When the running kernel is unknown, every kernel version is
treated as running. On the first pilot's Ubuntu 20.04 host this turned the
same CVE from five findings per kernel version (headers, flavour headers,
modules, plus linux-libc-dev and linux-tools-common for the newest) into
one; the fixture in internal/intel/pilot_test.go goes from 510 findings and
100 P1 to 150 and 20. Alpine installs one kernel package at a time and is
matched as before.
Lifecycle of distribution packages
End-of-life dates from endoflife.date are the upstream project's: nginx 1.18 ended in 2021, PHP 8.1 on 2025-12-31, MySQL 8.0 on 2026-04-30. A distribution that ships one of those versions keeps patching its own package for as long as the distribution release is supported (Ubuntu 22.04 to 2027, RHEL 9 to 2032), so an upstream end-of-life finding on it would be a false positive. For a runtime or server matched to an endoflife.date product:
| Installed as | End-of-life finding |
|---|---|
| Outside the package manager (nvm's Node.js, a downloaded binary, a language package) | Upstream dates, as before |
A distribution package (deb, rpm or apk with a distro qualifier) on a supported distribution release |
None. The inventory row records "nginx 1.18 is end of life upstream since 2021-04-20; this is Ubuntu 22.04's own package, and Ubuntu 22.04 provides security updates until 2027-06-30", shown on the component and asset pages (lifecycle_note) |
| A distribution package on a release that is itself end of life (Ubuntu 20.04 after 2025-05-31) | None of its own: the operating system's end-of-life finding says its packages no longer get free fixes, and the action plan's release upgrade lists them. If the asset has no operating system row (some SBOMs), the package finding stays |
A distribution package whose release is not in the lifecycle data, or without a distro qualifier |
Upstream dates: the distribution's support cannot be confirmed |
A build from another repository: a package name only a vendor ships (mongodb-org-server, docker-ce, elasticsearch, grafana, ...) or a version that shows the repository: Ondřej Surý's PHP (deb.sury.org), nginx.org (1.24.0-1~jammy), Docker (~ubuntu.24.04~noble), Redis (-1rl1~noble1), MariaDB (+maria~), NodeSource, PGDG, Remi (.remi), nginx.org rpm (.ngx), MySQL's APT repository (-1ubuntu22.04) |
Upstream dates: the distribution does not maintain it. The inventory row's note names the repository |
.NET (dotnet-runtime-X.Y) from Red Hat, from Microsoft's repository (packages.microsoft.com, the only source on Debian) or from Ubuntu's .NET backports PPA (~ppa) |
Upstream dates: Red Hat's .NET life cycle is Microsoft's, and Microsoft's and the PPA's packages end with the release. Ubuntu's own archive packages (-0ubuntu1~22.04.1) follow the Ubuntu row above, since Canonical supports them for the Ubuntu release's lifetime |
The distribution's date is the endoflife.date end of its standard security
support (eol), the same date the operating system's own finding uses; paid
extensions (Ubuntu Pro, SUSE LTSS, RHEL ELS) do not count. Limits: the agent
does not record which repository a package came from, so a third-party build
whose name and version look like the distribution's own is treated as the
distribution's (Team RabbitMQ's rabbitmq-server 4.0.2-1, Microsoft's
dotnet-runtime-8.0 8.0.3-1, InfluxDB 1.x, Redis's rpm); Ubuntu's security support covers the main repository, and
universe packages get security fixes only through Ubuntu Pro, which the
package data does not distinguish; RHEL Application Streams modules can
retire before the release does. Vulnerability matching is unaffected:
fixes that only a paid channel publishes are still reported.
What Stackurity cannot check
Lifecycle mappings
End-of-life dates come from endoflife.date. A component gets them when its package URL maps to an endoflife.date product, in this order:
- An entry of Stackurity's lifecycle overlay marked
override(none today). - endoflife.date's own package identifiers.
- The same package name in another namespace of a family:
pkg:rpm/RHEL, its rebuilds and Syft's name for it (redhat,rhel,centos,rocky,almalinux,ol), andpkg:deb/debianandubuntu. endoflife.date listspkg:rpm/redhat/nginx, sopkg:rpm/rocky/nginxand agent-reported RHEL packages (pkg:rpm/rhel/...) matched nothing before. Amazon Linux and Fedora are not in a family: their package names differ.dotnet-sdk-*is left out, so .NET keeps one finding per release fromdotnet-runtime-X.Y. - The rest of the overlay
(
internal/intel/eoloverlay/lifecycle_overlay.json), a versioned data file embedded in the binary. Each entry names the index it was checked against. It adds:
| Product | Package URLs |
|---|---|
| Electron | pkg:npm/electron (endoflife.date tracks it with no identifier) |
| MongoDB | mongodb-org-server deb and rpm (MongoDB's repository; endoflife.date lists pkg:deb/*/mongodb) |
| Redis | redis-server deb (endoflife.date lists only the redis metapackage) |
| Docker Engine, containerd | docker-ce deb and rpm, docker.io, containerd.io, containerd |
| PostgreSQL | postgresql-<major> deb, PGDG's postgresql<major>-server rpm (the release line is read from the name) |
| Node.js | nodejs deb (NodeSource and the distributions) |
| Elasticsearch, Kibana, Logstash, OpenSearch, Grafana | Their own repositories' deb and rpm packages |
| InfluxDB, Telegraf | influxdb, influxdb2, influxdb3-core, influxdb3-enterprise, telegraf deb |
| MySQL, MariaDB | mysql-community-server deb and rpm, mariadb-server deb |
| Apache HTTP Server, Tomcat | apache2 deb; tomcat9, tomcat10, tomcat11 deb and org.apache.tomcat.embed:tomcat-embed-core (Spring Boot) |
| RabbitMQ, Kubernetes, GitLab, Jenkins, SQL Server | rabbitmq-server deb; kubelet deb and rpm; gitlab-ce and jenkins deb and rpm; mssql-server deb |
| Eclipse Temurin, Amazon Corretto, Go | temurin-<v>-jdk/-jre; java-<v>-amazon-corretto-jdk; golang-<v>-go (release line from the name) |
| HashiCorp Vault, Consul, Terraform, Nomad | Their deb packages from HashiCorp's repository; the distributions' own consul (Debian 10-11, Ubuntu 18.04-23.10) and nomad (Ubuntu 18.04-21.04), versioned +dfsg, stay distribution packages |
| OpenSSL, Exim, Postfix, Dovecot, Prometheus, Erlang, Podman | Distribution packages (openssl, exim4-base, postfix, dovecot-core, prometheus, erlang-base, podman); on a supported release they get the upstream note, not a finding |
| Symfony, CakePHP, Twig, Craft CMS, Shopware | symfony/http-kernel, cakephp/cakephp, twig/twig, craftcms/cms, shopware/core (Composer) |
| Kotlin, Quarkus, Apache Kafka, Apache Lucene, Liquibase | kotlin-stdlib, quarkus-core, kafka_2.13/kafka_2.12 (the broker), lucene-core, liquibase-core (Maven) |
A Debian or RPM epoch is ignored when the release line is read
(5:27.3.1-1~ubuntu.24.04~noble is Docker 27). An end-of-life finding mapped
by the overlay says so in its evidence (mapping: overlay or
namespace_family, with overlay_version).
Not covered: products endoflife.date does not track (NestJS, Flask, FastAPI,
CodeIgniter, Varnish; the overlay lists them so the coverage-gap report counts
them, and no dates are invented for them), release lines endoflife.date does
not list (Elasticsearch 8.15, for example), packages whose names were not
checked against a vendor's index (MongoDB Enterprise, gitlab-ee, PGDG and
RHEL postgresql-server, HashiCorp rpm packages), and Amazon Corretto 8
installed as java-1.8.0-amazon-corretto-jdk is read as line 8.
Packages from vendor repositories
Debian, Ubuntu and RHEL-family advisories describe the distribution's own
builds. A package from a vendor's repository either has no record there
(mongodb-org-server, docker-ce) or carries a different version from the
distribution's build, so matching it against them showed it as clean. Such a
package (recognised as in the lifecycle table above: a vendor-only name or a
version that shows the repository) is now coverage unsupported, with the
reason "built by , not by the distribution", and its end of life
uses upstream dates. This includes builds from Ondřej Surý's PHP, nginx.org,
NodeSource, PGDG, Remi and MySQL's repository, which were matched against the
distribution's advisories before.
Vulnerabilities of these packages are not matched: none of these servers has an upstream ecosystem in OSV that their versions can be compared in without guesswork (MongoDB, Redis, nginx, PostgreSQL and Node.js are not packages of an OSV ecosystem; Docker and Grafana are Go modules whose module versions do not follow the release numbers). Use the vendor's security advisories for them.
Coverage-gap report
Instance administrators see what Stackurity cannot check across every
workspace under Settings → Coverage gaps (GET /api/v1/admin/coverage-gaps):
files a scan found that no built-in reader or installed stack pack reads, by
kind (mix.lock, rebar.lock, Package.swift, Package.resolved,
Podfile.lock, conanfile.txt, conanfile.py, conan.lock, vcpkg.json,
uv.lock, pdm.lock, packages.config, deno.lock, bun.lock,
bun.lockb, build.sbt, and Maven, Gradle and Cargo files without their
stack pack); components with no vulnerability source, by package type and
reason (vendor builds per repository); and products with no lifecycle match.
Each is counted by assets and workspaces. The report names no workspace,
asset, path or package. The new file kinds are reported by agents and scans
from this release on; older agents report only the kinds they knew.
Windows missing updates
Windows does not install security fixes package by package: each month's cumulative update replaces the operating system files and raises the build's update revision (the registry's UBR, the last part of 10.0.20348.4294), and contains every earlier fix. Microsoft's Security Update Guide publishes, for each CVE and each Windows release, the update (KB) that fixes it and the build it brings. Stackurity compares the host's build and update revision with those builds: no agent change is needed, and the agent's existing os_version is enough.
Feed. msrc:Windows reads the Security Update Guide's CVRF API (api.msrc.microsoft.com/cvrf/v3.0, one document per month) and is created when a Windows host is in inventory. Every 6 hours it reads the index (about 50 KB), which says when each monthly document last changed, and downloads only the changed documents: a Patch Tuesday release (about 17:00 UTC on the second Tuesday) and later revisions are read within 6 hours. Every 30 days it reads every document in its window again. A document that cannot be read does not hold up the others: the sync stores what it read, re-evaluates, succeeds with a warning (shown as the feed's last error) and reads only that document again next time, keeping what it last read of it meanwhile; the sync fails only when no document of the window can be read. A document that lists no CVEs, or fewer than half of those stored for its month, is refused the same way, so a truncated download never withdraws a month of advisories. Each CVE of a document is stored as an advisory MSRC-<month>-<CVE> (aliased to the CVE, so KEV and EPSS apply as for any finding), with Microsoft's severity rating and CVSS vector.
Window: the last 24 months (STACKURITY_MSRC_MONTHS, 1 to 120). Cumulative updates make the window a question of how many old CVEs are named, never of whether a host is reported: a host older than the window is below every fixed build in it, so it gets a finding for every CVE in the window (about 3,800, 43 of them in KEV, as of October 2026) and the fix to the latest update, and its coverage and fix say its build predates the data. 24 months covers the whole life of Windows Server 2025 and Windows 11 24H2 so far and the whole 24-month servicing of a Windows 11 Home or Pro release, at about 140 MB for the first sync (the monthly documents have grown to 5 to 30 MB in 2026). Documents that leave the window are kept.
Update lines. Every edition, Server Core installation and processor architecture of a release take the same update and build, so a release is one line:
| Host | Line | Build |
|---|---|---|
| Windows Server 2016, 2019, 2022, 2025 | Server 2016, 2019, 2022, 2025 | 14393, 17763, 20348, 26100 |
| Windows Server, version 23H2 (annual channel) | Server 23H2 | 25398 |
| Windows 10 1507, 1607, 1809 (LTSB/LTSC) | 10 1507, 10 1607, 10 1809 | 10240, 14393, 17763 |
| Windows 10 21H2, 22H2 | 10 21H2, 10 22H2 | 19044, 19045 |
| Windows 11 22H2, 23H2, 24H2, 25H2, 26H1, 26H2 | 11 22H2 ... 11 26H2 | 22621, 22631, 26100, 26200, 28000, 26300 |
The build decides the line, as for end of life; the product name tells Server from client (Windows 11 calls itself "Windows 10" in ProductName), and the edition does not matter. Windows Server 2019 and the 1809 semi-annual channel release share build 17763; the year in the name tells them apart. The agent does not report the architecture, and does not need to: Microsoft lists the same fixed build for x64, ARM64 and 32-bit. Where Microsoft gives a sibling release's build (10.0.19044.x for Windows 10 22H2, 10.0.22631.x for Windows 11 22H2: releases that share one update through an enablement package), the update revision is what counts. A fixed build of any other line is ignored.
Findings. One finding per CVE whose fixed build is above the host's (compared as numbers: .887 is before .4294), keyed by the CVE, with the fixed build as the fixed version and in the evidence kb ("KB5066782"), kb_url, fixed_build, installed_build, update_line and update_released (the Patch Tuesday of the update's month). When Microsoft lists two fixes for one release in a month (the Patch Tuesday update and an out-of-band one that completed the fix, as for CVE-2025-59287), the higher build is the fix. A CVE in several monthly documents is grouped by CVE and the highest fixed build counts. A release Microsoft lists as affected without a fixed build is not reported. When a release has passed its end of life, a fix released after that date comes only with paid Extended Security Updates: the finding says so (requires_subscription), as for Ubuntu Pro, and the action plan puts it in the release upgrade.
Action plan. Cumulative updates contain every earlier fix, so a host's findings are one fix: install the newest update among them ("Install Windows update KB5126655", with the build and month), listing the updates the findings were first fixed in. Hosts that need the same update are one fix in the plan's "by fix" view.
Not evaluated, and shown as such (coverage unsupported with the reason, counted under Settings → Coverage gaps as "Windows hosts", never shown as fully patched):
- Hotpatching: Windows Server 2022 Datacenter: Azure Edition always; Windows Server 2025 and Windows 11 Enterprise hosts enrolled in hotpatching while their build is a hotpatch build Microsoft lists. Hotpatch builds are not numbered like cumulative updates.
- Windows Server 2012 R2 and older, Windows 7, 8 and 8.1: their updates are paid Extended Security Updates or have ended, and their builds are numbered 6.x. End of life is evaluated.
- .NET Framework, Office and servicing stack updates: they are not part of the cumulative update's build. Every evaluated Windows row says "cumulative updates only", and the agent's unsupported
windows:hotfixesscope (installed KBs are not read) is counted under unread files in the coverage-gap report.
Not evaluated (not_evaluated, with the reason): a version without an update revision, a release with no updates in the window (Windows 11 21H2, semi-annual channel Server), and any release whose line cannot be told (see below). The second check re-derives these findings with its own table of lines and its own dotted-number comparison.
Windows end of life
The Windows agent reports the operating system as pkg:generic/windows@10.0.<CurrentBuild>.<UBR> with the registry's ProductName, EditionID and DisplayVersion. The build number decides the endoflife.date release; the product name and edition tell Server from client and pick between releases that share a build. Server Core, Datacenter, Standard, Essentials, Evaluation and Azure Edition installs of a release share its dates.
| Build | Windows Server release (endoflife.date windows-server) |
|---|---|
| 6002, 6003 | 2008 SP2 (2008-sp2) |
| 7601 | 2008 R2 SP1 (2008-r2-sp1) |
| 9200 | 2012 |
| 9600 | 2012 R2 (2012-r2) |
| 14393 | 2016 |
| 16299, 17134 | 1709, 1803 (semi-annual channel) |
| 17763 | 2019 when the product name says 2019; 1809 (semi-annual channel, 1809-sac) when it has no year ("Windows Server Datacenter") |
| 18362, 18363, 19041, 19042 | 1903, 1909, 2004, 20H2 (semi-annual channel) |
| 20348 | 2022 |
| 25398 | 23H2 (annual channel, 23h2-ac) |
| 26100 | 2025 |
Windows client (endoflife.date windows) is mapped too: the build gives the version (19045 is Windows 10 22H2, 22631 Windows 11 23H2, 26100 Windows 11 24H2; Windows 7 SP1, 8 and 8.1 by build), and the edition the support policy: Home and Pro (including Pro Education and Pro for Workstations) take the -w release, Enterprise, Education and Enterprise multi-session the -e release, Enterprise LTSC/LTSB -e-lts and IoT Enterprise LTSC -iot-lts. Windows 11 reports "Windows 10" in its product name; the build decides. Agents older than this change do not send the edition; the product name is used instead.
A finding is raised when the release's endoflife.date eol date (end of Microsoft's extended support; for Windows Server 2016, 2027-01-12) has passed, titled "Windows Server 2016 is end-of-life since 2027-01-12", like Linux releases: there is no finding ahead of the date. Paid Extended Security Updates (endoflife.date eoes, Windows Server 2012 R2 to 2026-10-13) do not count, as Ubuntu Pro and RHEL ELS do not. The action plan's release upgrade for Windows Server names the newest supported LTSC release.
When the release cannot be told, the operating system row is a coverage gap (not_evaluated) with the reason, never supported: a build not in the tables (Insider and newer builds until Stackurity adds them), Windows Server 2003 (one build for RTM, SP1 and SP2) and 2008 R2 without SP1, build 17763 without a product name, a product name whose year disagrees with the build, a client DisplayVersion that disagrees with the build, an edition the tables do not know, and products endoflife.date does not track as Windows (Azure Stack HCI, Hyper-V Server). A release missing from the endoflife.date data is a gap too.
.NET end of life
endoflife.date dotnet releases are "8", "6", "3.1". Flagged when the release has ended:
- Linux distribution packages:
dotnet-runtime-X.Y(deb or rpm, any distribution) is .NET X.Y; one finding per installed release, since the SDK and ASP.NET Core runtime pull it in. Red Hat's packages, Microsoft's (packages.microsoft.com) and Ubuntu's .NET backports PPA get the upstream date; Ubuntu's own archive packages are maintained by Canonical while the Ubuntu release is supported (see Lifecycle of distribution packages). - NuGet:
pkg:nuget/Microsoft.NETCore.Appand the runtime packs (Microsoft.NETCore.App.Runtime.linux-x64and the like), in apackages.lock.json(self-contained apps list the runtime pack), an image scan or an imported SBOM.
Not flagged:
- .NET installed outside a package manager on Linux (the
dotnet-installscript, a tarball under/usr/share/dotnet,/opt/dotnetor~/.dotnet): the agent does not look for it. - .NET on Windows: the installed programs ("Microsoft .NET Runtime - 8.0.10 (x64)", "Microsoft ASP.NET Core 8.0.10 - Shared Framework") are inventoried by name and not matched to endoflife.date, nor is .NET Framework.
- An application's target framework (
<TargetFramework>net6.0</TargetFramework>in a project file): project files are not read, and a framework-dependent app'spackages.lock.jsondoes not list the runtime.
Paid support channels
Ubuntu Pro (Canonical) and SUSE LTSS are paid subscriptions for commercial
use. Their advisories are matched, and a finding whose only fixed build is in
one of them is labelled "no free fix" (requires_subscription). They are
never the recommended action: the action plan says "Fixed in Ubuntu Pro (paid
subscription); without it, upgrade to a supported release" on an end-of-life
release, and on a supported one, to install the update when the distribution
publishes a free fix. Groups carry needs so a team with a subscription can
use it, and findings that need one get no "fix available" bonus in the risk
score.
Coverage states
Having no findings only means something if the components were checked. The dashboard, the API and these docs use one vocabulary for that.
Each inventoried component (each row on an asset) is:
| Row coverage | Meaning |
|---|---|
Checked (evaluated) |
Matched against the vulnerability feed for its ecosystem and release |
Stale intelligence (stale_intelligence) |
Matched, but the feed is past its staleness window, disabled or its last sync failed: newer advisories are missing |
Not checked (not_evaluated) |
A source exists but could not be used: the feed has not synced, the release has no advisories in it, the version could not be read, or the distro release is unknown. The reason is shown |
Unsupported (unsupported) |
No vulnerability source exists for it: an unsupported ecosystem or distribution, a runtime installed outside a package manager, a Kubernetes or managed-service version (lifecycle only) |
Awaiting verification (awaiting) |
Inventoried, not evaluated yet |
Each asset is in one or more states; the most severe, in this order, is its headline:
| Asset state | When |
|---|---|
Failed collection (failed_collection) |
A collector reported a failed scope, or the asset stopped reporting (stale), so the inventory may be incomplete or out of date |
Stale intelligence (stale_intelligence) |
Components were checked against stale or failing intelligence |
Partially evaluated (partially_evaluated) |
Components could not be checked, the last collection was incomplete, or a scope was only partly read |
Unsupported (unsupported) |
Components or collector scopes have no vulnerability source |
Awaiting verification (awaiting_verification) |
Inventory has not been evaluated yet, or not within the last 48 hours |
Healthy and recently evaluated (healthy) |
None of the above: every scope was collected and every component checked against current intelligence within 48 hours |
The asset page shows the states with their reasons above the tabs, the
Findings tab says how many components the findings do not cover, and the
Inventory tab marks each component that was not checked ("not checked:
") and can be filtered by coverage. The Coverage page counts assets
by state; the Intelligence page lists every component not checked. The API
returns the same values (GET /assets/{id}/coverage-summary, coverage on
inventory rows).
How matching is tested
Each supported ecosystem has a corpus of real advisory records, frozen and
trimmed, with installed versions and the verdict each must get, in
internal/intel/testdata/corpus.
The test runs them through the whole pipeline (download, storage, release
selection, comparison, fixed version, subscription labels, coverage), not
only the version comparators. Every corpus also has cases the system cannot
evaluate, with the explicit response expected.
| Ecosystem | Corpus | What it covers | Cannot evaluate |
|---|---|---|---|
| npm | npm/ |
Pre-release ranges (canary, beta), last_affected, several ranges, listed versions, a withdrawn record, a record spanning several ecosystems |
A dist-tag (latest) instead of a version: not checked |
| Packagist | packagist/ |
Two advisories for one CVE, v prefixes, short bounds ("6"), RC versions, withdrawn records, Drupal's own repository |
A branch (dev-master): not checked |
| PyPI | pypi/ |
Branch ranges, pre-releases (1.8b1), last_affected, GHSA and PYSEC duplicates, PEP 503 names, withdrawn records |
A non-PEP 440 version: not checked |
| Go | go/ |
v prefixes, pseudo-versions, the standard library and its go1.x spelling, withdrawn records |
(devel): not checked |
| Maven | maven/ |
Qualifiers (2.0-beta9), three ranges per advisory, listed versions only, withdrawn records |
An unresolved ${property}: not checked |
| RubyGems | rubygems/ |
Pre-releases (3.0.0.beta1), several ranges, withdrawn "all versions" records |
A string Gem::Version rejects: not checked |
| crates.io | crates/ |
Several introduced/fixed pairs in one range, pre-releases, advisories without a CVE, withdrawn records | A requirement (1.x): not checked |
| NuGet | nuget/ |
Per-major ranges, last_affected without a fix, pre-releases, withdrawn records |
More than four version parts: not checked |
| Pub | pub/ |
+build versions, pre-release fixes, single-version advisories, withdrawn records |
A constraint (any): not checked |
| SwiftURL | swift/ |
Several ranges per record, an ECOSYSTEM range with a two-part fix, pre-releases, last_affected, repository names in any letter case, withdrawn records |
A branch name: not checked; a registry identity without a URL, CocoaPods: unsupported |
| Hex | hex/ |
Per-minor ranges, the same CVE from the EEF CNA and GitHub, last_affected without a fix, pre-releases, withdrawn records |
A requirement (1.x): not checked; a private organisation's package: unsupported |
| Debian | debian/ |
+debNuM backports, epochs (and a version reported without one), per-release fixes, binary to source mapping, withdrawn records |
A release without advisories, no distro qualifier, a malformed epoch: not checked; derivatives: unsupported |
| Ubuntu, including Pro | ubuntu/ |
ubuntu0.22.04.N updates, Pro-only (ESM) fixes and universe packages, FIPS builds and the FIPS-updates channel, kernel modules against the linux source while headers, linux-libc-dev and linux-tools-common get no findings |
A release without advisories: not checked |
| Alpine | alpine/ |
-rN revisions, per-release fixes, _alpha pre-releases |
A release without advisories, no distro qualifier: not checked; other apk distributions: unsupported |
| Rocky Linux | rocky/ |
Source-package matching, el9_4 z-stream fixes, epochs (agent and Syft forms, and a missing epoch), Rocky 8 and 9 |
A release without advisories: not checked |
| AlmaLinux | alma/ |
Binary-package records without CVE ids, minor releases on the major stream | A release without advisories: not checked |
| Red Hat | redhat/ |
el9_4 fixes, EUS records kept out of the main stream, RHEL 10 minor-release streams, Syft's namespace and epoch, kernel-core matched while kernel-devel (listed in the advisory) gets no findings |
A RHEL 10 stream without advisories: not checked; CentOS: unsupported |
| SUSE, including LTSS | suse/ |
Source-package matching, Basesystem fixes, LTSS-only fixes, SLES for SAP | A service pack without advisories, an unreadable VERSION_ID: not checked |
| openSUSE Leap | opensuse/ |
Leap entries of SUSE records, per-release fixes | A Leap release without advisories: not checked; Tumbleweed: unsupported |
| Amazon Linux 2 and 2023 | amazon/ |
Real updateinfo read through the repository mirrors, epochs, AL2 extras (kernel-5.10) limited to their version line |
Amazon Linux 1: unsupported |
Known limits the corpus documents: RHEL hosts on an EUS minor release are matched against the main stream; from a FIPS build's version alone the matcher cannot tell the certified FIPS channel from FIPS-updates and follows FIPS-updates; a Debian or rpm version reported without its epoch sorts below every fix with one.