Trivy i CI/CD-pipelines 2026: Containerscanning, SBOM og IaC
Sådan integrerer du Trivy i GitHub Actions og GitLab CI: containerscanning, SBOM-generering, IaC-checks og pragmatisk fail-policy med KEV-filter og OpenVEX-suppression.
Trivy er open source-scanneren fra Aqua Security, der finder sårbarheder, hemmeligheder, licensproblemer og fejlkonfigurationer i containerbilleder, filsystemer, IaC-manifester og Kubernetes-klynger, alt sammen i én binær og med én kommando. I 2026 er Trivy blevet den de facto standard for pipelinescanning på Linux, fordi den understøtter SBOM-generering (SPDX og CycloneDX), VEX-suppression og direkte opslag i CISA KEV-kataloget. Denne guide viser, hvordan du integrerer Trivy i GitHub Actions og GitLab CI, hærder policyerne og filtrerer støjen fra, så bygninger kun fejler, når det faktisk betyder noget.
Trivy 0.58+ (juni 2026) understøtter SBOM-attest med Cosign, VEX-dokumenter i OpenVEX-format og indbygget KEV-berigelse.
En pragmatisk CI-policy fejler kun på CRITICAL-CVE'er, der findes i KEV-kataloget eller har en tilgængelig patch, ikke på hver eneste rød linje.
Trivy Operator giver klyngen konstant scanning uden sidecar-injektion; den skriver VulnerabilityReport-CRD'er direkte til etcd.
Trivy IaC-scanner dækker Terraform, CloudFormation, Kubernetes YAML, Helm og Dockerfiles i samme binær og med én cache.
SBOM'er bør genereres én gang i build-fasen og genbruges i deploy og runtime, ikke rescannes fra bunden i hver pipeline.
Grype, Snyk og Docker Scout dækker overlappende felter. Trivy vinder på licensering, IaC-bredde og ingen call-home.
Hvad er Trivy, og hvorfor pipeline-først?
Trivy er en enkelt Go-binær, der scanner otte artefakttyper (containerbilleder, filsystemer, git-repos, Kubernetes-klynger, VM-billeder, IaC-manifester, SBOM'er og AWS-konti) mod en samlet sårbarhedsdatabase, som opdateres to gange dagligt af Aqua Security. Fra og med Trivy 0.58 (juni 2026) er databasen delt i tre: trivy-db for OS-pakker, trivy-java-db for Maven-artefakter og trivy-checks for IaC-policy. Alle tre distribueres som OCI-artefakter og kan speiles i et privat registry.
Ærligt talt vinder Trivy pipelineslaget mod Grype og Snyk af tre grunde, sådan som jeg har oplevet det i produktion. For det første er den gratis for kommerciel brug (Apache 2.0), uden bruger- eller repo-loft. For det andet dækker den alle lag, jeg rører i en typisk DevSecOps-pipeline: docker build, Terraform-plan, Helm-chart og runtime-klynge. Og for det tredje kalder den ikke hjem. Al scanning sker lokalt, hvilket betyder, at jeg kan køre den i air-gapped miljøer uden PII-lækage. Det er også derfor, jeg placerer Trivy før images-push i registryet, ikke bagefter: en fejlet CVE-check her koster et par sekunder, mens en tilbagerulning i produktion koster en hel eftermiddag.
Pipeline-først betyder også, at scanning ikke er en engangsopgave. Jeg kører Trivy i mindst tre faser: pull-request (blokerer på kritiske), nightly (fanger nye CVE'er i uændrede images) og runtime via Trivy Operator (opdager drift efter deployment). Kombineret med signering via Cosign og Sigstore-workflowet giver det en beviskæde fra kildekode til klynge. Det er sådan set hele pointen.
Installation og opdatering af Trivy i 2026
På Debian, Ubuntu, RHEL og Fedora er det officielle repository den nemmeste vej. Trivy 0.58.1 (juni 2026) understøtter Ubuntu 24.04, Debian 13 (trixie), RHEL 9/10 og Fedora 40+. Undgå snap-installationen; den halter typisk 2-3 versioner bagud og misser KEV-berigelsen.
I CI foretrækker jeg det officielle container-image aquasec/trivy:0.58.1 med en fast tag, ikke latest. Det gør builds reproducerbare og undgår, at et pludseligt DB-skema-brud lukker hele pipelinen. Cache databasen i en persistent volume (/root/.cache/trivy) for at spare 200-400 MB download per job.
Scanning af containerbilleder på Linux
Grundscanning af et image tager typisk 3-8 sekunder efter første DB-download. Trivy læser OS-pakker (dpkg, rpm, apk) og sprogafhængigheder (npm, pip, go.sum, Cargo.lock, pom.xml, Gemfile.lock) i samme kørsel. Den afgørende hemmelige sauce er --severity-filteret kombineret med --exit-code. Det er faktisk det, der får pipelinen til at fejle på det rigtige tidspunkt.
# Grundscanning — outputter til stdout
trivy image nginx:1.27-alpine
# Kun HIGH/CRITICAL, fejl builden hvis der findes noget
trivy image \
--severity HIGH,CRITICAL \
--exit-code 1 \
--ignore-unfixed \
nginx:1.27-alpine
# JSON-output til videre parsing i pipeline
trivy image \
--format json \
--output nginx-scan.json \
--scanners vuln,secret,license \
nginx:1.27-alpine
# SARIF for GitHub Code Scanning
trivy image \
--format sarif \
--output trivy-results.sarif \
--severity HIGH,CRITICAL \
nginx:1.27-alpine
Flaget --ignore-unfixed er det, jeg altid slår til i CI. Det springer sårbarheder over, hvor upstream ikke har frigivet en patch endnu, og der er ingen grund til at fejle en build på noget, jeg ikke kan reagere på. --scanners begrænser til de scanninger, du har brug for; på et minimalt Alpine-image kan du slippe med vuln,secret og barbere 40% af køretiden af.
GitHub-actionen aquasecurity/[email protected] (2026) skifter automatisk til det officielle image og uploader SARIF til Code Scanning-fanen. Det nye i 2026 er --pkg-relationships, som filtrerer indirekte transitive afhængigheder fra. Det reducerer typisk støj med 30-50%.
Trikket her er separationen. SARIF uploades først, så udviklere altid kan se scanningen i Security-fanen, selv når builden fejler. Blokerings-tjekket er et efterfølgende job, der kun fejler på patchbare kritiske CVE'er, som har været offentlige i mere end 30 dage. Det matcher CISA KEV-baselinen, som de fleste compliance-frameworks nu peger på. For yderligere hærdning af selve container-runtimen, se guiden om RunC-sårbarheder og runtime-beskyttelse.
Trivy i GitLab CI med cache og SARIF-upload
GitLab har indbygget understøttelse af Trivy-rapporter via container_scanning-artefakter siden GitLab 16.5. I 2026 anbefaler jeg fortsat at køre Trivy direkte, fordi det giver mere kontrol over policy og caching end den indbyggede skabelon.
Spejlingen af trivy-db til det interne GitLab-registry er ikke pynt. Det er, hvad der får jobs til at gennemføre pålideligt i et VPN-isoleret miljø. En cron-job puller opstrøms hver 12. time og pusher til det interne registry.
SBOM-generering og signering med Cosign
SBOM (Software Bill of Materials) er ikke længere valgfrit i 2026. Det er et krav i EU's Cyber Resilience Act og NIS2 for produkter, der sælges kommercielt. Trivy kan producere både SPDX 2.3 og CycloneDX 1.6 i JSON eller XML. Anbefalingen: generér SBOM'en én gang i build-fasen, signér den med Cosign, og genbrug den derefter i alle downstream-scanninger.
Fordelen ved SBOM-baseret scanning er dobbelt: den er hurtigere (ingen filsystem-inspektion), og den bevarer et historisk snapshot af, hvad der var i imaget på build-tidspunktet, selv hvis basisimaget senere overskrives. Det er nøglen til at kunne besvare "var vi sårbare over for CVE-2026-XXXX i uge 22?" et halvt år efter kendsgerningen. Jeg har selv haft præcis den samtale med en revisor, og et attesteret SBOM sparede os for en uges arkæologi. Se også vejledningen om signering af container-images med Cosign for hele attesteringskæden.
Kan Trivy scanne Terraform-filer?
Ja. Trivy erstattede sit gamle IaC-modul i version 0.35 med den bredere config-scanner, som deler engine med tfsec og cfsec. Fra 0.58 er dækningen: Terraform (HCL), Terraform Plan JSON, CloudFormation, Kubernetes YAML, Helm charts, Dockerfiles, containerd og Azure ARM. Reglerne er skrevet i Rego via det åbne trivy-checks-repo og opdateres uafhængigt af selve binæren.
# Scan hele repoet for IaC-fejlkonfigurationer
trivy config .
# Kun HIGH+, JSON-output, med filter-fil
trivy config \
--severity HIGH,CRITICAL \
--format json \
--output iac-scan.json \
--config-check-bundle-repository ghcr.io/aquasecurity/trivy-checks:1 \
--skip-dirs "**/vendor/**,**/node_modules/**" \
./terraform
# Kombineret filesystem-scan: kode, deps OG IaC på én gang
trivy fs \
--scanners vuln,secret,misconfig,license \
--severity HIGH,CRITICAL \
--ignorefile .trivyignore \
.
Et lille footgun: trivy config vs trivy fs --scanners misconfig. De to producerer samme fund, men trivy fs udnytter fælles cache, hvis du allerede scanner for sårbarheder og hemmeligheder. På en stor monorepo er den forskel 30-60 sekunder per job. Ikke dramatisk, men det tæller op over hundredvis af PR'er om ugen. For en dybere gennemgang af IaC-hærdning, se guiden om CIS Benchmark-compliance med OpenSCAP.
Hvordan adskiller Trivy sig fra Grype?
Grype er Anchores modstykke og deler faktisk en del data med Trivy via NVD og GitHub Security Advisories. Forskellene ligger primært i bredden, licens og operationel model. Denne tabel opsummerer, hvor jeg placerer dem i en typisk DevSecOps-stak i 2026:
Funktion
Trivy 0.58
Grype 0.86
Docker Scout
Licens
Apache 2.0
Apache 2.0
Proprietær (gratis niveau)
Containerimage-scanning
Ja
Ja
Ja
IaC / Terraform
Ja (indbygget)
Nej
Nej
Hemmeligheds-scanner
Ja
Nej (kræver Syft+ext)
Delvist
SBOM-generering
SPDX, CycloneDX
Kræver Syft
SPDX
VEX / OpenVEX
Native
Native
Native
KEV-berigelse
Indbygget
Via ekstern feed
Ja
Kubernetes Operator
Trivy Operator
Nej officielt
Nej
Ringer hjem
Nej
Nej
Ja (opt-out)
Startup-tid (koldt)
2-4 s
1-2 s
5-10 s
Kort sagt: Grype er fremragende, hvis du allerede har standardiseret på Syft til SBOM'er og kun har brug for CVE-matching. Trivy er det rigtige valg, når du vil dække image, IaC, hemmeligheder og licenser i én binær, og især når air-gap-krav udelukker Docker Scout.
Hvordan fejler jeg en build kun på kritiske sårbarheder?
At fejle på hver MEDIUM-CVE er den hurtigste vej til udviklertræthed (jeg har prøvet det, det virker ikke). Min anbefaling siden 2024 har været en tre-lags policy: rapportér alt, fejl på patchbare kritiske, og bloker deploy på KEV-listede. Det holder pipelinen anvendelig og fokuserer opmærksomheden på ægte risici.
Med denne fil i repo-roden behøver CI-kommandoen kun være trivy image --exit-code 1 $IMAGE. Al policy er versioneret sammen med koden, hvilket også betyder, at PR-anmeldere kan se, når nogen forsøger at slække på en regel.
# CI-klar Bash: to-lags gate — advar, så bloker
trivy image --severity HIGH --exit-code 0 "$IMAGE" # rapport
trivy image --severity CRITICAL \
--ignore-unfixed \
--pkg-relationships direct \
--exit-code 1 "$IMAGE" # blokér
Undertrykkelse af falske positiver med VEX og .trivyignore
Selv med et stramt filter dukker der falske positiver op. Klassikeren: en CVE i libxml2, som kun rammer XSLT-parsing, mens vores app kun bruger DOM. To metoder til at håndtere det renligt: .trivyignore for hurtige undertrykkelser og OpenVEX-dokumenter for auditbare beslutninger.
# .trivyignore: enkel, kommenteret, versioneret
# libxml2 XSLT-hul, vi bruger kun DOM
# Verificeret af sikkerhed 2026-05-14, gennemgåes hvert kvartal
CVE-2025-12345
# Falsk positiv i k8s-vendored code
# Reference: https://github.com/aquasecurity/trivy/discussions/8421
CVE-2026-00892 exp:2026-12-31
VEX går et lag dybere: du erklærer eksplicit hvorfor en CVE ikke er relevant (not_affected, fixed, under_investigation). Trivy læser .vex/-mappen automatisk fra 0.55 og fremad.
Trivy Operator er en Kubernetes-controller, som scanner alle images, konfigurationer og RBAC-tilladelser i klyngen, og skriver resultaterne som CRD'er (VulnerabilityReport, ConfigAuditReport, ExposedSecretReport). Version 0.24 fra maj 2026 tilføjede indbygget SBOM-generering og en gauge-metric per CVE-alvor, som Prometheus kan alarmere på.
helm repo add aqua https://aquasecurity.github.io/helm-charts/
helm install trivy-operator aqua/trivy-operator \
--namespace trivy-system --create-namespace \
--set trivy.ignoreUnfixed=true \
--set trivy.severity=HIGH\,CRITICAL \
--set operator.metricsVulnIdEnabled=true \
--set operator.builtInTrivyServer=true \
--version 0.24.1
# Se sårbarheder på tværs af klyngen
kubectl get vulnerabilityreports -A -o wide
# Prometheus-alert (uddrag)
- alert: KubeCriticalCVE
expr: sum(trivy_image_vulnerabilities{severity="Critical"}) by (namespace, image) > 0
for: 15m
labels: {severity: page}
Operatoren komplementerer runtime-kontrollen fra Tetragon med eBPF-baseret kørselssikkerhed. Trivy fanger sårbarheder i imaget, mens Tetragon fanger, hvad imaget faktisk gør, når det kører. Sammen dækker de før-deploy- og efter-deploy-hullerne i en typisk klynge.
Aqua Security opdaterer trivy-db hver 6. time, mens trivy-java-db opdateres dagligt, og trivy-checks opdateres ved behov (typisk en gang om ugen). I CI cacher jeg databasen i 12 timer for at balancere friskhed og downloadstøj.
Er Trivy gratis til kommerciel brug?
Ja. Trivy er udgivet under Apache 2.0-licensen uden bruger-, repo- eller image-loft. Aqua Security tilbyder et betalt tillæg (Aqua Enterprise), som tilføjer et centralt dashboard, RBAC og SLA, men selve scannerens funktionalitet forbliver open source.
Understøtter Trivy scanning bag en proxy eller i air-gap?
Ja. Sæt HTTPS_PROXY for netværk gennem en proxy, eller spejle trivy-db, trivy-java-db og trivy-checks til et internt OCI-registry og peg på dem via TRIVY_DB_REPOSITORY-miljøvariablerne. Alle Trivy-kommandoer kan derefter køres offline.
Hvad er forskellen på Trivy fs og Trivy image?
trivy image scanner et bygget containerbillede (fra registry eller lokalt), mens trivy fs scanner et lokalt filsystem eller git-repo. Førstnævnte fanger runtime-lag som base image; sidstnævnte fanger, hvad der er i den kode, du er ved at bygge, før imaget eksisterer.
Kan Trivy generere en SBOM uden at scanne for sårbarheder?
Ja. Kør trivy image --format cyclonedx --skip-vulnerabilities --output sbom.json IMAGE. Det udskriver kun komponentlisten, hvilket er hurtigere og nyttigt, når SBOM'en skal signeres og gemmes for compliance uden aktiv sårbarhedsberigelse.
Hvordan integrerer Trivy med Cosign og attesteringer?
Generér SBOM'en med trivy image --format cyclonedx, og attester derefter med cosign attest --predicate sbom.cdx.json --type cyclonedx IMAGE. Attesteringen gemmes ved siden af imaget i registryet og kan verificeres i deploy-fasen med cosign verify-attestation.
En praktisk guide til at signere og verificere container-images med Cosign v2.4 og Sigstore på Linux i 2026. Dæk keyless OIDC-signering i GitHub Actions, KMS-baseret signering i luftgab, håndhævelse med Kyverno og SLSA-attestationer.
Komplet guide til container-sikkerhed i 2026: Forstå runC-sårbarheder (CVE-2025-31133, CVE-2025-52565, CVE-2025-52881), hærd dine images, opsæt seccomp og AppArmor, implementer Falco-overvågning, og udforsk gVisor og Kata Containers.