SBOM
Jak wygenerować SBOM w GitHub Actions
SBOM z pipeline'u GitHub Actions można uzyskać na cztery sposoby, a każdy opisuje co innego: repozytorium, pliki na dysku, podpisaną kopię jednego z nich lub to, co build faktycznie pobrał. Wybór zależy od tego, co SBOM ma udowodnić. Każdemu podejściu poniżej towarzyszy YAML lub polecenia do jego uruchomienia.
Zaktualizowano
Cztery podejścia
| Funkcja | Podejście | Co opisuje SBOM | Nakład pracy |
|---|---|---|---|
| Eksport grafu zależności | Graf GitHub | Manifesty i lockfile repozytorium, na gałęzi domyślnej | Żaden |
| Krok generatora | Syft, Trivy, cdxgen | Pliki lub obraz, które ma przed sobą w chwili wykonania kroku | Jeden krok na zadanie |
| Poświadczenie | actions/attest | Dowolny przekazany SBOM, podpisany i powiązany z artefaktem | Jeden krok po wygenerowaniu |
| Rejestrowanie w czasie buildu | CRACI | To, co zadanie pobrało w trakcie działania, ze stanem kompletności | Zmiana runs-on |
1. Eksport grafu zależności
GitHub buduje graf zależności z manifestów i lockfile w repozytorium i potrafi wyeksportować go jako SBOM w SPDX. Nie wymaga to zmiany workflow: należy otworzyć kartę Insights repozytorium, wybrać Dependency graph i kliknąć Export SBOM. Eksport opisuje repozytorium na gałęzi domyślnej, a nie konkretny build, więc nie ma w nim narzędzi i pakietów instalowanych przez workflow.
Do skryptów służy REST API. GET /repos/{owner}/{repo}/dependency-graph/sbom zwraca SPDX JSON w jednym wywołaniu, ale GitHub wyłącza je po 13 listopada 2026. Zastępcze rozwiązanie jest asynchroniczne: należy zażądać raportu, a następnie pobrać zwrócony sbom_url. Ten URL odpowiada kodem 202, dopóki SBOM jest generowany, a potem przekierowuje do pliku SPDX JSON, który GitHub przechowuje do tygodnia.
# Export the dependency graph as SPDX JSON (closing down after November 13, 2026)
curl -L \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer $GITHUB_TOKEN" \
-H "X-GitHub-Api-Version: 2026-03-10" \
https://api.github.com/repos/OWNER/REPO/dependency-graph/sbom
# The replacement: request a report; the response carries an sbom_url
curl -L \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer $GITHUB_TOKEN" \
-H "X-GitHub-Api-Version: 2026-03-10" \
https://api.github.com/repos/OWNER/REPO/dependency-graph/sbom/generate-report 2. Dodanie kroku generatora
Krok w workflow uruchamia generator na przestrzeni roboczej lub obrazie. anchore/sbom-action uruchamia Syft: domyślnie skanuje katalog przestrzeni roboczej i zwraca SPDX JSON, może zamiast tego skanować obraz kontenera, a SBOM przesyła jako artefakt workflow i dołącza do wydań. README akcji wymaga contents: write, a przy dołączaniu SBOM do wydania także actions: read:
name: sbom
on:
push:
branches: [main]
release:
types: [published]
jobs:
sbom:
runs-on: ubuntu-latest
permissions:
contents: write # upload the SBOM
actions: read # attach it to a release
steps:
- uses: actions/checkout@v7
- uses: actions/setup-node@v7
with:
node-version: 24
- run: npm ci
# Scan the workspace after the install step
- uses: anchore/sbom-action@v0
with:
path: .
format: cyclonedx-json format przyjmuje spdx, spdx-json, cyclonedx lub cyclonedx-json. Aby skanować obraz, należy zastąpić path przez image, na przykład image: ghcr.io/OWNER/app:1.0. Własne SBOM-y obrazów BuildKit opisuje strona Docker SBOM.
Trivy i cdxgen można uruchamiać w ten sam sposób, jako zwykłe kroki run. cdxgen zapisuje CycloneDX; od wersji 13 jego pakiet npm to @cdxgen/cdxgen:
steps:
- uses: actions/checkout@v7
- run: npm ci
- run: npm install -g @cdxgen/cdxgen --ignore-scripts
- run: cdxgen -o bom.json .
- uses: actions/upload-artifact@v7
with:
name: sbom
path: bom.json Moment ma znaczenie. Krok należy uruchomić po zainstalowaniu zależności, inaczej ich nie zobaczy. Nawet wtedy generator widzi tylko pliki, które ma przed sobą: może brakować pakietu, który skrypt pobrał, użył i usunął, lub narzędzia zainstalowanego poza menedżerem pakietów.
3. Podpisanie jako poświadczenie
Artifact attestations GitHub wiążą SBOM z opisywanym artefaktem i podpisują go za pomocą Sigstore. actions/attest@v4 przyjmuje SPDX lub CycloneDX JSON przez sbom-path, do 16 MB. Bez sbom-path wytwarza zamiast tego pochodzenie buildu SLSA. actions/attest-sbom jest wycofywana na rzecz actions/attest, którą teraz opakowuje. Zadanie potrzebuje id-token: write, aby otrzymać certyfikat podpisujący, oraz attestations: write, aby zapisać wynik:
jobs:
build:
runs-on: ubuntu-latest
permissions:
id-token: write # sign with a Sigstore certificate
contents: read
attestations: write # store the attestation
steps:
- uses: actions/checkout@v7
- run: make build # writes dist/my-app
- uses: anchore/sbom-action@v0
with:
path: .
format: spdx-json
output-file: sbom.spdx.json
upload-artifact: false
- uses: actions/attest@v4
with:
subject-path: dist/my-app
sbom-path: sbom.spdx.json W przypadku obrazu kontenera należy przekazać subject-name i subject-digest zamiast subject-path, ustawić push-to-registry: true i dodać packages: write. Artifact attestations działają w repozytoriach publicznych na każdym obecnym planie GitHub; repozytoria prywatne i wewnętrzne wymagają GitHub Enterprise Cloud.
GitHub CLI sprawdza następnie, kto wytworzył SBOM i dla którego artefaktu. Poświadczenia SBOM wymagają --predicate-type; dodanie --format json pokazuje sam SBOM. W przypadku obrazu zamiast ścieżki pliku należy użyć oci:// z nazwą obrazu.
gh attestation verify dist/my-app \
-R OWNER/REPO \
--predicate-type https://spdx.dev/Document/v2.3 Poświadczenie dowodzi, kto wytworzył SBOM i dla którego artefaktu. Nie czyni SBOM bardziej kompletnym.
4. Rejestrowanie w czasie buildu
CRACI rejestruje SBOM podczas działania zadania. Wystarczy zmienić runs-on na craci:
jobs:
build:
runs-on: craci # was: ubuntu-latest Proxy rozpoznające pakiety na runnerze rejestruje wtedy każdy pakiet pobrany przez zadanie, łącznie z pakietami przywróconymi z cache CI i ukrytymi zależnościami, których nie wymienia żaden lockfile, takimi jak kod pobierany przez skrypty instalacyjne. Nie ma kroku generatora do umieszczenia, więc pytanie o moment znika. Każdy SBOM, w CycloneDX lub SPDX, określa swoją kompletność dla każdego zadania i każdego cache, a API zwraca SBOM-y, ślady sieciowe i dane o pochodzeniu. Konfigurację, w tym GitHub App CRACI i ustawienia sieci, opisuje dokumentacja CRACI, a znaczenie każdego stanu kompletności wyjaśnia kompletność SBOM zadań i cache.
Które podejście wybrać
- Szybki inwentarz repozytorium: eksport grafu zależności.
- SBOM obrazu kontenera: krok generatora uruchomiony na obrazie.
- Dowód, kto wytworzył SBOM dla którego artefaktu: poświadczenie, oparte na jednym z powyższych.
- Zapis tego, czego build faktycznie użył, na potrzeby reagowania na podatności lub Cyber Resilience Act: rejestrowanie w czasie buildu. Zob. porównanie narzędzi SBOM.
SBOM-y w GitHub Actions: najczęściej zadawane pytania
Jak wygenerować SBOM w GitHub Actions?
Należy dodać krok generatora po kroku instalacji. Najkrótsza droga to anchore/sbom-action@v0, która uruchamia Syft na przestrzeni roboczej i przesyła SBOM SPDX JSON jako artefakt workflow. Aby otrzymać podpisany SBOM, należy przekazać plik do actions/attest@v4 przez sbom-path.
Czy GitHub generuje SBOM automatycznie?
GitHub potrafi wyeksportować graf zależności repozytorium jako SBOM w SPDX, z karty Insights lub przez REST API. Opisuje on manifesty i lockfile w repozytorium, a nie konkretny build, więc nie pokaże narzędzi ani pakietów pobieranych przez workflow.
Która akcja generuje SBOM w GitHub Actions?
anchore/sbom-action uruchamia Syft. Domyślnie skanuje katalog przestrzeni roboczej i zwraca SPDX JSON; może zamiast tego skanować obraz kontenera, przesyła SBOM jako artefakt workflow i dołącza go do wydań.
Jakich uprawnień potrzebuje workflow SBOM?
anchore/sbom-action wymaga contents: write, a do dołączenia SBOM do wydania także actions: read. Podpisywanie za pomocą actions/attest wymaga id-token: write i attestations: write, a gdy poświadczenie trafia do rejestru kontenerów, także packages: write.
Jak podpisać SBOM w GitHub Actions?
Należy użyć artifact attestations GitHub. actions/attest podpisuje SBOM SPDX lub CycloneDX JSON za pomocą Sigstore i wiąże go z artefaktem; weryfikację wykonuje gh attestation verify. actions/attest-sbom jest wycofywana na rzecz actions/attest, którą teraz opakowuje.
Jak wygenerować SBOM obrazu kontenera w GitHub Actions?
Należy przekazać obraz do anchore/sbom-action przez wejście image zamiast path. Aby go podpisać, trzeba podać actions/attest nazwę i digest obrazu przez subject-name i subject-digest, ustawić push-to-registry: true i zweryfikować przez gh attestation verify oci://IMAGE.
Czy workflow powinien wytwarzać SPDX czy CycloneDX?
Ten, którego oczekuje narzędzie czytające SBOM. Eksport grafu zależności to tylko SPDX, a cdxgen zapisuje CycloneDX. anchore/sbom-action zapisuje oba, a actions/attest przyjmuje oba. Zob. CycloneDX czy SPDX.
Czy krok SBOM powinien działać przed buildem czy po nim?
Po zainstalowaniu zależności, inaczej je pominie. Nawet wtedy widzi to, co jest na dysku, a nie to, co zadanie pobrało i usunęło ani co pobrał skrypt. Rejestrowanie w czasie buildu eliminuje pytanie o moment.
SBOM zarejestrowany z jednego z Państwa buildów
Proszę zmienić runs-on w jednym zadaniu, uruchomić je na CRACI i porównać zarejestrowany SBOM z tym, który tworzy Państwa obecny krok.
Umów demo