Bezpieczeństwo łańcucha dostaw 2026: SBOM, Sigstore cosign, Syft i Grype na Linuksie

Generowanie SBOM z Syft, skan CVE w Grype, keyless podpisy Sigstore cosign i atestacje SLSA w GitHub Actions oraz GitLab CI. Pełny pipeline supply chain w 2026.

SBOM Sigstore Cosign Syft Grype 2026

Aktualizacja: 28 czerwca 2026

Bezpieczeństwo łańcucha dostaw oprogramowania to praktyka weryfikowania, podpisywania i śledzenia każdego komponentu (od kodu źródłowego, przez zależności, aż po obrazy kontenerów), tak aby na produkcję trafiały wyłącznie artefakty o znanym pochodzeniu i pełnej liście składników (SBOM). W 2026 roku, po incydentach typu xz-utils backdoor i kolejnych falach typosquatów w npm i PyPI, generowanie SBOM przez Syft, skanowanie podatności w Grype oraz keyless-podpisywanie obrazów w Sigstore cosign stało się minimum higieny dla każdego zespołu DevSecOps na Linuksie.

Szczerze? Jeszcze trzy lata temu większość pipeline'ów, jakie widziałem na audytach, kończyła się na "docker push". Dziś to już naprawdę nie wystarcza.

  • SBOM (SPDX 3.0 lub CycloneDX 1.6) jest wymagany przez wykonawcze rozporządzenie USA 14028 oraz unijny Cyber Resilience Act, który wchodzi w życie 11 grudnia 2027.
  • Syft 1.x generuje SBOM dla obrazów OCI, archiwów i katalogów w jednej komendzie; Grype korzysta z tego samego pliku do skanu CVE bez ponownego rozpakowywania warstw.
  • Sigstore cosign 2.x oferuje podpis „keyless" przez OIDC: krótkotrwałe certyfikaty Fulcio i wpis do publicznego rejestru Rekor, bez utrzymywania prywatnych kluczy w sekretach CI.
  • SLSA v1.0 definiuje cztery poziomy dojrzałości (Build L1–L3 plus Source); poziom 3 wymaga izolowanego buildera i nieusuwalnego provenance.
  • Atestacje in-toto wiążą SBOM, wyniki SAST i provenance z konkretnym digestem obrazu, a politykami w admission controllerze (Kyverno, Connaisseur) weryfikujesz je przed dopuszczeniem do klastra.
  • W 2026 GitHub Actions ma natywne wsparcie attestations, a GitLab CI od 17.0 oferuje wbudowany Sigstore signing; integracja zajmuje kilkanaście linii YAML.

Czym jest bezpieczeństwo łańcucha dostaw oprogramowania?

W moim doświadczeniu z audytami DevSecOps trzy lata po SolarWinds wciąż spotykam zespoły, które dostarczają obraz kontenera na produkcję, nie wiedząc, jakie biblioteki w nim siedzą ani kto faktycznie zbudował binarkę. Bezpieczeństwo łańcucha dostaw (ang. software supply chain security) to dyscyplina, która zamyka tę lukę: każdy artefakt ma manifest składników (SBOM), kryptograficzny podpis pochodzenia (provenance), wynik skanu podatności i, opcjonalnie, atestację SLSA opisującą warunki buildu.

Po backdoorze w xz-utils (CVE-2024-3094) i serii ataków typosquatu w PyPI w 2025, regulatorzy zareagowali. Amerykański Executive Order 14028 wymaga SBOM dla dostawców federalnych, a unijny Cyber Resilience Act (CRA), z pełnym egzekwowaniem od 11 grudnia 2027, narzuca wymóg dokumentowania komponentów na każdy produkt z elementem cyfrowym sprzedawany na rynku UE. W praktyce oznacza to tyle, że jeśli budujesz cokolwiek na Linuksie z myślą o klientach europejskich, SBOM przestaje być „nice to have". Jeśli dopiero porządkujesz fundamenty, zacznij od wpisu o hartowaniu jądra Linux, a potem wróć tutaj.

SBOM w praktyce: SPDX vs CycloneDX

SBOM (Software Bill of Materials) to maszynowo czytelny manifest wszystkich komponentów wchodzących w skład artefaktu: bibliotek, pakietów systemowych, plików licencji, hashy. Dwa formaty dominują rynek i oba są wspierane przez większość narzędzi.

