Scanning Basics
This section introduces container image scanning: finding known vulnerabilities in an image before it ships, then blocking bad images at the Kubernetes admission gate.
Search across all documentation pages
This section introduces container image scanning: finding known vulnerabilities in an image before it ships, then blocking bad images at the Kubernetes admission gate.
Quick install of Trivy on Debian/Ubuntu:
# Install Trivy from the Aqua Security apt repo
sudo apt-get install -y wget gnupg
wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | sudo gpg --dearmor -o /usr/share/keyrings/trivy.gpg
echo "deb [signed-by=/usr/share/keyrings/trivy.gpg] https://aquasecurity.github.io/trivy-repo/deb generic main" | sudo tee /etc/apt/sources.list.d/trivy.list
sudo apt-get update && sudo apt-get install -y trivyRun Trivy against an image you just built to list known CVEs by severity.
trivy image myapp:1.4.0Make the scanner return a non-zero exit code so CI stops the pipeline.
trivy image --severity HIGH,CRITICAL --exit-code 1 myapp:1.4.0--exit-code 1 turns findings into a failed step, which blocks the merge or deploy.--severity limits what counts as a failure so low-noise findings do not break builds.--ignore-unfixed to skip CVEs that have no available patch yet.Catch problems in dependencies and configuration without building an image.
trivy fs --scanners vuln,misconfig .trivy fs scans a project directory for vulnerable lockfile dependencies.misconfig scanner flags insecure Dockerfile and manifest settings, like running as root.Produce a software bill of materials so you can map future CVEs to shipped images.
trivy image --format cyclonedx --output sbom.json myapp:1.4.0--format spdx-json.Grype is a fast, drop-in second opinion that reads the same image.
grype myapp:1.4.0 --fail-on high--fail-on high fails the run on High or Critical findings.Avoid re-downloading the DB on every pipeline run.
trivy image --cache-dir .trivycache/ --exit-code 1 --severity CRITICAL myapp:1.4.0--cache-dir at a path your CI system caches between runs.TRIVY_DB_REPOSITORY.Point Trivy at your cluster to report on images already deployed.
trivy k8s --report summary clustertrivy k8s inspects the images referenced by running workloads.Combine continuous scanning with a policy that blocks vulnerable images from being admitted.
# Kyverno: deny Pods whose image has an unresolved CRITICAL vulnerability report
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: block-critical-cves
spec:
validationFailureAction: Enforce
background: false
rules:
- name: check-vuln-report
match:
any:
- resources:
kinds: ["Pod"]
context:
- name: report
apiCall:
urlPath: "/apis/aquasecurity.github.io/v1alpha1/namespaces/{{request.namespace}}/vulnerabilityreports"
validate:
message: "Image has CRITICAL vulnerabilities and is blocked."
deny:
conditions:
any:
- key: "{{ report.items[].report.summary.criticalCount | sum(@) }}"
operator: GreaterThan
value: 0vulnerabilityreports custom resources.validationFailureAction: Enforce makes the deny real; use Audit first to see impact.Prove an image came from your pipeline before allowing it to run.
# In CI, after pushing the image
cosign sign --key env://COSIGN_KEY registry.example.com/myapp:1.4.0cosign sign attaches a signature to the image in the registry.verifyImages rule rejects any image lacking a valid signature.Make a failed scan block the pull request automatically.
# .github/workflows/scan.yml (job step)
- name: Scan image
uses: aquasecurity/trivy-action@master
with:
image-ref: myapp:${{ github.sha }}
severity: HIGH,CRITICAL
exit-code: "1"
ignore-unfixed: "true"ignore-unfixed avoids blocking on vulnerabilities with no patch available.Stack versions: This page was written for Kubernetes 1.36.2, Docker Engine 29.6.1 (BuildKit default), containerd (CRI runtime on nodes), Helm 3, Compose v2, Argo CD (latest - verify at build), and Gateway API (GA - verify controller support at build).
Reviewed by Chris St. John·Last updated Jul 19, 2026