Architecture & data flow
How the StackRadar scanner works: what runs in your cluster, exactly what data leaves it, how SBOMs are matched to vulnerabilities, and where data is stored.
The two halves
StackRadar is split deliberately into a source-available scanner agent that runs in your cluster and a managed backend that stores SBOMs and does vulnerability matching. You can audit everything that runs inside your infrastructure on GitHub; the heavy state — a 900K+ record vulnerability database and your scan history — lives outside your cluster so there's nothing to operate or keep fresh in it.
What runs in your cluster
A single Helm release in the stackradar namespace. The agent watches the Kubernetes API for pods starting anywhere in the cluster. When a pod starts with a container image the agent hasn't already scanned, it:
- Asks the API whether this cluster already has an SBOM for that image (a digest lookup via
GET /v1/sboms/check?imageDigest=…) before pulling anything — one image running in five namespaces is still one pull and one scan. - Pulls the image from your registry and generates a CycloneDX 1.6 SBOM — a structured inventory of every package inside it (see the CycloneDX format reference).
- Uploads it via
POST /v1/sboms/upload/cyclonedx, authenticated with the cluster-scoped API key.
Separately from SBOMs, the agent reports the cluster's workload inventory (POST /v1/inventory): the namespaces, workloads, and containers it can see, the Helm release that packaged each workload, and the ArgoCD application that delivers it. Each report replaces the previous one for the cluster. This is what lets the dashboard show every discovered container — per cluster, and org-wide on the Containers page — with its scanned-vs-unscanned coverage, before and after the SBOMs land, and what ties a finding to the chart version and GitOps app you'd actually change to fix it.
The agent also sends a periodic heartbeat (POST /v1/heartbeat) carrying its version in an X-Scanner-Version header and the cluster's Kubernetes version in X-Kubernetes-Version, which is what powers the cluster health, scanner version, and Kubernetes version display in the dashboard.
Because scanning is triggered by pod starts rather than a schedule, coverage tracks your deploys: a new image is scanned the moment it starts running, and there is no window where a scheduled scan hasn't caught up yet. A periodic sweep (every 6 hours by default) re-lists the cluster so nothing is missed between events.
Exactly what data leaves the cluster
| Sent | Not sent |
|---|---|
CycloneDX SBOMs — syft's raw output, uploaded unmodified: package names, versions, PURLs, licenses, hashes, component properties (which include in-image file paths and the image's own LABELs as syft:image:labels:*), the distro syft identified, and syft's own tool metadata | Source code or image layer contents |
| Workload inventory: namespace and workload names, image references, an allowlisted set of well-known workload labels and the Helm/ArgoCD attribution annotations, running-pod counts and first-started timestamps, Helm release names and chart versions, ArgoCD application names and their repository URL (credentials redacted), chart, path and target revision | Environment variables, ConfigMaps, Secrets, registry credentials |
| Heartbeats: scanner version, cluster ID, cluster Kubernetes version | Application traffic, logs, or arbitrary labels and annotations |
Namespace labels are never sent: the agent isn't granted the RBAC to read them, and the inventory reports them as null rather than guessing — a missing permission is never made to look like an unlabelled namespace.
All data leaving the cluster goes over HTTPS to a single endpoint, api.stackradar.io; the agent's only other egress is the pulls it makes from your own registries, and syft's update check-in is disabled. All data is stored in the EU — relevant if you're working toward CRA or NIS2 compliance and need to answer "where does our dependency inventory live?". For the broader data-handling picture, see the security page.
What happens server-side
On upload, the SBOM is validated against the CycloneDX 1.6 schema, parsed, and its components stored. Each component is then matched against StackRadar's local mirror of the OSV.dev vulnerability database — matching is by Package URL and affected version ranges, described in detail in how vulnerability matching works.
The OSV mirror is kept fresh by an hourly incremental sync that polls OSV.dev's change feed, so a newly published advisory is matched against SBOMs you already uploaded — you don't need to redeploy or rescan anything to learn that yesterday's image is affected by today's CVE.
Each finding is also scored for priority, not just severity: its contribution to the Radar Score weights CVSS by the advisory's EPSS exploitation probability (synced daily from FIRST.org), and a listing in the CISA Known Exploited Vulnerabilities catalogue replaces that likelihood term with certainty (1.0) — observed exploitation is a score input, not just a badge. The full formula is published in how the Radar Score works.
Authentication model
The agent authenticates with a cluster-scoped API key sent in the X-API-Key header. A key identifies exactly one cluster in one organization, which is what lets the dashboard attribute every SBOM to the cluster it came from — and lets you revoke one cluster's access without touching the others. Everything derived from an upload stays scoped to that cluster; nothing one cluster reports is ever shared with another. Full details in API keys & cluster scoping.
Verifying this yourself
Everything above is observable. Watch what the agent does:
# See the scanner's workload and its (lack of) privileges
kubectl get pods --namespace stackradar
kubectl describe pod --namespace stackradar -l app.kubernetes.io/name=stackradar-scanner
# Read the source of what's running
# https://github.com/lockdep/stackradar-scannerNext steps
- Vulnerability matchingHow StackRadar matches SBOM components against 900K+ OSV.dev advisories: PURL matching, version-range evaluation from npm to Debian and RPM, and confidence.
- API keys & cluster scopingHow StackRadar API keys work: one cluster-scoped key per cluster, why every scanner request requires one, and how to get and rotate keys safely.