CechaSPDX 3.0CycloneDX 1.6
MecenasLinux FoundationOWASP
Standard ISOISO/IEC 5962:2021ECMA-424 (2024)
Formaty serializacjiJSON-LD, RDF, YAML, tag-valueJSON, XML, Protobuf
Wsparcie atestacjiProfile (Build, Security)VEX, BOM-Link, ML-BOM
Preferowany wŚrodowiskach federalnych (USA)Pipeline'ach DevSecOps, narzędziach OWASP
Czytelność dla człowiekaŚrednia (bardzo formalny)Wysoka (zwięzły JSON)
Wbudowane VEXNie (osobny dokument CSAF)Tak (od 1.4)

W praktyce wybierajcie SPDX, jeśli musicie zapewnić zgodność z NTIA Minimum Elements i kontraktami rządowymi USA. W pozostałych przypadkach CycloneDX jest bardziej zwarty i ma natywne wsparcie dla VEX (Vulnerability Exploitability eXchange), który pozwala oznaczyć fałszywie pozytywne CVE bezpośrednio w SBOM-ie. Syft generuje oba formaty z tej samej komendy, więc wybór to flaga, a nie projekt migracyjny.

Generowanie SBOM z Syft krok po kroku

Syft od Anchore to obecnie de facto standard generowania SBOM na Linuksie. Instalacja na systemie z apt-em wymaga jednego skryptu, ale w pipeline lepiej pobrać konkretną wersję z weryfikacją sumy kontrolnej (to akurat lekcja, której nauczyłem się boleśnie, kiedy upstream zmienił domyślny format wyjścia między wersjami minor).

# Instalacja Syft 1.18 z weryfikacją checksum (przykład pinning w CI)
SYFT_VERSION="1.18.1"
curl -sSfL "https://raw.githubusercontent.com/anchore/syft/main/install.sh" \
  | sh -s -- -b /usr/local/bin "v${SYFT_VERSION}"

syft version
# syft 1.18.1

Generowanie SBOM dla obrazu kontenera w formacie CycloneDX JSON, gotowego do attachu jako artefakt OCI:

# SBOM z lokalnego obrazu Docker
syft registry.example.com/api:1.4.2 \
  --output cyclonedx-json=sbom.cdx.json \
  --source-name api \
  --source-version 1.4.2

# To samo z katalogu źródłowego (przed budowaniem obrazu)
syft dir:./src \
  --output spdx-json=sbom.spdx.json \
  --exclude '**/node_modules/.cache/**'

# Multi-format: jednocześnie SPDX i CycloneDX
syft my-image:latest \
  -o spdx-json=sbom.spdx.json \
  -o cyclonedx-json=sbom.cdx.json \
  -o table  # czytelne dla człowieka w logach

Syft 1.18 wykrywa pakiety z ponad 30 ekosystemów: APK, DEB, RPM, npm, PyPI (włącznie z poetry.lock i uv.lock), Cargo, Go modules, Maven, NuGet, RubyGems, a od wersji 1.16 również composer.lock, R packages i Swift Package Manager. Dla projektów wielomodułowych warto użyć --scope all-layers, aby uwzględnić zależności usuwane w warstwach pośrednich obrazu (często to właśnie tam ukrywa się stara libssl).

Skanowanie podatności z Grype i Trivy

Mając SBOM, skanowanie CVE jest natychmiastowe. Grype nie musi ponownie eksplorować obrazu. Bazę podatności Grype czerpie z OSV, NVD, GitHub Security Advisory i feedów dystrybucji (Debian, RHEL, Alpine, Wolfi). Trivy z Aqua Security to bezpośredni konkurent z bardziej rozbudowanym katalogiem typu „misconfig + secret + license".

# Skan SBOM-u zamiast obrazu: szybkie, deterministyczne
grype sbom:./sbom.cdx.json \
  --fail-on high \
  --output table \
  --add-cpes-if-none

# Ten sam SBOM, ale wynik w SARIF do uploadu do GitHub Code Scanning
grype sbom:./sbom.cdx.json \
  --output sarif > grype-results.sarif

# Wykluczenia (np. CVE bez patcha, oznaczone VEX-em)
cat > .grype.yaml <<'EOF'
ignore:
  - vulnerability: CVE-2024-12345
    reason: "Podatność dotyczy ścieżki kodu wyłączonej w naszej konfiguracji (VEX not_affected)"
    fix-state: not-fixed
EOF

Krótkie porównanie obu skanerów po roku produkcji u klientów, którym pomagałem migrować na pipeline 2026:

AspektGrype 0.85Trivy 0.58
WejścieObraz, dir, SBOM, archiwumObraz, dir, SBOM, repo Git, IaC
Misconfig (Dockerfile, K8s)Nie (osobne narzędzie)Tak (wbudowane)
Skan sekretówNieTak
Aktualizacja bazy~6 h, lokalna~6 h, lokalna lub serwer
Wsparcie VEXTak (CycloneDX, OpenVEX)Tak (CycloneDX, CSAF, OpenVEX)
Air-gappedTak (offline DB)Tak (offline DB)

