Documentation menu

Restricted networks & mirroring

Run the StackRadar scanner behind restricted egress: chart and image mirroring, proxies and custom CAs, the one endpoint to allow, and what leaves the network.

Last updated

Many clusters can't pull from public registries or have tightly filtered egress. This guide covers the patterns that make the StackRadar scanner work there: mirroring the chart and image into your own registry, routing through an egress proxy, and allowlisting the one endpoint the scanner needs. Credentials for scanning images in private registries are covered in Private registry authentication.

StackRadar Cloud is a hosted service, so a fully air-gapped cluster (zero outbound connectivity, ever) can't report scan results to it. The scanner needs one outbound path: HTTPS to api.stackradar.io. Everything else — the chart, the image, all image pulls — can come from inside your network. If no outbound path from the cluster is acceptable, the self-hosted Community Edition keeps the server inside your network too; its server still needs a route to OSV.dev, FIRST (EPSS) and CISA (KEV) to build and refresh the vulnerability mirror.

What the scanner needs, exactly

RequirementCan be internal?
Helm chart (stackradar-scanner)Yes — mirror to any OCI registry or internal chart repo
Scanner container imageYes — mirror to your private registry
Read access to the registries your workloads run fromYes — the scanner pulls images over your own network, never through StackRadar
SBOM uploads & heartbeats — HTTPS to api.stackradar.ioNo — allowlist directly or route via egress proxy

Notably, the scanner does not need to download a vulnerability database into your cluster. Vulnerability matching happens server-side against StackRadar's continuously synced OSV.dev mirror, so there is no nightly feed download to allowlist and no stale in-cluster database to maintain. See how vulnerability matching works.

Authenticating to a private registry

The scanner pulls every image it scans itself, so for workloads running from a private registry it needs credentials of its own — either the imagePullSecrets your pods already declare, or a Docker config Secret mounted via dockerConfigSecret. That has its own guide, with the exact credential for Amazon ECR, Google Artifact Registry, Azure ACR, Docker Hub and GHCR: Private registry authentication.

One thing belongs here rather than there: the chart's imagePullSecrets value is how the kubelet pulls the scanner's own image once you have mirrored it, below. It has nothing to do with what the scanner can scan.

Mirroring the chart and image

Check the current chart version and default values on Artifact Hub, then pull the chart from the public OCI registry on a connected machine:

bash
helm pull oci://ghcr.io/lockdep/charts/stackradar-scanner --version <version>

Pin --version — for a mirror, reproducibility is the point: the .tgz you push is then exactly the bytes you reviewed, not whatever the registry considered latest that day. Push it to your internal registry (any OCI-compliant registry works — Harbor, ECR, Artifact Registry, ACR, Nexus):

bash
helm push stackradar-scanner-<version>.tgz oci://registry.internal.example.com/charts

Mirror the scanner image the same way you mirror other public images (e.g. with crane copy, skopeo copy, or your registry's proxy-cache feature). One constraint: released charts pin the scanner image by digest (image.digest), so your mirror must hold a byte-identical copy — crane copy and skopeo copy preserve digests, as does a proxy-cache. If you rebuild or re-sign the image, its digest changes, and you must clear image.digest (and set image.tag) — the digest wins over the tag, so without clearing it the pull asks your registry for bytes it doesn't hold and fails. List the chart's default image references and configurable values with:

bash
helm show values oci://ghcr.io/lockdep/charts/stackradar-scanner

Then install from your internal registry, overriding the image repository values shown by helm show values to point at your mirror:

bash
helm install stackradar-scanner \
    oci://registry.internal.example.com/charts/stackradar-scanner \
    --namespace stackradar --create-namespace \
    --set stackradar.apiKey=$STACKRADAR_API_KEY \
    --set stackradar.clusterId=$STACKRADAR_CLUSTER_ID \
    --values internal-registry-overrides.yaml

In these environments credentials rarely belong on the command line at all. If a sealed-secrets, external-secrets, or SOPS pipeline delivers your Secrets, give it a Secret with cluster-id and api-key keys and point the chart at it with stackradar.existingSecret instead of the two --set flags above — the chart then creates no credentials Secret of its own.

Restricted egress

  • Firewall allowlist — allow outbound HTTPS (TCP 443) to api.stackradar.io. No other StackRadar endpoint is contacted by the scanner.
  • Egress proxy — set proxy.httpsProxy (and proxy.noProxy for your internal registries) and the chart puts HTTPS_PROXY / NO_PROXY on the pod and routes the agent's own API calls through the proxy too. Include the scheme — proxy.corp:8080 is rejected at install time. The in-cluster Kubernetes API is always exempted, so you only list your own hosts. If the proxy terminates TLS, add your CA with caBundle.configMapName — or caBundle.secretName when your secrets pipeline delivers the bundle as a Secret.
  • NetworkPolicy — the chart ships its own, on by default (networkPolicy.enabled): a policy allowing egress to DNS, the Kubernetes API server, and TCP 443 (the StackRadar API and your registries), and nothing else — networkPolicy.egress replaces those defaults when you want to narrow the 443 rule to known CIDRs, or add a registry on another port. The flip side under default-deny ingress: the kubelet must still reach the scanner's health port, or its probes fail and the pod restarts in a loop — the chart's policy already allows that ingress, so prefer it over hand-writing one.

What actually leaves the network

Uploads are CycloneDX SBOM documents: package names, versions, and identifiers (PURLs) for each container image, plus cluster/workload metadata so results are attributable. No source code, no environment variables, no secrets, and no image contents are transmitted — and all data is stored in the EU. Details in architecture & data flow.

Next steps