Scanning Registries
This guide explains how to configure and run scans on container registries using SUSE Security Vulnerability Scanner.
It covers:
-
Defining a
Registrycustom resource -
Running on-demand scans with a
ScanJob -
Targeting a subset of a Registry from a
ScanJob -
Configuring scheduled scans
-
Configuring registry without catalog
-
Filtering by tags
-
Filtering by platforms
-
Monitoring scan progress and results
-
Stopping scans and cleaning up resources
-
Remove a Registry
1. Define a Registry
Before scanning a registry, create a Registry custom resource that specifies the registry endpoint and repositories to scan.
Example manifest:
apiVersion: sbomscanner.kubewarden.io/v1alpha1
kind: Registry
metadata:
name: my-registry
namespace: default
spec:
uri: ghcr.io
scanInterval: 1h
repositories:
- name: kubewarden/sbomscanner/test-assets/golang
This configuration:
-
Targets the
ghcr.ioregistry -
Scans the
kubewarden/sbomscanner/test-assets/golangrepository -
Runs a new scan every hour
Apply the resource:
kubectl apply -f registry.yaml
For private registries, see the Private Registries guide.
2. Run a Scan on Demand
To run a one-time scan, omit the scanInterval in the Registry resource and create a ScanJob that references it.
Example Registry without scheduling:
apiVersion: sbomscanner.kubewarden.io/v1alpha1
kind: Registry
metadata:
name: my-registry
namespace: default
spec:
uri: ghcr.io
repositories:
- name: kubewarden/sbomscanner/test-assets/golang
Example ScanJob manifest:
apiVersion: sbomscanner.kubewarden.io/v1alpha1
kind: ScanJob
metadata:
name: my-scanjob
namespace: default
spec:
registry: my-registry
Apply the job:
kubectl apply -f scanjob.yaml
|
The |
3. Target a Subset of a Registry
By default a ScanJob scans every repository (and every matchCondition) declared on the referenced Registry. You can narrow the scan to a subset by setting spec.repositories on the ScanJob.
Each entry references a repository by name and may optionally restrict the scan to a subset of the repository’s matchConditions.
Example: scan only one repository, all of its matchConditions:
apiVersion: sbomscanner.kubewarden.io/v1alpha1
kind: ScanJob
metadata:
name: my-scanjob
namespace: default
spec:
registry: my-registry
repositories:
- name: kubewarden/sbomscanner/test-assets/golang
Example: scan a single repository, restricted to two of its matchConditions:
apiVersion: sbomscanner.kubewarden.io/v1alpha1
kind: ScanJob
metadata:
name: my-scanjob
namespace: default
spec:
registry: my-registry
repositories:
- name: kubewarden/sbomscanner/test-assets/golang
matchConditions:
- production tags
- latest tag
Each entry under spec.repositories must reference a repository declared on the Registry, and each name listed under matchConditions must reference an existing matchCondition on that repository. The ScanJob controller validates these references when reconciling the job and marks it as failed if any of them does not exist.
|
When |
4. Configuring registry without catalog
In some cases, you may work with registries that do not implement/exposes the _catalog endpoint (such as Docker Hub, Amazon ECR, or ghcr.io).
To make SUSE Security Vulnerability Scanner work with these registries, you can manually specify the repositories you want to scan, instead of pulling the catalog.
|
When using |
Example Registry without catalog:
apiVersion: sbomscanner.kubewarden.io/v1alpha1
kind: Registry
metadata:
name: my-registry
namespace: default
spec:
uri: ghcr.io
catalogType: NoCatalog
repositories:
- name: kubewarden/sbomscanner/test-assets/golang
Here’s a list of registries that do NOT support _catalog (or intentionally disable it):
-
Amazon ECR
-
Google Container Registry (GCR)
-
GitHub Container Registry (GHCR)
5. Filtering By Platforms
In most cases you don’t want to scan all the platforms of the same image version. For this reason we created a filter mechanism to avoid unuseful scans and waste of time.
To lighten the workload of SUSE Security Vulnerability Scanner, you can specify which platforms you want to scan, instead of discovering them and consequently scan.
Here’s an example of how to configure the registry to look only at the linux/amd64 platform.
apiVersion: sbomscanner.kubewarden.io/v1alpha1
kind: Registry
metadata:
name: my-first-registry
namespace: default
spec:
uri: dev-registry.default.svc.cluster.local:5000
platforms:
- arch: "amd64"
os: "linux"
To configure multiple platforms, you can list them this way:
...
spec:
uri: dev-registry.default.svc.cluster.local:5000
platforms:
- arch: "amd64"
os: "linux"
- arch: "386"
os: "linux"
- arch: "arm64"
os: "linux"
variant: "v7"
6. Filtering By Tags
You can filter image tags using CEL expressions in the matchConditions field under repositories. This lets you use regex patterns, semantic versioning comparisons, or string operations (like substring matching or contains checks) to select which tags to scan. This filtering capability helps reduce the number of scanned images and lowers the load on the system.
Let’s see an example:
apiVersion: sbomscanner.kubewarden.io/v1alpha1
kind: Registry
metadata:
name: my-first-registry
namespace: default
spec:
uri: dev-registry.default.svc.cluster.local:5000
repositories:
- name: kubewarden/sbomscanner/test-assets/test-image
matchConditions:
- name: "production tags"
expression: "tag.endsWith('-prod')"
This example shows how to filter for images with a tag ending with -prod, helpful to scan only for images being deployed in a production environment.
Another helpful example is to avoid scanning for release candidate images, which are typically tagged as <version>-rc<rc_version_number>, by using the following expression: !tag.matches('-rc*').
It’s important to mention that multiple expressions can be defined under the matchConditions field. This will help the user to define complex filters, splitting them into shorter expressions:
apiVersion: sbomscanner.kubewarden.io/v1alpha1
kind: Registry
metadata:
name: my-first-registry
namespace: default
spec:
uri: dev-registry.default.svc.cluster.local:5000
repositories:
- name: kubewarden/sbomscanner/test-assets/test-image
matchConditions:
- name: "semver is less than v1.0.0"
expression: "semver(tag, true).isLessThan(semver('v1.0.0', true))"
- name: "semver is greater than v1.1.0"
expression: "semver(tag, true).isGreaterThan(semver('v1.1.0', true))"
This way the user can scan only for a defined range of image versions (from v1.0.0 to v1.1.0).
By default, all conditions must pass for a tag to be included (AND logic).
Using OR Logic
If you want a tag to match when at least one condition passes, set the matchOperator field to Or:
apiVersion: sbomscanner.kubewarden.io/v1alpha1
kind: Registry
metadata:
name: my-first-registry
namespace: default
spec:
uri: dev-registry.default.svc.cluster.local:5000
repositories:
- name: kubewarden/sbomscanner/test-assets/test-image
matchOperator: Or
matchConditions:
- name: "latest tag"
expression: "tag == 'latest'"
- name: "production tags"
expression: "tag.endsWith('-prod')"
- name: "stable tags"
expression: "tag.endsWith('-stable')"
This configuration scans tags that are either latest, end with -prod, or end with -stable.
Common Expression Language
The Common Expression Language (CEL) is used in the Kubernetes API to declare validation rules, policy rules, and other constraints or conditions.
It is widely used in Kubernetes, making CEL a convenient alternative to out-of-process mechanisms, such as webhooks, for many extensibility use cases.
For further information about the CEL specification, please take a look to this repository: https://github.com/google/cel-spec
Here’s the most common CEL expressions that can be used for tag filtering:
String and Regex
| function | example | description |
|---|---|---|
|
|
Tags that starts with |
|
|
Tags that ends with |
|
|
Tags that matches the regex |
7. Monitor Scan Progress
Check the status of a scan:
kubectl get scanjob my-scanjob -n default -o yaml
Example status:
status:
imagesCount: 10
conditions:
- type: Complete
status: "True"
reason: "AllImagesScanned"
message: "Scan completed successfully"
8. View Results
Reports generated by scans include images, SBOMs, and vulnerability findings. See the Querying Reports guide for details.
9. Stop an Ongoing Scan
To cancel a running scan, delete its ScanJob:
kubectl delete scanjob my-scanjob -n default
10. Remove a Registry
To delete a registry and its associated data:
kubectl delete registry my-registry -n default
This action removes:
-
The registry definition
-
All related images, SBOMs, and vulnerability reports
-
Any
ScanJobresources referencing the registry
If a scan is in progress, it will be terminated.