Jeśli macie już wdrożone audyt podatności Linuksa z Lynis i OpenSCAP, Grype/Trivy uzupełnia tę warstwę o skanowanie artefaktów buildu. Host kontra workload, niezależne pipeline'y.

Jak działa podpisywanie obrazów w Sigstore cosign?

Sigstore to projekt OpenSSF (Linux Foundation), który dostarcza trzy komponenty: Fulcio (krótkotrwałe certyfikaty X.509 wystawiane na podstawie OIDC), Rekor (publiczny, append-only rejestr transparentności) oraz cosign (CLI klienta). „Keyless" podpis oznacza, że nie generujesz pary kluczy. Cosign autoryzuje się tokenem OIDC (GitHub Actions, GitLab CI, Buildkite, twój IdP), Fulcio wystawia certyfikat ważny 10 minut, podpis ląduje w Rekor, i tyle.

# Instalacja cosign 2.4 z weryfikacją podpisu
COSIGN_VERSION="2.4.1"
curl -sSfL "https://github.com/sigstore/cosign/releases/download/v${COSIGN_VERSION}/cosign-linux-amd64" \
  -o /usr/local/bin/cosign
chmod +x /usr/local/bin/cosign

# Keyless signing w GitHub Actions (zmienna $GITHUB_TOKEN dostępna automatycznie)
cosign sign --yes registry.example.com/api@sha256:abc123...

# Weryfikacja podpisu i tożsamości buildera
cosign verify registry.example.com/api@sha256:abc123... \
  --certificate-identity-regexp "https://github.com/myorg/.+" \
  --certificate-oidc-issuer "https://token.actions.githubusercontent.com"

# Atestacja: dołącz SBOM jako podpisany artefakt
cosign attest --yes \
  --predicate sbom.cdx.json \
  --type cyclonedx \
  registry.example.com/api@sha256:abc123...

