Forsyningskæde¶
Fra version 1.0.0 og fremefter bærer de container-images, Turbo EA publicerer til GHCR, verificerbare forsyningskæde-metadata, så operatører kan bekræfte, at et image kom fra dette projekts CI, før det trækkes ind i produktion.
Denne side dækker, hvad der er signeret, hvilken cosign-version du har brug for, hvordan du verificerer et image og Helm-chartet, hvor SBOM'en lever, og hvordan Trivy-porten passer ind.
Hvad er signeret¶
Hvert image bygget af .github/workflows/docker-publish.yml og pushet til ghcr.io/vincentmakes/turbo-ea/<image> er signeret med cosign ved hjælp af nøgleløs OIDC: der er ingen langtidsholdbar signeringsnøgle. Certifikatet udstedes af Sigstores Fulcio for workflow-identiteten (https://github.com/vincentmakes/turbo-ea/.github/workflows/docker-publish.yml@<ref>), registreres i den offentlige Rekor-transparenslog og kasseres, så snart signaturen er oprettet.
Signerede images:
ghcr.io/vincentmakes/turbo-ea/dbghcr.io/vincentmakes/turbo-ea/backendghcr.io/vincentmakes/turbo-ea/frontendghcr.io/vincentmakes/turbo-ea/nginxghcr.io/vincentmakes/turbo-ea/mcp-server
Helm-chartet, ghcr.io/vincentmakes/turbo-ea/charts/turbo-ea, signeres på samme måde af .github/workflows/helm-publish.yml ved hvert release-tag (identitet …/helm-publish.yml@<ref>).
Alle images, som docker-compose.yml henter fra GHCR, står på den liste. Den valgfrie Ollama-container gør ikke: siden 2.155.0 fastlåser docker-compose.yml direkte udgivelsestagget for upstream-imaget ollama/ollama, og Turbo EA hverken signerer eller scanner det image — verificér det med de midler, upstream stiller til rådighed. En patchet kopi, ghcr.io/vincentmakes/turbo-ea/ollama, findes kun for 2.154.0 til 2.154.2.
Signaturen gælder for OCI manifest list-digest, så en enkelt signatur dækker transparent både linux/amd64 og linux/arm64. Der er ingen per-platform-signatur at jagte.
Signaturformat og den cosign-version, du har brug for¶
Verificér med cosign 2.6 eller nyere, eller en hvilken som helst cosign 3.x. Ældre klienter — cosign 2.5 og derunder — rapporterer no signatures found for hvert image og chart publiceret siden 1.37.0, selvom signaturen er der.
Årsagen er en ændring af lagringsformatet, ikke af signeringen. Op til 1.36.0 kørte publicerings-workflowet cosign 2, som gemte signaturen under tagget sha256-<digest>.sig ved siden af imaget. Siden 1.37.0 (juni 2026, da cosign-installeren skiftede til cosign 3) er signaturen et Sigstore-bundle: en OCI 1.1-referrer til imaget. GHCR implementerer ikke referrers-API'et, så cosign gemmer bundlet under fallback-indekstagget sha256-<digest> — uden .sig-suffiks — hvilket er præcis det sted, en klient før 2.6 aldrig kigger. cosign tree viser, hvad der er vedhæftet et image:
cosign tree ghcr.io/vincentmakes/turbo-ea/backend:<version>
| Releases | Signaturformat | Verificeres med |
|---|---|---|
| 1.0.0 – 1.36.0 | ældre sha256-<digest>.sig-tag |
enhver cosign |
| 1.37.0 og senere, samt hvert Helm-chart | Sigstore-bundle (OCI-referrer) | cosign ≥ 2.6 eller 3.x |
Hver publicering verificerer nu sin egen signatur med cosign 2.6 — den ældste klient, denne side lover — før jobbet bliver grønt, så en fremtidig formatændring ville få CI til at fejle frem for dit deploy. Projektet udsender bevidst én enkelt signatur i det aktuelle Sigstore-format: hvis en admission controller eller policy-motor i dit cluster stadig kun læser det ældre tag, så opgradér den i stedet for at forvente en anden signatur.
Verifikation af et image¶
Installér cosign 2.6 eller nyere, derefter:
cosign verify \
--certificate-identity-regexp 'https://github.com/vincentmakes/turbo-ea/.+' \
--certificate-oidc-issuer 'https://token.actions.githubusercontent.com' \
ghcr.io/vincentmakes/turbo-ea/backend:<version>
Hvad flagene gør:
--certificate-identity-regexp— accepterer enhver workflow-sti inde i dette repo, så den samme kommando virker, uanset om imaget blev publiceret fradocker-publish.ymlpåmaineller på et tag. Hvis du vil være strengere, så erstat med--certificate-identity 'https://github.com/vincentmakes/turbo-ea/.github/workflows/docker-publish.yml@refs/tags/v<version>'.--certificate-oidc-issuer— pinner OIDC-issueren til GitHubs token-endpoint. En signatur udstedt af en hvilken som helst anden issuer (f.eks. en forks CI) vil fejle verifikation.
En vellykket verifikation udskriver den signerede payload og en post i Rekor-transparensloggen. En fejl afslutter med en ikke-nul exit-kode og en diagnostik — lad dit deploy fejle på den. Hvis diagnostikken er no signatures found, så tjek først cosign version: se afsnittet ovenfor.
Du kan også verificere efter digest, hvilket er den strengeste form (immun over for tag-remapping):
DIGEST=$(docker buildx imagetools inspect ghcr.io/vincentmakes/turbo-ea/backend:<version> --format '{{ .Manifest.Digest }}')
cosign verify \
--certificate-identity-regexp 'https://github.com/vincentmakes/turbo-ea/.+' \
--certificate-oidc-issuer 'https://token.actions.githubusercontent.com' \
ghcr.io/vincentmakes/turbo-ea/backend@${DIGEST}
Verifikation af Helm-chartet¶
Chartet er et OCI-artefakt i samme registry og verificeres med samme kommando:
cosign verify \
--certificate-identity-regexp 'https://github.com/vincentmakes/turbo-ea/.+' \
--certificate-oidc-issuer 'https://token.actions.githubusercontent.com' \
ghcr.io/vincentmakes/turbo-ea/charts/turbo-ea:<version>
Én undtagelse fra tag-identiteten: chart 2.141.0, den første chart-release, blev pushet men ikke signeret (dets signeringstrin fejlede på registry-autentificering) og blev signeret efterfølgende fra main-branchen, så dets certifikatidentitet er …/helm-publish.yml@refs/heads/main frem for en tag-reference. Det regulære udtryk ovenfor accepterer begge; en streng --certificate-identity skal for netop den version angive refs/heads/main.
SBOM¶
En SPDX software bill of materials genereres automatisk af buildkit (sbom: true på build-trinnet) og vedhæftes hvert image som en OCI-referrer. Der er intet ekstra at installere — den lever i registret sammen med imaget.
Træk den med:
docker buildx imagetools inspect --format '{{ json .SBOM }}' \
ghcr.io/vincentmakes/turbo-ea/backend:<version> | jq .
SBOM'en lister hver pakke, buildkit observerede i det endelige image (apk-pakker, Python-wheels, Node-moduler osv.) med versioner og kilde-URL'er. Nyttige input til din egen sårbarhedsscanner, licens-compliance-værktøj eller komponentlager.
Sårbarhedsscanning (Trivy)¶
Publicerings-workflowet kører Trivy mod hvert bygget image i to trin:
- Observér — HIGH- og CRITICAL-fund uploades som SARIF til repository'ets GitHub Security-faneblad. Dette trin får aldrig jobbet til at fejle.
- Port — ethvert CRITICAL-fund med en tilgængelig rettelse får publiceringen til at fejle, medmindre CVE'en står i
.github/trivy-allowlistmed en skriftlig begrundelse (hver post revurderes kvartalsvis og fjernes, så snart upstream udsender en patch).
De samme to trin køres dagligt igen mod de faktisk publicerede :latest-manifester, og et rettelsesbart HIGH- eller CRITICAL-fund på et publiceret image udløser en genopbygning mod friske Alpine-repositorier. HIGH-fund forbliver indtil videre kun under observation: baserne er alpine-baserede (python:3.12-alpine, postgres:18-alpine, nginx:alpine) og bærer regelmæssigt baseline-fund mod musl-libc og transitive apk-afhængigheder, som ingen kodesti i Turbo EA når, men som Trivy rapporterer alligevel.
Dynamisk scanning af den kørende stak. Én gang om ugen startes de udgivne :latest-images også med den uændrede docker-compose.yml og undersøges med OWASP ZAPs passive baseline-scanning, anonymt og logget ind som demo-administrator: svar-headers, cookie-flag, Content-Security-Policy og informationslæk på hver side og API-rute, som spideren når. Intet fuzzes. Accepterede advarsler står med begrundelse i .github/zap-rules.tsv; alt andet får kørslen til at fejle. Scanningen dækker stakken i dens standardform, ikke din reverse proxy, identitetsudbyder eller dit netværk — kør derfor din egen DAST mod din instans.
Til operatører: porten beskytter de publicerede images, men kør også din egen scanner mod det trukne image — din politik kan afvige fra vores. Den publicerede SBOM er et rent input.
Til bidragydere: hvis du opdager et fund, der faktisk kan udnyttes i en Turbo EA-anvendelsessti, så rapportér det venligst via en privat sikkerhedsmeddelelse i stedet for at kommentere i et offentligt issue. Se SECURITY.md.
Action SHA-pinning¶
Hver GitHub Action, der bruges af publicerings-workflowet, er pinnet til en 40-tegns commit-SHA, ikke et flydende major-tag. Det betyder, at en kompromitteret upstream-vedligeholder eller en typosquat ikke stille kan ændre, hvad der kører i vores CI, uden en synlig diff i dette repo. Opdateringer flyder gennem Dependabots github-actions-økosystem i en månedlig kadence, så opdateringer stadig sker — de går bare gennem review.