- announcements
- open source
- self-hosting
StackRadar is open source: a self-hosted Kubernetes vulnerability dashboard under AGPL-3.0
The server, the dashboard and the Helm chart are on GitHub under AGPL-3.0, the scanner and CLI under Apache-2.0. One Helm command installs the lot in your cluster, with no telemetry and nothing leaving it. What is open, why these licences, and where the cloud fits.
StackRadar Team
8 min read
As of this week the whole of StackRadar is on GitHub. The server that mirrors the advisory feeds and ranks every finding, the dashboard, the Helm chart that installs both with a bundled Postgres, and the scanner that was already public: one helm install puts the lot in your cluster, under a licence you can read in full, with nothing leaving the cluster but the advisory downloads. The repository is lockdep/stackradar.
This post says what is open and under which licence, why we chose those licences, how the community edition and the cloud relate, and what a self-hosted install does and does not do. It is the long version of the README; if you only want the command, it is in the next section.
A self-hosted Kubernetes vulnerability dashboard in one command
helm install stackradar \
oci://ghcr.io/lockdep/helm-charts/stackradar \
--namespace stackradar --create-namespace
kubectl -n stackradar port-forward svc/stackradar-client 3000:3000Open http://localhost:3000 and sign in as admin@stackradar.local with the password admin. The scanner is part of the chart, so the cluster it landed in is already being inventoried; findings appear once the vulnerability mirror has bootstrapped. Kubernetes 1.25 and Helm 3.8 or newer are the only requirements. On a laptop cluster, the chart's quickstart values trim the resources and bootstrap an Alpine-only mirror in about two minutes.
Without a cluster, the same server and dashboard run under Docker Compose:
curl -LO https://raw.githubusercontent.com/lockdep/stackradar/main/deploy/compose/docker-compose.yml
docker compose up -dCompose cannot run the scanner, so the walkthrough uploads a CycloneDX SBOM with two curl lines to see findings. It is the way to look at the product in ten minutes before deciding whether to give it a cluster.
What the community edition does
The pitch has not changed with the licence. A scanner tells you your cluster has four thousand CVEs. StackRadar tells you which of them are on images that are running right now, which of those are being exploited in the wild, and which chart version or image tag makes them go away. In a self-hosted install that means:
- Scans what runs, once. A read-only agent watches the pods of the cluster it runs in, pulls each image once per digest and writes its SBOM with Syft. No scan Job per workload, and no report objects in etcd.
- Re-matches instead of re-scanning. The server mirrors OSV.dev, EPSS and the CISA KEV catalogue locally and matches every stored SBOM again whenever the mirror changes, so a new CVE does not need a new scan.
- Ranks by exploitability. The Radar Score folds CVSS, EPSS and KEV into one number per finding and sums them per image, container, release and cluster. The top of every list is what to fix first.
- Separates your layer from the base image, so a finding in your own dependencies is not buried under Debian's.
- Knows how the image got there. The Helm release that packaged a workload and the Argo CD application that delivers it are on the page, so the fix is a chart version and a
helm,argocdorkubectlcommand. - Shows what changed. A feed of advisories that landed on running images, containers that moved between digests, and the finding delta between them. New critical and KEV findings can go to a Slack webhook.
- Sign-in your way. Local username and password, any OpenID Connect provider, GitHub or Google. One Postgres, migrations on boot, no telemetry.
The trust boundaries, the data model and the decisions behind them are written up in the repository's architecture document and its ADRs, and more briefly on the docs site.
What is open, and under which licence
Four repositories, three licences, and the split follows one rule: the stricter licence goes on the thing that runs in our infrastructure and the permissive one on the things that run in yours.
lockdep/stackradar: the server, the web client and the self-hosting manual. AGPL-3.0-only.lockdep/helm-charts: thestackradarchart, which installs both apps, a bundled Postgres and the scanner. Apache-2.0.lockdep/stackradar-scanner: the in-cluster agent, the only SBOM ingestion path. Apache-2.0.lockdep/stackradar-cli:stackradar scan, the same answer from a laptop. Apache-2.0, as it has been since launch.
One exception, stated in the root licence and in NOTICE: two directories, server/src/cloud/ and client/src/cloud/, hold the code that only the cloud runs. Billing, email alerting, enterprise single sign-on, the feedback inbox, the live demo. They are source-available under the StackRadar Cloud Licence, which follows PolyForm Shield in substance: read it, modify it, run it for your own organisation, but do not use it to offer a competing hosted service. The licence covers the code, not the name; you may ship a modified version as "based on StackRadar", not as StackRadar.
Why AGPL
The question will be asked, so here is the answer written down. For the people who actually run StackRadar, the AGPL is free of obligations: you install it in your cluster, you do not redistribute it, nothing is triggered. If you patch it and keep running it internally, still nothing. The licence bites in exactly one case, which is a company taking the server, running it as a hosted service for others and keeping its changes to itself. That is the business the cloud edition is, and it is how a one-person project pays for mirroring 900,000 advisories and answering issues. Grafana, Plausible, Cal.com and PostHog made the same call for the same reason.
The scanner and the CLI are the other way round on purpose. They run inside other people's clusters and CI pipelines, often bundled into something else, and there the copyleft question is real rather than theoretical. A thin agent around Syft has no moat worth defending, and an agent that reads every image in your cluster should carry the licence that asks the fewest questions.
One more sentence that matters more than the licence name: the community edition cannot be relicensed out from under you. Contributions come in under the Developer Certificate of Origin, not a contributor licence agreement, so no single party holds the rights to change the core's licence. The AGPL core can only ever be relicensed with every contributor's consent, which is the point.
Community Edition and StackRadar Cloud are the same images
There is no fork, no single-tenant repository and no private overlay. The cloud at app.stackradar.io runs the images built from the public repository, with one environment variable set.
STACKRADAR_EDITION is read once at boot into a frozen capabilities object, and every product gate reads that object: whether "Add cluster" exists, whether alerting is one webhook or email with routing, whether SAML is offered. Unset means community, so the public image is safe by default; the cloud opts in; any other value refuses to start rather than silently becoming the wrong edition. None of the gates is inferred from which secrets happen to be present, which is how "the community edition" stays a product decision instead of a misconfiguration.
What the cloud sells is hosting (you run only the scanner, not Postgres or a 1.3 GB advisory mirror), many clusters in one dashboard, enterprise SSO, full alerting and a person to email. What the community edition is: the dashboard for the one cluster it runs in, with everything else in the list above. The README's comparison table keeps the row-by-row version current, and the pricing page has the numbers. If you outgrow one cluster, the move is the same images with more clusters; nothing you learned is wasted.
Nothing leaves your cluster
This was the objection on every sales call before the licence changed, and it is now a property you can check. A self-hosted install has no telemetry and no phone-home. The only outbound connections are the server fetching advisories: OSV.dev every hour, EPSS and the CISA KEV catalogue every day. Your SBOMs, your findings, your history and your users sit in one PostgreSQL inside the cluster. The agent is read-only, with list and watch on pods and metadata-only get on their controllers, and what it reports to the server is an allowlist documented in the scanner README.
Trust in the binaries is checkable too. Every release's images are multi-arch, signed with cosign keyless from the repository's GitHub Actions identity, and carry SLSA provenance and SBOM attestations; the chart pins them by digest. The release process has the cosign verify commands, and it is modelled on Dependency-Track's, down to the version dropdown in the defect template.
How the licence boundary is kept honest
Two licences in one repository only work while the line between them is visible and mechanical, so it is enforced in CI rather than by convention. Every file under a cloud directory carries an SPDX header naming the cloud licence; every cloud directory carries its own LICENSE; and nothing outside the cloud may import from inside it, except a short list of named mount points, one per process, where the AGPL core reaches the cloud by name behind an edition check.
# fails when a cloud file lacks its SPDX header, a core file carries one,
# or anything outside the mount points imports from src/cloud/
node scripts/check-cloud-boundary.mjsThe check needs no dependencies and runs on a bare checkout, so you can run it yourself before trusting the claim. The other direction, cloud code importing the core, is allowed, because the cloud is built on the core and not the reverse. The practical result is that a self-hosted process never loads a single cloud file, and a pull request that blurs the line fails before anyone reviews it.
What it does not do
A launch post that only lists strengths is an advert, so the limits, stated the way we would want another project to state them:
- It is not a configuration scanner. No RBAC assessment, no CIS benchmarks, no admission control. Trivy Operator and Kubescape do those, and StackRadar runs next to them without conflict.
- The community edition is one cluster. Several clusters in one dashboard is the cloud's feature and the way the project is paid for. One install per cluster works; a fleet view does not.
- It only knows what OSV knows. Debian, Ubuntu, Alpine, Red Hat, SUSE and the mainstream language ecosystems are well covered. OSV has no feed for Amazon Linux, Oracle Linux, Fedora or Photon OS, so base images on those get no OS-package findings. We have written about what that looks like.
- It is not a CI scanner. The artefact you are about to ship is best scanned by Trivy, Grype or
stackradar scan --imagebefore it is deployed. StackRadar answers the question that comes after: what is running, and did a new advisory just land on it. - The bundled Postgres is single-node. It is a kept volume, a NetworkPolicy and a note that you own backups and major upgrades. For anything you would miss, point the chart at a database you run.
Where to go
Install it, in a staging cluster on a Tuesday afternoon, and tell us what it gets wrong. Questions go to GitHub Discussions, defects and enhancement requests to Issues through the templates, and security reports to private reporting or security@stackradar.io. Issues labelled good first issue are the ones to start with if you want to contribute, and DEVELOPING.md gets both apps running locally with Docker and Node 22.
StackRadar ships no telemetry, so ADOPTERS.md is the only way we learn who runs it. It currently reads "Nobody yet. Be the first." We would like to change that line.
Frequently asked questions
Is StackRadar open source?
Yes. The server and the dashboard are AGPL-3.0-only; the Helm chart, the in-cluster scanner and the CLI are Apache-2.0. The code that only the cloud runs (billing, email alerting, enterprise SSO, the live demo) sits in two directories of the same repository under a source-available licence that permits everything except offering it as a hosted service. All of it is on GitHub, and a self-hosted install never loads the cloud directories.
Why AGPL-3.0 and not Apache or MIT?
For a tool that runs inside your own cluster the AGPL costs you nothing: you are not redistributing it, so no obligation is triggered. What the licence does is stop a hosting company from taking the code, running it as a service and giving nothing back. That is the business the cloud edition is, so it is the one case we needed a licence to cover. The scanner and the CLI run inside other people’s clusters and pipelines, where a copyleft licence would be a real question, so they are Apache-2.0.
Can the community edition be relicensed later?
Not without every contributor’s consent. Contributions are accepted under the Developer Certificate of Origin, not a contributor licence agreement, so there is no party that holds the rights to change the licence of the AGPL core on its own. The cloud directories do not accept external contributions, which is why they need no CLA either.
What is the difference between the community edition and StackRadar Cloud?
They are the same images. With STACKRADAR_EDITION unset the images boot as the community edition: one cluster, one organisation, local or OIDC sign-in, one Slack webhook for alerts, no billing, no telemetry. Set to cloud, the same images become app.stackradar.io: many clusters in one dashboard, enterprise SSO, email alerting with routing and digests, billing and support. Every gate reads one capabilities object, never a missing secret.
Does a self-hosted StackRadar send anything to StackRadar?
No. There is no telemetry and no phone-home. The only outbound traffic from a self-hosted install is the server downloading advisories from OSV.dev, EPSS and the CISA KEV catalogue. Your SBOMs, findings and history stay in a Postgres inside your cluster.
What do I need to run it?
Kubernetes 1.25 or newer and Helm 3.8 or newer. The chart bundles a single-node Postgres and the scanner, so a bare helm install with no values file works; the walkthrough in the repository says which fixture credentials to replace before you keep it. Without a cluster, the Docker Compose file runs the server and dashboard on a laptop and you upload an SBOM by hand.
More from the blog
All postsIntroducing the StackRadar CLI: scan what your cluster is actually running
stackradar scan is a free, Apache-2.0 CLI that finds known and exploited CVEs in every image your Kubernetes cluster is running. No agent, no account, no telemetry.
5 min read
Most of your container vulnerabilities are not yours to fix
A container scan mixes three kinds of finding: your dependencies, the base image, and images someone else builds. How to separate them without hiding an exploited CVE.
7 min read
Open-source vulnerability scanners for Kubernetes: what each one does and does not do
Trivy Operator, Kubescape, Grype and Syft, OSV-Scanner, the StackRadar CLI, and what became of KubeClarity: what each does, and what you still build yourself.
8 min read
A new CVE should not need a new scan: how we keep 900,000 advisories current
Most scanners match an image once, when it is scanned. We mirror OSV.dev every hour, EPSS and KEV every day, and re-match every stored SBOM when the mirror changes. How, and what it does not solve.
10 min read