Tradycyjny model z prywatnym kluczem GPG/PGP w sekretach CI ma trzy problemy: klucz może wyciec, klucz nie ma daty ważności, i nikt nie wie, kto faktycznie go użył. Keyless rozwiązuje wszystkie trzy. Certyfikat żyje 10 minut, identyfikator OIDC jest wpisany w certyfikat (np. https://github.com/myorg/api/.github/workflows/release.yml@refs/tags/v1.4.2), a wpis Rekor jest niemodyfikowalny. Auditor zobaczy nie tylko, że artefakt jest podpisany, ale dokładnie który workflow i z którego commita go zbudował.

Co to jest SLSA i jakie są poziomy?

SLSA (Supply-chain Levels for Software Artifacts, wymawiane „salsa") to framework od OpenSSF opisujący stopień dojrzałości procesu buildu. Wersja 1.0 z 2023 (z aktualizacjami do 2025) definiuje cztery poziomy w torze „Build" plus osobny tor „Source" i „Distribution" w przygotowaniu.

  • Build L1: build jest skryptowy, generuje provenance (kto, gdzie, jak). To po prostu uruchomienie GitHub Actions lub GitLab CI z actions/attest-build-provenance.
  • Build L2: build odbywa się na hostowanej platformie, która sama generuje provenance (nie da się jej sfałszować z poziomu workflow). GitHub-hosted runners spełniają L2 dla większości zastosowań.
  • Build L3: builder jest izolowany (każdy job w świeżej VM), provenance niepodrabiane nawet przez kompromitację kodu buildowanego. Pełne L3 wymaga slsa-github-generator lub Tekton Chains z izolacją.
  • Build L4 (planowany w v1.1): dwustronna weryfikacja, hermetyczny build, reprodukowalność bit-po-bicie.

Dla większości zespołów cel realistyczny w 2026 to L2 (out-of-the-box w GitHub i GitLab) z provenance dołączonym jako atestacja in-toto. L3 to inwestycja sensowna dla bibliotek dystrybuowanych szeroko (przykład: pakiety w PyPI z trusted publishing) i obrazów bazowych. Provenance powstałe na L2+ zawiera materiały wejściowe (źródła, lock-files), środowisko (runner, Dockerfile, polecenie buildu) oraz subject (digest obrazu), i to wszystko podpisane jako atestacja in-toto.

Atestacje in-toto i polityki dopuszczenia

in-toto to standard atestacji rozwijany przez Linux Foundation: podpisany dokument JSON łączący subject (digest artefaktu) z predicate (dowolna informacja, np. SBOM, wynik SAST, provenance, opinia o jakości). Cosign używa go pod spodem; admission controllery weryfikują te atestacje przed dopuszczeniem obrazu do klastra.

# Polityka Kyverno: dopuszczamy tylko obrazy z atestacją SBOM i provenance SLSA
apiVersion: kyverno.io/v2
kind: ClusterPolicy
metadata:
  name: require-sbom-and-slsa
spec:
  validationFailureAction: Enforce
  webhookConfiguration:
    failurePolicy: Fail
  rules:
  - name: verify-attestations
    match:
      any:
      - resources:
          kinds: [Pod]
    verifyImages:
    - imageReferences: ["registry.example.com/*"]
      attestations:
      - type: https://cyclonedx.org/bom
        attestors:
        - entries:
          - keyless:
              subject: "https://github.com/myorg/*"
              issuer: "https://token.actions.githubusercontent.com"
      - type: https://slsa.dev/provenance/v1
        attestors:
        - entries:
          - keyless:
              subject: "https://github.com/myorg/*"
              issuer: "https://token.actions.githubusercontent.com"
        conditions:
        - all:
          - key: "{{ predicate.buildDefinition.buildType }}"
            operator: Equals
            value: "https://actions.github.io/buildtypes/workflow/v1"

Ten model („nic bez podpisu nie wjedzie na klaster") jest logicznym następnikiem wczesnych mechanizmów takich jak runtime detection Falco i Tetragon. Tam wykrywaliśmy złe zachowanie po fakcie; tu blokujemy złe artefakty przed uruchomieniem. W praktyce wdrożenie zaczynamy w trybie Audit (logujemy naruszenia, nic nie blokujemy), zbieramy listę legacy obrazów bez podpisu, i dopiero po wyzerowaniu tej listy przełączamy na Enforce. Honestly, ten jeden trick uratował mi co najmniej dwa weekendy.

Pełny pipeline w GitHub Actions i GitLab CI

GitHub Actions: minimalny supply chain

# .github/workflows/release.yml
name: build-sign-attest
on:
  push:
    tags: ['v*']

permissions:
  contents: read
  packages: write
  id-token: write     # OIDC do Sigstore
  attestations: write # Natywne attestations GitHub

jobs:
  release:
    runs-on: ubuntu-24.04
    steps:
      - uses: actions/checkout@v5

      - name: Build i push obrazu
        id: build
        uses: docker/build-push-action@v6
        with:
          push: true
          tags: ghcr.io/${{ github.repository }}:${{ github.ref_name }}

      - name: Generuj SBOM
        uses: anchore/sbom-action@v0
        with:
          image: ghcr.io/${{ github.repository }}@${{ steps.build.outputs.digest }}
          format: cyclonedx-json
          output-file: sbom.cdx.json

      - name: Skan podatności
        uses: anchore/scan-action@v5
        with:
          sbom: sbom.cdx.json
          fail-build: true
          severity-cutoff: high

      - name: Podpis keyless cosign
        env:
          IMAGE: ghcr.io/${{ github.repository }}@${{ steps.build.outputs.digest }}
        run: |
          cosign sign --yes "$IMAGE"
          cosign attest --yes --predicate sbom.cdx.json --type cyclonedx "$IMAGE"

      - name: SLSA build provenance
        uses: actions/attest-build-provenance@v2
        with:
          subject-name: ghcr.io/${{ github.repository }}
          subject-digest: ${{ steps.build.outputs.digest }}
          push-to-registry: true

GitLab CI 17.5+

# .gitlab-ci.yml
stages: [build, scan, sign]

variables:
  IMAGE: $CI_REGISTRY_IMAGE:$CI_COMMIT_TAG

build:
  stage: build
  image: docker:27
  services: [docker:27-dind]
  script:
    - docker build -t $IMAGE .
    - docker push $IMAGE
    - docker inspect --format='{{index .RepoDigests 0}}' $IMAGE > digest.txt
  artifacts:
    paths: [digest.txt]

sbom-scan:
  stage: scan
  image: anchore/syft:v1.18.1
  script:
    - DIGEST=$(cat digest.txt)
    - syft "$DIGEST" -o cyclonedx-json=sbom.cdx.json
    - grype sbom:./sbom.cdx.json --fail-on high
  artifacts:
    paths: [sbom.cdx.json]
    reports:
      cyclonedx: sbom.cdx.json

sign:
  stage: sign
  image: gcr.io/projectsigstore/cosign:v2.4.1
  id_tokens:
    SIGSTORE_ID_TOKEN:
      aud: sigstore
  script:
    - DIGEST=$(cat digest.txt)
    - cosign sign --yes "$DIGEST"
    - cosign attest --yes --predicate sbom.cdx.json --type cyclonedx "$DIGEST"

Oba pipeline'y mieszczą się w 50 liniach YAML i dają wam: SBOM jako artefakt CI, skan podatności blokujący wydanie przy High/Critical, podpis keyless oraz atestacje gotowe do weryfikacji w Kyverno. Czas wykonania? Mniej więcej 30–90 sekund overhead na typowy obraz aplikacyjny, czyli w mojej praktyce mniej niż czas oczekiwania na slot runnera.

Częste błędy i jak ich unikać

Pięć grzechów, które najczęściej widzę w audytach:

  1. Tag zamiast digestu w polityce weryfikacji. my-image:latest może wskazywać na inny artefakt jutro. Zawsze pinujcie po @sha256:... i weryfikujcie podpis przy digestzie, nie tagu.
  2. SBOM generowane z katalogu źródłowego zamiast obrazu. Tracicie pakiety systemowe (apk, deb), które weszły z bazy. Generujcie SBOM z obrazu OCI po buildzie.
  3. Brak polityki w admission controllerze. Podpisywanie bez weryfikacji daje 0% bezpieczeństwa. Produkcja musi blokować niepodpisane obrazy (Kyverno, Connaisseur, Gatekeeper z Cosigned).
  4. Ignore-listy bez wygasania. Dodajecie CVE-2024-12345: ignore i o nim zapominacie. Wymagajcie pola expires w VEX-ie i przeglądu kwartalnego.
  5. Brak weryfikacji --certificate-identity. Sam fakt, że artefakt jest podpisany czymkolwiek, nie znaczy nic. Musicie określić, że podpisał go wasz workflow (regex po certificate-identity i oidc-issuer).

Łańcuch dostaw nie jest projektem „raz wdrożymy i koniec". To ciągła praca z politykami, listami zignorowanych CVE i rotacją zaufanych issuerów. Ale nakład 2–3 dni inżyniera na pierwsze wdrożenie zwraca się przy pierwszym audycie SOC 2, ISO 27001 lub CRA, a także przy pierwszym incydencie, kiedy w 5 minut odpowiecie auditorowi, czy waszą produkcję dotknęło CVE z dzisiejszego rana.

Najczęściej zadawane pytania

Czy SBOM jest wymagany prawnie w UE?

Tak. Unijny Cyber Resilience Act (Rozporządzenie 2024/2847) wchodzi w pełną egzekwowalność 11 grudnia 2027 i wymaga dokumentowania komponentów software'owych każdego „produktu z elementem cyfrowym" sprzedawanego w UE. SBOM w formacie SPDX lub CycloneDX spełnia ten wymóg.

Czym różni się Sigstore cosign od podpisu GPG?

Cosign w trybie keyless używa krótkotrwałych (10 min) certyfikatów Fulcio wystawianych na podstawie tożsamości OIDC, a podpis jest wpisywany do publicznego, niemodyfikowalnego rejestru Rekor. GPG wymaga zarządzania długoterminowymi prywatnymi kluczami w sekretach CI, nie wskazuje na konkretny workflow, i nie ma rejestru transparentności.

Syft czy Trivy, które narzędzie wybrać?

Jeśli chcecie sam SBOM i osobny skaner, wybierzcie Syft plus Grype. Jeśli zależy wam na jednym narzędziu, które robi SBOM, skan CVE, wykrywa sekrety i misconfig (Dockerfile, K8s, Terraform), wybierzcie Trivy. W praktyce wiele zespołów uruchamia oba: Syft jako źródło SBOM-u dla atestacji, Trivy jako gate'a w PR.

Jaki poziom SLSA jest realistyczny dla małego zespołu?

SLSA Build L2 to standard out-of-the-box dla GitHub-hosted runners i GitLab Shared Runners. Wystarczy włączyć actions/attest-build-provenance lub odpowiednik w GitLab. L3 wymaga slsa-github-generator lub Tekton Chains z hermetycznym builderem; to inwestycja sensowna dla bibliotek dystrybuowanych publicznie, nie dla wewnętrznych mikroserwisów.

Czy mogę używać Sigstore w środowisku air-gapped?

Tak. Projekt sigstore-scaffolding dostarcza Helm chart, który pozwala uruchomić własną instancję Fulcio, Rekor i CTLog w klastrze Kubernetes. Alternatywą jest klasyczny podpis kluczem (cosign sign --key cosign.key); rezygnujecie wtedy z rejestru transparentności, ale zachowujecie spójność formatu i kompatybilność z politykami Kyverno.

O Autorze Editorial Team

Our team of expert writers and editors.