Skanning av container-images
Skanning av container-images svarar på frågan vad i den här imagen är sårbart, som ett komplement till SBOM:ens vad finns i den här imagen. Fynden kommer från två källor, och båda visas bredvid den image eller commit de beskriver.
Så fungerar det
Den dagliga genomsökningen av registryt
fremforge skannar själv container-imagerna i din organisations paketregistry. Du behöver inte lägga till något i dina arbetsflöden.
- Vad som skannas. Varje tagg på varje container-image. Varje tagg löses upp till sin manifest-digest, och imagen skannas med
trivy imageefter sårbarheter och läckta hemligheter, inklusive OS-paket och språkberoenden i varje lager. - När. En gång om dagen, efter att Trivys sårbarhetsdatabas har uppdaterats. En digest som redan har skannats mot samma databasversion hoppas över, så en nypublicerad CVE tas upp mot en image som inte har ändrats.
- Var fynden sparas. Med image-digesten som nyckel (
frem.sh/<org>/<image>@sha256:<digest>). Avfärdanden följer med när en image skannas om. - Begränsningar. För en image med flera arkitekturer skannas bara varianten
linux/amd64. En image som är större än 2 GiB (summan av dess lager som de lagras i registryt) hämtas inte, så den skannas inte.
Samma genomsökning skannar också varje repos standardbranch (trivy fs och trivy config).
Samma pull av imagen matchas också mot OSV:s lista över skadliga paket. Den kontrollen beskrivs i Skadliga paket; en pull av en image med ett öppet fynd nekas, oavsett blockeringsåtgärden nedan. Sedan 2026-10-11 gäller samma sak för images som cachas genom beroendeproxyn (se nedan).
Images som cachas genom beroendeproxyn
Images som din organisation hämtar genom beroendeproxyn skannas på samma sätt som de images du pushar.
- När. En image köas för sin första skanning när din organisation cachar den första gången, och skannas normalt inom 15 minuter. Därefter skannas den om varje gång Trivys sårbarhetsdatabas ändras, i samma dagliga genomsökning som dina egna images, så länge den finns kvar i din cache.
- Vad som skannas. Den image för en enda plattform som din klient hämtade (för en tagg med flera arkitekturer, den variant du hämtade), med
trivy imageefter sårbarheter och läckta hemligheter. - Var fynden sparas. Med nyckeln
frem.sh/<org>/dependency-proxy/<upstream>/<repository>@sha256:<digest>, till exempel.../dependency-proxy/docker.io/library/alpine@sha256:…, bredvid dina egna images under Organisationens administration → Säkerhet › Fynd › Container-images och i Findings API. Avfärdanden följer med när imagen skannas om. - Blockeringsåtgärd.
block_pullgäller även images via proxyn: en pull genom proxyn av en image med ett fynd på high eller critical som inte har avfärdats nekas med403 DENIED. - Skadliga paket. Språkpaketen i en cachad image matchas mot OSV:s advisories om skadliga paket, precis som för pushade images, och en träff blir ett fynd på fliken Skadlig kod. Sedan 2026-10-11 nekas en pull av en cachad image med ett öppet fynd, precis som för en pushad image; se Beroendeproxy.
- Delade skanningar. En image identifieras av sin digest, så när flera organisationer cachar samma image skannas den en gång, och varje organisation får sin egen kopia av fynden. Du ser bara fynd för images i din egen cache.
- När en image lämnar din cache. Dess fynd finns kvar så länge imagen fortfarande används: hämtad genom proxyn av din organisation, eller angiven i någon av dina driftsättningar, under de senaste 30 dagarna (åtkomstloggen för registryt och driftsättningsposterna visar vilka). Därefter tas de bort vid nästa genomsökning. En image som hämtas igen efter att dess fynd har tagits bort får tillbaka dem vid nästa genomsökning, från skanningen av dess digest.
Images som dina Helm-charts driftsätter
De images som ett Helm-chart i ditt repo driftsätter skannas efter sårbarheter, och fynden rapporteras i repots kontroll fremforge/image-scan.
- Vad som läses. Varje chart i repot, det vill säga varje katalog med en
Chart.yaml. Ivalues.yaml: enimage:med en referens (image: nginx:1.25.3), och den uppdelade form som charts oftast använder (image:medregistry,repository,tagochdigestunder sig). En uppdelad image utan tagg, eller medtag: "", är chartetsappVersion, vilket är vad{{ .Values.image.tag | default .Chart.AppVersion }}driftsätter. Itemplates/: enimage:-rad med en literal referens. Nycklar sominitImageellersidecarImageräknas också;imagePullPolicyochimagePullSecretsgör det inte. - Vad som inte läses. Mallar renderas inte och ingen chart-kod körs, så en image som sätts ihop av mallogik, andra values-filer än
values.yaml(en overlay du väljer vid installationen) och beroende charts som inte finns i repot täcks inte. En referens utan registry är Docker Hub (nginxärdocker.io/library/nginx), och en utan tagg ärlatest. - Hur imagen hämtas. Genom din organisations beroendeproxy, på samma sätt som en pull av dig skulle göras: dina inloggningsuppgifter för upstream, paketpolicy, skanning efter skadlig kod och cache gäller. Om din organisation inte har någon beroendeproxy hämtar fremforges egen proxy den, anonymt och bara från register som tillåter det (till exempel
ghcr.io,quay.io,registry.k8s.io). En image som din proxy nekar (till exempel en som din policy blockerar) skannas inte. Imagen för linux/amd64 skannas medtrivy image, efter sårbarheter. - Docker Hub kräver dina egna inloggningsuppgifter. Images från Docker Hub hämtas bara med din organisations egna inloggningsuppgifter för Docker Hub, aldrig anonymt och aldrig med ett fremforge-konto. Utan dem skannas inte en Docker Hub-image i ett chart: statusen
fremforge/image-scansäger det (“N Docker Hub image(s) in Helm charts not scanned: add your Docker Hub credential”), och Säkerhet › Fynd › Container-images listar imagerna med en länk för att lägga till inloggningsuppgifterna under Inloggningsuppgifter för upstream. Imagerna skannas när du har lagt till dem, från repots nästa skanning; fynd som skannats för en annan organisation visas aldrig för din. - När. En image köas första gången en skanning nämner den, och skannas normalt inom 15 till 30 minuter; dess fynd visas vid repots nästa skanning. En image som fortfarande nämns skannas igen med några dagars mellanrum, eftersom en tagg kan flyttas och nya advisories publiceras.
- Hur ett fynd ser ut. Målet är chart-filen och imagen, till exempel
charts/web/values.yaml: docker.io/library/nginx:1.19.0, med paketet, dess version och den åtgärdade versionen. Fynden går genom tröskeln och avfärdandena för image-skanningen, och en pull request blockeras bara av fynd som den själv lägger till.
Nyare taggar för upstream-images
En image som du hämtar från upstream har ingen egen Dockerfile som du kan åtgärda, så fremforge letar efter en nyare tagg som åtgärdar dess fynd. För varje cachad image med öppna fynd på high eller critical, högst en gång om dagen:
- Taggen du hämtade. Digesten matchas mot den tagg din organisation hämtade den med, via indexet för flera arkitekturer när det finns ett.
- Kandidaten. Det här är den nyaste taggen i samma serie, som har samma form och samma siffror utom den sista:
3.12.4-slimtill3.12.10-slim, eller16.4till16.10. Det är aldrig en annan major- eller minor-version, eftersom det är en migrering snarare än en åtgärd. En tagg utan en sådan serie, som3.12-slim,16ellerpg17, kontrolleras i stället för en ombyggnad: samma tagg, ombyggd upstream sedan du hämtade den. - Vad den åtgärdar. Kandidaten hämtas och skannas med samma skanner. Varje öppet fynd hos dig som kandidaten inte längre har räknas som åtgärdat.
Fyndet säger sedan något av följande:
| Visas | Betydelse |
|---|---|
Nyare tagg <tag> åtgärdar N av imagens fynd | Byt till den taggen. Öppna PR med <tag> öppnar pull requesten nedan |
Ombyggd upstream: hämta <tag> igen så åtgärdas N av imagens fynd | Samma tagg är nyare upstream. Hämta den igen; inget ändras i ditt repo om inte en referens fäster en digest |
| Upstream-image, ingen nyare åtgärdad tagg | Ingen tagg i samma serie, och ingen ombyggnad, har färre av de här fynden |
| Upstream-image: nyare taggar har inte kontrollerats än | Inte kontrollerad än, eller så är registryt inte ett som fremforge läser taggar från (Docker Hub, GHCR, Quay, MCR, ECR Public och registry.k8s.io är det) |
Samma sak finns i Findings API som upstream_update.
Pull requesten. Öppna PR med <tag>, eller POST /orgs/{org}/dependency-updates/security-fixes/image-ref-requests med image_finding_id, söker i din organisations repon efter referenser till imagen med den tagg du hämtade. Det omfattar docker compose-filer, Kubernetes-manifest, Helm-values med repository: och tag: på separata rader, och CI-posterna image: och container:, under vilket som helst av de namn imagen har:
frem.sh/<org>/dependency-proxy/docker.io/library/python:3.12.4-slimdocker.io/library/python:3.12.4-slimpython:3.12.4-slim
Varje repo som har en referens får en pull request med en säkerhetsfix som flyttar alla dess referenser. En fäst digest flyttas till kandidatens digest. Den har den vanliga branchen, etiketten, gränserna och merge-inställningen. En FROM i en Dockerfile ändras inte här: det är åtgärden för bas-imagen. När inget repo refererar till imagen öppnas ingenting, och fyndet fortsätter att visa den tagg som åtgärdar det. Upp till 60 repon och 400 YAML-filer läses per begäran.
Skanna från ditt eget arbetsflöde
Du kan också skanna i CI och skicka in resultaten. fremforges runner-image levereras med Trivy. Det här exemplet skannar repots filsystem (trivy fs — beroenden + läckta hemligheter) och IaC-konfigurationen (trivy config — Dockerfiles, Compose-filer), och skickar sedan fynden med POST:
- 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 behöver behörigheten findings:write.
Policyinställningar
Säkerhet › Policyer › Image-policyer innehåller de här inställningarna (fram till 2026-10-15 låg de under Fynd › Container-images):
- Aktiverad — när den är av svarar inläsningen
202 {accepted: 0, status: 'disabled'}(resultatet tolkas fortfarande, men kastas). Användbart för team före lansering som vill att skanningen körs men inte blockerar. - Blockeringsåtgärd —
none|warn|block_pull:none— sparar fynd, postar ingen commit-status. Bara upptäckt på byggsidan. Pulls kontrolleras inte.warn— sparar fynd, postar commit-statusensuccessmed en beskrivning som anger antalet. Merge av pull requests blockeras inte. Pulls kontrolleras men nekas aldrig: en pull somblock_pullskulle neka levereras och registreras somwould_blocki åtkomstloggen för registry och som granskningshändelsenregistry.pull.would_block(se Granskningslogg och SIEM).block_pull— sparar fynd, postar commit-statusenfailurenär det finns minst ett fynd som inte har avfärdats på eller över din blockeringströskel. På en pull request räknas bara fynd som pull requesten inför (se Pull requests: bara nya fynd blockerar). Branch-skydd med den obligatoriska statuskontrollenfremforge/image-scanblockerar sedan merge. Den blockerar också pulls: endocker pull(med tagg eller digest) av en image med ett sådant fynd nekas med403 DENIED, och meddelandet anger tröskeln och länkar till fynden. Avfärda eller åtgärda fynden för att häva blockeringen. Varje nekande är granskningshändelsenregistry.pull.blocked.
- Kräv signerade images — när den är på tar inläsningen också emot fältet
signature_status(signed/unsigned/unknown). Osignerade images (eller signerade images från en utfärdare som inte finns på listan över tillåtna) får ett syntetiskt critical-fynd, så att samma väg för att blockera pull upprätthåller signeringspolicyn. Se Cosign för signeringssidan.
Blockeringströskel
De fynd som blockerar är de som ligger på eller över en allvarlighetsgrad, som ställs in per organisation. Det är block_severity i posten image_scan i din organisationsövergripande skanningspolicy, samma inställning för merge och för pulls:
block_severity | Blockerar vid |
|---|---|
critical | critical |
high (standard) | high och critical |
medium | medium, high och critical |
low | alla fynd |
Ställ in 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 konfiguration som kod som scan_policy = { image_scan = { mode = "enforce", block_severity = "critical" } }. null, eller ingen post image_scan, betyder high, vilket är vad alla organisationer hade innan tröskeln gick att ställa in. Alla andra värden avvisas med 400. Token behöver policy:write. Konsolen har ingen kontroll för det än.
Bara den organisationsövergripande posten räknas. En åsidosättning av skanningspolicyn per repo kan innehålla en block_severity, men en pull av en image är inte knuten till ett repo, så image-spärrarna läser den inte.
Pull requests: bara nya fynd blockerar
Kontrollen fremforge/image-scan på en pull request underkänns bara av fynd som pull requesten inför. fremforge jämför pull requestens fynd på eller över din blockeringströskel med den senaste skanningen av den branch som den mergas in i. Ett fynd som den branchen redan har blockerar inte, så en pull request som inte ändrar något sårbart kan mergas i ett repo som har öppna fynd. Statusen lyder då till exempel No new high/critical findings; 7 already on main.
- Ett fynd är detsamma när dess advisory, dess paket och dess fil är desamma, den identitet som ett avfärdande följer med på. Samma advisory i en annan fil är ett nytt fynd.
- En pull request som lägger till ett nytt fynd på high i ett repo med många befintliga underkänns: 1 new high/critical finding(s) …; merge blocked; 30 already on main.
- En pull request som åtgärdar några fynd och inte lägger till några godkänns.
- Befintliga fynd döljs inte. De listas, räknas mot din SLA och spärrar pulls av images som tidigare.
Branchen skannas efter en push till din standardbranch, högst en gång i timmen, och den senaste pushen vinner. Ett fynd som har nått branchen sedan dess senaste skanning räknas därför fortfarande som pull requestens fram till nästa skanning. Det är aldrig tvärtom: ett nytt fynd tas aldrig för ett befintligt.
När det inte finns någon skanning av den branch som pull requesten mergas in i blockerar alla fynd på eller över tröskeln, som tidigare. För standardbranchen begär den pull requestens skanning också en skanning av branchen. När branchens första skanning har registrerats skannar fremforge, av sig själv, om de öppna pull requests mot den vars kontroll underkändes under tiden (högst 20 per repo, de senast uppdaterade), så att de blir gröna, eller förblir röda bara för det de lägger till, utan en ny körning eller en ny push. En pull request mot någon annan branch räknar alltid alla fynd.
Spärren för pull av images är oförändrad: en pull av en image med ett fynd som inte har avfärdats på eller över tröskeln nekas under block_pull, oavsett om fyndet är nytt eller inte.
Granskningslogg och SIEM
Varje pull-beslut från image-spärrarna skrivs till din granskningslogg och därifrån till ditt SIEM:
registry.pull.blocked— en pull nekades: avblock_pull(spärrenimage_scan), av matchning mot skadlig kod (image_malware), av ett lager som ClamAV fann infekterat eller inte kunde skanna (registry_scan, ellerregistry_blobför ett lager som hämtats direkt via digest), eller av kontrollen av image-signaturer (signature).registry.pull.would_block— en pull levererades som någon av de spärrarna skulle ha nekat: under dinwarn, eller medan en spärr körs i observationsläge.
Det finns en händelse per image-digest, spärr och beslut per timme; nästa händelse för samma digest bär föregående timmes antal.
Var fynden visas
Organisationens administration → Säkerhet › Fynd › Container-images listar skanningar efter image-referens + commit + PR. Varje rad visar:
- Antal per allvarlighetsgrad (critical / high / medium / low)
- Antal som går att åtgärda (fynd med en
fixed_versionsom inte är null) - Status (
success/failure/skipped) + den commit-status som postades - Länkar till advisories upstream (CVE, GHSA när den finns)
Hur ett fynd ser ut i databasen
Fält som sparas per fynd: cve_id, severity, package, installed_version, fixed_version, target (filsökvägen i imagen) och det scan_run_id som knyter ihop fynd från samma körning. Hela Trivy-utdata sparas INTE — bara raderna per fynd, vilket är den form som går att fråga mot.
Lagringstid
Fynd följer tenantens policy för lagringstid i granskningsloggen. Fynd som har passerat lagringstiden behåller sin hash i kedjan (manipuleringsskydd) men förlorar innehållet per rad.
Se även
- Skadliga paket — samma pull av imagen matchas också mot OSV:s
MAL-*-advisories; en pull av en image med ett öppet fynd nekas oavsett blockeringsåtgärden ovan. - Cosign — signering av images + policy för signerade images.
- SBOM:er — paketinventering i imagen (oberoende av sårbarhetsläget).
- OSV-rekommendationer — komplementet på källsidan (sårbarheter i dina beroenden innan de levereras).
- API-referens — inläsningsendpointen
POST /_app/api/v1/image-scans/findings(avgränsad per tenant via runnerns PAT).