Skanning av containerimager
Skanning av containerimager svarer på spørsmålet hva er sårbart i dette imaget – som et supplement til SBOM-en, som svarer på hva finnes i dette imaget. Funnene kommer fra to kilder, og begge vises ved siden av imaget eller commiten de gjelder.
Slik fungerer det
Den daglige gjennomgangen av registeret
fremforge skanner selv containerimagene i organisasjonens pakkeregister. Du trenger ikke legge til noe i workflowene dine.
- Hva som skannes. Hver tag av hvert containerimage. Hver tag løses opp til manifest-digesten sin, og imaget skannes med
trivy imagefor sårbarheter og lekkede secrets, inkludert OS-pakker og språkavhengigheter i hvert lag. - Når. Én gang om dagen, etter at Trivys sårbarhetsdatabase er oppdatert. En digest som allerede er skannet mot samme databaseversjon, hoppes over, slik at en nypublisert CVE meldes mot et image som ikke har endret seg.
- Hvor funnene lagres. Med image-digesten som nøkkel (
frem.sh/<org>/<image>@sha256:<digest>). Avvisninger følger med når et image skannes på nytt. - Begrensninger. For et image med flere arkitekturer skannes bare
linux/amd64-varianten. Et image større enn 2 GiB (summen av lagene slik de er lagret i registeret) hentes ikke, og blir derfor ikke skannet.
Den samme gjennomgangen skanner også standardbranchen i hvert repository (trivy fs og trivy config).
Det samme image-pullet sjekkes også mot OSV-listen over ondsinnede pakker. Den sjekken er beskrevet i Ondsinnede pakker; en pull av et image med et åpent funn avvises, uansett blokkeringshandlingen nedenfor. Siden 2026-10-11 gjelder det samme for imager som er bufret gjennom avhengighetsproxyen (se nedenfor).
Imager bufret gjennom avhengighetsproxyen
Imager organisasjonen din puller gjennom avhengighetsproxyen, skannes på samme måte som imagene du pusher.
- Når. Et image settes i kø for første skanning når organisasjonen din bufrer det første gang, og skannes normalt innen 15 minutter. Deretter skannes det på nytt hver gang Trivys sårbarhetsdatabase endres, i den samme daglige gjennomgangen som dine egne imager, så lenge det ligger i bufferen din.
- Hva som skannes. Imaget for én plattform som klienten din pullet (for en tag med flere arkitekturer: varianten du pullet), med
trivy imagefor sårbarheter og lekkede secrets. - Hvor funnene lagres. Med nøkkelen
frem.sh/<org>/dependency-proxy/<upstream>/<repository>@sha256:<digest>, for eksempel.../dependency-proxy/docker.io/library/alpine@sha256:…, ved siden av dine egne imager i Organisasjonsadministrasjon → Sikkerhet › Funn › Containerimager og i Findings-API-et. Avvisninger følger med når imaget skannes på nytt. - Blokkeringshandling.
block_pullgjelder også for imager gjennom proxyen: en pull gjennom proxyen av et image med et ikke-avvist high- eller critical-funn avvises med403 DENIED. - Ondsinnede pakker. Språkpakkene inne i et bufret image sjekkes mot OSVs sårbarhetsvarsler om ondsinnede pakker, som for pushede imager, og et treff blir et funn på Malware-fanen. Siden 2026-10-11 avvises en pull av et bufret image med et åpent funn, som for et pushet image; se Avhengighetsproxy.
- Delte skanninger. Et image identifiseres ved digesten sin, så når flere organisasjoner bufrer det samme imaget, skannes det én gang, og hver organisasjon får sin egen kopi av funnene. Du ser aldri funn for andre imager enn dem i din egen buffer.
- Når et image forlater bufferen din. Funnene blir værende så lenge imaget fortsatt er i bruk: pullet gjennom proxyen av organisasjonen din, eller nevnt i en av utrullingene dine, i løpet av de siste 30 dagene (tilgangsloggen for registeret og utrullingsregistreringene viser hvilke). Etter det fjernes de ved neste gjennomgang. Et image som pulles på nytt etter at funnene er fjernet, får dem tilbake ved neste gjennomgang, fra skanningen av digesten.
Imager som Helm-chartene dine ruller ut
Imagene et Helm-chart i repositoryet ditt ruller ut, skannes for sårbarheter, og funnene rapporteres på repositoryets fremforge/image-scan-sjekk.
- Hva som leses. Hvert chart i repositoryet, det vil si hver katalog med en
Chart.yaml. Ivalues.yaml: enimage:med en referanse (image: nginx:1.25.3), og den oppdelte formen chartene oftest bruker (image:medregistry,repository,tagogdigestunder). Et oppdelt image uten tag, eller medtag: "", er chartetsappVersion, som er det{{ .Values.image.tag | default .Chart.AppVersion }}ruller ut. Itemplates/: enimage:-linje med en bokstavelig referanse. Nøkler sominitImageellersidecarImageteller også;imagePullPolicyogimagePullSecretsgjør det ikke. - Hva som ikke leses. Maler rendres ikke, og ingen chartkode kjøres, så et image som settes sammen av mallogikk, andre values-filer enn
values.yaml(en overlay du velger ved installasjon) og avhengighetscharter som ikke ligger i repositoryet, dekkes ikke. En referanse uten register er Docker Hub (nginxerdocker.io/library/nginx), og en uten tag erlatest. - Hvordan imaget hentes. Gjennom organisasjonens avhengighetsproxy, slik en pull fra deg ville blitt: upstream-legitimasjonen din, pakkepolicy, skanning etter skadevare og buffer gjelder. Har organisasjonen din ingen avhengighetsproxy, henter fremforges egen proxy det, anonymt og bare fra registre som tillater det (for eksempel
ghcr.io,quay.io,registry.k8s.io). Et image proxyen din avviser (for eksempel et som policyen din blokkerer), skannes ikke. linux/amd64-imaget skannes medtrivy imagefor sårbarheter. - Docker Hub krever din egen legitimasjon. Docker Hub-imager pulles bare med organisasjonens egen Docker Hub-legitimasjon, aldri anonymt og aldri med en fremforge-konto. Uten den blir et Docker Hub-image i et chart ikke skannet:
fremforge/image-scan-statusen sier det («N Docker Hub image(s) in Helm charts not scanned: add your Docker Hub credential»), og Sikkerhet › Funn › Containerimager lister imagene med en lenke for å legge til legitimasjonen under Påloggingsdetaljer for upstream. Imagene skannes når du har lagt den til, fra repositoryets neste skanning; funn skannet for en annen organisasjon vises aldri for din. - Når. Et image settes i kø første gang en skanning nevner det, og skannes normalt innen 15 til 30 minutter; funnene vises ved repositoryets neste skanning. Et image som fortsatt nevnes, skannes på nytt med noen dagers mellomrom, fordi en tag kan flytte seg og nye sårbarhetsvarsler publiseres.
- Slik leses et funn. Målet er chartfilen og imaget, for eksempel
charts/web/values.yaml: docker.io/library/nginx:1.19.0, med pakken, versjonen og den rettede versjonen. Funnene går gjennom terskelen og avvisningene for image-skanning, og en pull request blokkeres bare av funn den selv legger til.
Nyere tagger for upstream-imager
Et image du puller fra upstream, har ingen Dockerfile av deg som kan rettes, så fremforge ser etter en nyere tag som retter funnene. For hvert bufret image med åpne high- eller critical-funn, høyst én gang om dagen:
- Taggen du pullet. Digesten matches mot taggen organisasjonen din pullet den med, via indeksen for flere arkitekturer når det finnes en.
- Kandidaten. Dette er den nyeste taggen i samme linje, som har samme form og de samme tallene bortsett fra det siste:
3.12.4-slimtil3.12.10-slim, eller16.4til16.10. Det er aldri en annen major- eller minor-versjon, fordi det er en migrering og ikke en rettelse. En tag uten en slik linje, som3.12-slim,16ellerpg17, sjekkes i stedet for en ombygging: den samme taggen, bygget på nytt upstream siden du pullet den. - Hva den retter. Kandidaten pulles og skannes med den samme skanneren. Hvert åpent funn hos deg som kandidaten ikke lenger har, teller som rettet.
Funnet sier da ett av disse:
| Vises | Betydning |
|---|---|
Nyere tag <tag> retter N av funnene i dette imaget | Gå over til den taggen. Åpne PR med <tag> åpner pull requesten nedenfor |
Bygget på nytt upstream: å hente <tag> igjen retter N | Den samme taggen er nyere upstream. Pull den på nytt; ingenting endres i repositoryet ditt med mindre en referanse er låst til en digest |
| Upstream-image, ingen nyere rettet tag | Ingen tag i samme linje, og ingen ombygging, har færre av disse funnene |
| Upstream-image: nyere tagger er ikke sjekket ennå | Ikke sjekket ennå, eller registeret er ikke et som fremforge leser tagger fra (Docker Hub, GHCR, Quay, MCR, ECR Public og registry.k8s.io er det) |
Det samme finnes i Findings-API-et som upstream_update.
Pull requesten. Åpne PR med <tag>, eller POST /orgs/{org}/dependency-updates/security-fixes/image-ref-requests med image_finding_id, søker gjennom organisasjonens repositoryer etter referanser til imaget med taggen du pullet. Det dekker docker compose-filer, Kubernetes-manifester, Helm-values med repository: og tag: på separate linjer, og CI-oppføringer med image: og container:, under alle navnene imaget går under:
frem.sh/<org>/dependency-proxy/docker.io/library/python:3.12.4-slimdocker.io/library/python:3.12.4-slimpython:3.12.4-slim
Hvert repository som har en referanse, får én pull request med en sikkerhetsrettelse som flytter alle referansene. En låsing til digest flyttes til kandidatens digest. Den har den vanlige branchen, etiketten, grensene og merge-innstillingen. En FROM i en Dockerfile endres ikke her: det er rettelsen av base-image. Når ingen repositoryer refererer til imaget, åpnes ingenting, og funnet fortsetter å vise taggen som retter det. Opptil 60 repositoryer og 400 YAML-filer leses per forespørsel.
Skanning fra din egen workflow
Du kan også skanne i CI og sende inn resultatene. fremforges runner-image leveres med Trivy. Dette eksempelet skanner filsystemet i repoet (trivy fs – avhengigheter og lekkede secrets) og IaC-konfigurasjonen (trivy config – Dockerfiler, Compose-filer), og POST-er så funnene:
- name: Scan + push findings
run: |
trivy fs --format json --output trivy-fs.json .
trivy config --format json --output trivy-config.json .
curl -sS --fail \
-H "Authorization: Bearer ${{ secrets.FREMFORGE_API_TOKEN }}" \
-H 'Content-Type: application/json' \
-d @<(jq -c '{
image_ref: "'"${GITHUB_REPOSITORY}@${GITHUB_SHA}"'",
commit_sha: "'"${GITHUB_SHA}"'",
repo_full_name: "'"${GITHUB_REPOSITORY}"'",
findings: [.Results[].Vulnerabilities[] | {
cve_id: .VulnerabilityID,
severity: (.Severity|ascii_downcase),
package_name: .PkgName,
installed_version: .InstalledVersion,
fixed_version: .FixedVersion,
title: .Title,
target: .PkgPath
}]
}' trivy-fs.json) \
"https://frem.sh/_app/api/v1/image-scans/findings"PAT-en trenger scopet findings:write.
Policybrytere
Sikkerhet › Policyer › Imagepolicyer har disse innstillingene (fram til 2026-10-15 lå de under Funn › Containerimager):
- Slått på – når den er av, returnerer innsendingen
202 {accepted: 0, status: 'disabled'}(dataene parses fortsatt, men forkastes). Nyttig for team før lansering som vil at skanningen skal kjøre uten å sperre noe. - Block action –
none|warn|block_pull:none– lagrer funn og poster ingen commit-status. Bare deteksjon på byggesiden. Pulls sjekkes ikke.warn– lagrer funn og poster commit-statusensuccessmed en beskrivelse som oppgir antallet. Merge av pull requests blokkeres ikke. Pulls sjekkes, men avvises aldri: en pull somblock_pullville avvist, leveres og registreres somwould_blocki tilgangsloggen for registeret og som revisjonshendelsenregistry.pull.would_block(se Revisjonslogg og SIEM).block_pull– lagrer funn og poster commit-statusenfailurenår det finnes minst ett ikke-avvist funn på eller over blokkeringsterskelen din. På en pull request teller bare funn som pull requesten introduserer (se Pull requests: bare nye funn blokkerer). Branchbeskyttelse med den påkrevde statussjekkenfremforge/image-scanblokkerer da merge. Den blokkerer også pulls: endocker pull(med tag eller digest) av et image med et slikt funn avvises med403 DENIED, og meldingen oppgir terskelen og lenker til funnene. Avvis eller rett funnene for å oppheve blokkeringen. Hver avvisning er revisjonshendelsenregistry.pull.blocked.
- Require signed images – når den er på, godtar innsendingen også feltet
signature_status(signed/unsigned/unknown). Usignerte imager (eller signerte imager fra en utsteder som ikke står på tillatelseslisten) får et syntetisk critical-funn, slik at den samme pull-blokkeringen håndhever signeringspolicyen. Se Cosign for signeringssiden.
Blokkeringsterskel
Funnene som blokkerer, er de på eller over én alvorlighetsgrad, satt per organisasjon. Det er block_severity i image_scan-oppføringen i organisasjonens skannepolicy, den samme innstillingen for merges og for pulls:
block_severity | Blokkerer på |
|---|---|
critical | critical |
high (standard) | high og critical |
medium | medium, high og critical |
low | alle funn |
Sett den med PUT /_app/api/v1/orgs/<org>/policy:
curl -X PUT -H "Authorization: Bearer ${FREMFORGE_PAT}" -H 'Content-Type: application/json' \
-d '{"scan_policy": {"image_scan": {"mode": "enforce", "block_severity": "critical"}}}' \
"https://frem.sh/_app/api/v1/orgs/acme/policy"eller i konfigurasjon som kode som scan_policy = { image_scan = { mode = "enforce", block_severity = "critical" } }. null, eller ingen image_scan-oppføring, betyr high, som er det alle organisasjoner hadde før terskelen kunne settes. Alle andre verdier avvises med 400. Tokenet trenger policy:write. Konsollen har ingen kontroll for dette ennå.
Bare oppføringen for hele organisasjonen teller. En overstyring av skannepolicyen per repository kan ha en block_severity, men en image-pull er ikke knyttet til ett repository, så image-sperrene leser den ikke.
Pull requests: bare nye funn blokkerer
fremforge/image-scan-sjekken på en pull request feiler bare på funn som pull requesten introduserer. fremforge sammenligner pull requestens funn på eller over blokkeringsterskelen med den siste skanningen av branchen den merges inn i. Et funn som den branchen allerede har, blokkerer ikke, så en pull request som ikke endrer noe sårbart, kan merges i et repository med åpne funn. Statusen lyder da for eksempel No new high/critical findings; 7 already on main.
- Et funn er det samme når sårbarhetsvarselet, pakken og filen er de samme – den identiteten en avvisning følger med etter. Det samme sårbarhetsvarselet i en annen fil er et nytt funn.
- En pull request som legger til ett nytt high-funn i et repository med mange eksisterende, feiler: 1 new high/critical finding(s) …; merge blocked; 30 already on main.
- En pull request som retter noen funn og ikke legger til noen, går gjennom.
- Eksisterende funn skjules ikke. De listes, teller mot SLA-en din og sperrer image-pulls som før.
Branchen skannes etter en push til standardbranchen, høyst én gang i timen, og den nyeste pushen vinner. Et funn som har kommet inn på branchen siden siste skanning, teller derfor fortsatt som pull requestens fram til neste skanning. Det går aldri motsatt vei: et nytt funn blir aldri forvekslet med et eksisterende.
Når det ikke finnes noen skanning av branchen pull requesten merges inn i, blokkerer alle funn på eller over terskelen, som før. For standardbranchen ber skanningen av pull requesten også om en skanning av branchen. Når branchens første skanning er registrert, skanner fremforge på nytt, av seg selv, de åpne pull requestene inn i den der sjekken feilet i mellomtiden (høyst 20 per repository, de sist oppdaterte), slik at de blir grønne, eller forblir røde bare på grunn av det de legger til, uten ny kjøring eller ny push. En pull request inn i en hvilken som helst annen branch teller alltid alle funn.
Sperren for image-pull er uendret: en pull av et image med et ikke-avvist funn på eller over terskelen avvises under block_pull, enten funnet er nytt eller ikke.
Revisjonslogg og SIEM
Hver pull-beslutning fra image-sperrene skrives til revisjonsloggen din og derfra til SIEM-en din:
registry.pull.blocked– en pull ble avvist: avblock_pull(sperrenimage_scan), av treff på skadevare (image_malware), av et lag som ClamAV fant infisert eller ikke kunne skanne (registry_scan, ellerregistry_blobfor et lag hentet direkte med digest), eller av sjekken av image-signatur (signature).registry.pull.would_block– en pull ble levert som en av disse sperrene ville avvist: underwarn, eller mens en sperre kjører i observasjonsmodus.
Det kommer én hendelse per image-digest, sperre og beslutning per time; neste hendelse for samme digest har med antallet fra timen før.
Hvor funnene vises
Organisasjonsadministrasjon → Sikkerhet › Funn › Containerimager lister skanninger etter image-ref, commit og PR. Hver rad viser:
- Antall per alvorlighetsgrad (critical / high / medium / low)
- Antall som kan rettes (funn med en
fixed_versionsom ikke er null) - Status (
success/failure/skipped) og commit-statusen som ble postet - Lenker til sårbarhetsvarslene upstream (CVE, GHSA når den finnes)
Slik ser et funn ut i databasen
Felt som lagres per funn: cve_id, severity, package, installed_version, fixed_version, target (filstien inne i imaget) og scan_run_id, som knytter sammen funn fra samme kjøring. Hele Trivy-utdataene lagres IKKE – bare radene per funn, som er den formen som kan spørres mot.
Oppbevaring
Funn følger oppbevaringspolicyen for revisjonsdata per kunde. Funn som har nådd utløpsalderen, beholder hashen sin i kjeden (manipulasjonsavslørende), men mister innholdet i raden.
Se også
- Ondsinnede pakker – den samme image-pullen sjekkes også mot OSVs
MAL-*-sårbarhetsvarsler; en pull av et image med et åpent funn avvises uansett blokkeringshandlingen ovenfor. - Cosign – signering av imager og policy for signerte imager.
- SBOM-er – pakkeoversikten i imaget (uavhengig av sårbarhetstilstand).
- OSV-anbefalinger – motstykket på kildesiden (sårbarheter i avhengighetene dine før de leveres).
- API-referanse – innsendingsendepunktet
POST /_app/api/v1/image-scans/findings(avgrenset til kunden via runnerens PAT).