Tradycyjny model weryfikacji bezpieczeństwa opiera się na statycznych raportach — dokumentach PDF generowanych po audycie, przeglądach zgodności przeprowadzanych raz na kwartał, arkuszach kalkulacyjnych z checklistami kontroli. Ten model nie nadąża za rzeczywistością współczesnego wytwarzania oprogramowania, gdzie zespoły deployują dziesiątki razy dziennie, a łańcuch dostaw obejmuje setki zależności open source.
ENISA w swoim playbooku Security by Design and Default proponuje fundamentalną zmianę: przejście od dokumentowej zgodności do maszynowej weryfikacji. Machine-readable security attestations — atestacje bezpieczeństwa w formatach strukturalnych — pozwalają automatycznie generować, aktualizować i weryfikować dowody bezpieczeństwa w ramach pipeline CI/CD.
Problem ze statyczną zgodnością
Audyt raz na kwartał vs. deploy 50 razy dziennie
Organizacje podlegające regulacjom (NIS2, DORA, ISO 27001) muszą wykazać zgodność z wymaganiami bezpieczeństwa. Tradycyjnie oznacza to:
- Audytor przychodzi raz na rok lub kwartał
- Zespół przygotowuje dokumentację przez tygodnie
- Audytor weryfikuje stan na dzień audytu
- Raport PDF trafia na półkę
Między audytami system może przejść setki zmian. Każda z nich potencjalnie wpływa na stan bezpieczeństwa. Raport PDF z marca nie mówi nic o stanie systemu w czerwcu.
Rozproszona odpowiedzialność
W modelu DevOps odpowiedzialność za bezpieczeństwo jest rozproszona między zespoły deweloperskie, operacyjne i security. Każdy zespół używa innych narzędzi, generuje inne artefakty, stosuje inne procesy. Brak centralnego, maszynowego źródła prawdy o stanie bezpieczeństwa prowadzi do luk i niespójności.
Łańcuch dostaw — niewidoczne ryzyko
Współczesne aplikacje składają się w 70-90% z komponentów open source. Każda zależność to potencjalna podatność. Incydenty jak Log4Shell, SolarWinds czy event-stream pokazały, że kompromitacja jednego komponentu może mieć kaskadowy wpływ na tysiące organizacji. Statyczne raporty nie są w stanie śledzić tego dynamicznego krajobrazu zagrożeń.
Czym są machine-readable security attestations?
Atestacja bezpieczeństwa w formacie maszynowym to strukturalna deklaracja w formacie JSON, YAML lub innym formacie parserowalnym, która stwierdza, że określona kontrola bezpieczeństwa została wdrożona lub określony warunek został spełniony.
Kluczowe cechy
- Automatycznie generowane — powstają jako output narzędzi w pipeline CI/CD
- Automatycznie aktualizowane — każda zmiana w kodzie generuje nowy zestaw atestacji
- Automatycznie weryfikowalne — system deployment sprawdza atestacje przed dopuszczeniem releasu
- Podpisane kryptograficznie — nie można ich sfałszować ani zmodyfikować bez wykrycia
- Powiązane z artefaktem — atestacja jest jednoznacznie przypisana do konkretnej wersji buildu
Anatomia atestacji
Przykład atestacji w formacie in-toto:
{
"_type": "https://in-toto.io/Statement/v1",
"subject": [
{
"name": "app-server",
"digest": {
"sha256": "a1b2c3d4e5f6..."
}
}
],
"predicateType": "https://slsa.dev/provenance/v1",
"predicate": {
"buildDefinition": {
"buildType": "https://github.com/actions/runner",
"externalParameters": {
"workflow": ".github/workflows/build.yml",
"ref": "refs/tags/v2.1.0"
}
},
"runDetails": {
"builder": {
"id": "https://github.com/actions/runner/v2"
},
"metadata": {
"invocationId": "https://github.com/org/repo/actions/runs/123456",
"startedOn": "2026-04-09T10:00:00Z",
"finishedOn": "2026-04-09T10:15:00Z"
}
}
}
}
Ta atestacja stwierdza: artefakt app-server o określonym hashu został zbudowany przez GitHub Actions runner, z konkretnego workflow, z taga v2.1.0. Każdy element jest weryfikowalny.
Atestacja kontroli bezpieczeństwa
Oprócz provenance (pochodzenia), atestacje mogą potwierdzać wyniki kontroli bezpieczeństwa:
{
"_type": "https://in-toto.io/Statement/v1",
"subject": [
{
"name": "app-server",
"digest": { "sha256": "a1b2c3d4e5f6..." }
}
],
"predicateType": "https://example.com/security-scan/v1",
"predicate": {
"scanner": "trivy",
"scanType": "vulnerability",
"timestamp": "2026-04-09T10:12:00Z",
"results": {
"critical": 0,
"high": 0,
"medium": 3,
"low": 12
},
"policy": {
"maxCritical": 0,
"maxHigh": 0,
"result": "PASS"
}
}
}
SLSA Framework — poziomy zabezpieczeń łańcucha dostaw
Supply-chain Levels for Software Artifacts (SLSA, wymawiane „salsa”) to framework opracowany przez Google, który definiuje cztery poziomy zabezpieczeń łańcucha dostaw oprogramowania. Każdy poziom wymaga coraz bardziej rygorystycznych atestacji.
Poziomy SLSA
SLSA Level 1 — Provenance istnieje
- Dokumentacja procesu budowania
- Automatycznie generowana provenance (atestacja pochodzenia)
- Minimum: wiadomo, kto i jak zbudował artefakt
SLSA Level 2 — Hosted build
- Build wykonywany na hostowanej usłudze (nie lokalnie)
- Provenance generowana przez usługę budowania, nie przez dewelopera
- Autentyczność provenance weryfikowalna
SLSA Level 3 — Hardened builds
- Izolacja procesu budowania od dewelopera
- Provenance nie może być sfałszowana przez nikogo z dostępem do repozytorium
- Build jest hermetyczny — deterministic i reproducible
SLSA Level 4 — Dwuosobowa weryfikacja
- Wszystkie zmiany wymagają przeglądu przez dwie osoby
- Hermetyczny, reprodukowalny build
- Provenance zawiera kompletne drzewo zależności
Implementacja SLSA w GitHub Actions
name: SLSA Build
on:
push:
tags: ['v*']
jobs:
build:
runs-on: ubuntu-latest
permissions:
id-token: write
contents: read
attestations: write
steps:
- uses: actions/checkout@v4
- name: Build application
run: |
npm ci
npm run build
tar -czf dist.tar.gz dist/
- name: Generate SBOM
uses: anchore/sbom-action@v0
with:
artifact-name: sbom.spdx.json
output-file: sbom.spdx.json
- name: Scan vulnerabilities
uses: aquasecurity/trivy-action@master
with:
scan-type: 'fs'
format: 'json'
output: 'trivy-results.json'
exit-code: '1'
severity: 'CRITICAL,HIGH'
- name: Generate attestation
uses: actions/attest-build-provenance@v1
with:
subject-path: 'dist.tar.gz'
- name: Verify attestation
run: |
gh attestation verify dist.tar.gz \
--owner ${{ github.repository_owner }}
SBOM — Software Bill of Materials
SBOM to kompletna lista wszystkich komponentów oprogramowania — bibliotek, frameworków, narzędzi i ich wersji. W kontekście atestacji bezpieczeństwa, SBOM pełni rolę fundamentu — bez wiedzy o tym, z czego składa się oprogramowanie, nie można ocenić jego bezpieczeństwa.
Formaty SBOM
CycloneDX — format opracowany przez OWASP, zaprojektowany specjalnie dla bezpieczeństwa. Obsługuje nie tylko komponenty, ale też podatności, licencje i usługi.
{
"bomFormat": "CycloneDX",
"specVersion": "1.5",
"version": 1,
"metadata": {
"timestamp": "2026-04-09T10:00:00Z",
"component": {
"type": "application",
"name": "app-server",
"version": "2.1.0"
}
},
"components": [
{
"type": "library",
"name": "express",
"version": "4.18.2",
"purl": "pkg:npm/express@4.18.2",
"hashes": [
{
"alg": "SHA-256",
"content": "abc123..."
}
]
}
],
"vulnerabilities": [
{
"id": "CVE-2024-XXXXX",
"source": { "name": "NVD" },
"ratings": [
{ "severity": "medium", "score": 5.3 }
],
"affects": [
{ "ref": "pkg:npm/express@4.18.2" }
],
"analysis": {
"state": "not_affected",
"justification": "code_not_reachable"
}
}
]
}
SPDX — format Linux Foundation, szerzej stosowany w kontekście licencji open source, ale obsługujący też informacje o bezpieczeństwie.
Automatyczne generowanie SBOM
SBOM powinien być generowany automatycznie przy każdym buildzie:
# GitLab CI example
generate-sbom:
stage: security
image: anchore/syft:latest
script:
- syft dir:. -o cyclonedx-json > sbom.json
- grype sbom:sbom.json --fail-on high
artifacts:
paths:
- sbom.json
reports:
cyclonedx: sbom.json
In-toto — framework atestacji łańcucha dostaw
in-toto to framework opracowany przez NYU i NJIT, który definiuje standard atestacji dla całego łańcucha dostaw oprogramowania. Umożliwia definiowanie layoutu — opisu wszystkich kroków, które muszą być wykonane, przez kogo i w jakiej kolejności.
Architektura in-toto
Layout (definicja pipeline)
├── Step: code-review
│ ├── Expected command: git merge --verify-signatures
│ └── Required signer: reviewer-key
├── Step: build
│ ├── Expected command: npm run build
│ └── Required signer: ci-runner-key
├── Step: security-scan
│ ├── Expected command: trivy image ...
│ └── Required signer: ci-runner-key
└── Step: deploy-approval
├── Expected command: kubectl apply ...
└── Required signer: deployer-key
Każdy krok generuje link — podpisaną atestację potwierdzającą wykonanie. System weryfikujący sprawdza, czy wszystkie kroki zostały wykonane, przez właściwe osoby/systemy, w prawidłowej kolejności.
Integracja z pipeline
# GitHub Actions z in-toto
- name: Record build step
uses: in-toto/in-toto-run-action@v1
with:
step-name: build
signing-key: ${{ secrets.IN_TOTO_KEY }}
products: dist/
command: npm run build
- name: Record security scan
uses: in-toto/in-toto-run-action@v1
with:
step-name: security-scan
signing-key: ${{ secrets.IN_TOTO_KEY }}
materials: dist/
command: trivy fs --exit-code 1 --severity HIGH,CRITICAL dist/
Sigstore — podpisywanie i weryfikacja artefaktów
Sigstore to projekt Linux Foundation zapewniający infrastrukturę do podpisywania i weryfikacji artefaktów oprogramowania. Kluczowy komponent: cosign — narzędzie do podpisywania obrazów kontenerów i innych artefaktów.
Podpisywanie artefaktów
# Podpisanie obrazu kontenera
cosign sign --key cosign.key registry.example.com/app:v2.1.0
# Weryfikacja podpisu
cosign verify --key cosign.pub registry.example.com/app:v2.1.0
# Dołączenie atestacji do obrazu
cosign attest --predicate sbom.json \
--type cyclonedx \
--key cosign.key \
registry.example.com/app:v2.1.0
# Weryfikacja atestacji
cosign verify-attestation --type cyclonedx \
--key cosign.pub \
registry.example.com/app:v2.1.0
Keyless signing z Fulcio
Sigstore oferuje też keyless signing — podpisywanie bez zarządzania kluczami. Tożsamość sygnatariusza jest weryfikowana przez OIDC (np. konto GitHub), a dowód podpisu zapisywany w publicznym, immutable logu (Rekor).
# Keyless signing — tożsamość z OIDC
cosign sign --identity-token=$(gcloud auth print-identity-token) \
registry.example.com/app:v2.1.0
Automated gatekeeping — blokowanie niebezpiecznych releasów
Kluczowym elementem machine-readable attestations jest możliwość automatycznego blokowania releasów, które nie spełniają wymagań bezpieczeństwa.
Polityki admission w Kubernetes
# Kyverno policy — wymaga podpisanego obrazu i atestacji SBOM
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-signed-images
spec:
validationFailureAction: Enforce
rules:
- name: verify-signature
match:
any:
- resources:
kinds: ["Pod"]
verifyImages:
- imageReferences: ["registry.example.com/*"]
attestors:
- entries:
- keys:
publicKeys: |-
-----BEGIN PUBLIC KEY-----
...
-----END PUBLIC KEY-----
attestations:
- type: https://cyclonedx.org/bom/v1.5
conditions:
all:
- key: "{{ vulnerabilities[?ratings[?severity=='critical']] | length(@) }}"
operator: Equals
value: "0"
Release gates w CI/CD
# GitHub Actions — gate sprawdzający atestacje
release-gate:
needs: [build, security-scan, sbom-generation]
runs-on: ubuntu-latest
steps:
- name: Verify all attestations present
run: |
# Sprawdź provenance
gh attestation verify dist.tar.gz --owner $GITHUB_REPOSITORY_OWNER
# Sprawdź wyniki skanowania
CRITICAL=$(jq '.results.critical' trivy-results.json)
HIGH=$(jq '.results.high' trivy-results.json)
if [ "$CRITICAL" -gt 0 ] || [ "$HIGH" -gt 0 ]; then
echo "RELEASE BLOCKED: Found $CRITICAL critical, $HIGH high vulnerabilities"
exit 1
fi
# Sprawdź SBOM
if [ ! -f sbom.json ]; then
echo "RELEASE BLOCKED: SBOM not generated"
exit 1
fi
echo "All gates passed — release approved"
Playbooki ENISA jako living artifacts
ENISA projektuje swoje playbooki nie jako statyczne dokumenty, lecz jako żywe artefakty zintegrowane z procesem wytwarzania. Każdy playbook zawiera:
- Zasadę — np. „Wszystkie artefakty muszą mieć weryfikowalną provenance”
- Cel — np. „Zapewnienie integralności łańcucha dostaw”
- Checklist — konkretne kroki do wykonania
- Minimalne dowody — jakie atestacje muszą istnieć
- Bramkę release — kryteria pass/fail
Mapowanie playbooka na pipeline
Playbook: Supply Chain Integrity
├── Checklist item: SBOM generation
│ └── Pipeline stage: generate-sbom → artifact: sbom.json
├── Checklist item: Vulnerability scan
│ └── Pipeline stage: security-scan → artifact: trivy-results.json
├── Checklist item: Build provenance
│ └── Pipeline stage: build → attestation: slsa-provenance.json
├── Checklist item: Signature verification
│ └── Pipeline stage: sign → cosign signature
└── Release gate: ALL attestations present + no CRITICAL/HIGH vulns
└── Pipeline stage: release-gate → PASS/FAIL
Taka struktura pozwala na automatyczną weryfikację zgodności z playbooka ENISA przy każdym renderze pipeline — nie raz na kwartał podczas audytu.
Transparentność łańcucha dostaw
Machine-readable attestations rozwiązują fundamentalny problem zaufania w złożonych ekosystemach cyfrowych. Tworzą odporny na manipulację, ciągły zapis stanu bezpieczeństwa produktu — od pierwszej linii kodu po deployment w produkcji.
Automatyzacja relacji zaufania
Zamiast polegać na jednorazowych audytach dostawców, organizacje mogą wymagać ciągłych, weryfikowalnych atestacji. Dostawca komponentu dostarcza:
- SBOM swoich zależności
- Atestacje provenance (skąd pochodzi artefakt)
- Wyniki skanowania podatności
- Podpisy kryptograficzne potwierdzające integralność
Odbiorca może automatycznie weryfikować te atestacje przed włączeniem komponentu do swojego produktu — spełniając wymogi NIS2 dotyczące bezpieczeństwa łańcucha dostaw.
Ciągły widok ryzyka
Atestacje maszynowe umożliwiają stakeholderom dostęp do spójnego i aktualnego widoku ryzyka. Dashboard bezpieczeństwa może w czasie rzeczywistym pokazywać:
- Status atestacji dla każdego komponentu
- Pokrycie SBOM w łańcuchu dostaw
- Trendy podatności w czasie
- Zgodność z politykami bezpieczeństwa per release
Wdrożenie w organizacji — od czego zacząć
Krok 1: SBOM dla istniejących aplikacji
Zacznij od automatycznego generowania SBOM dla swoich aplikacji. Narzędzia jak Syft (Anchore), cdxgen (CycloneDX) czy trivy mogą wygenerować SBOM z istniejącego kodu bez modyfikacji pipeline.
Krok 2: Skanowanie podatności w zależnościach
Podłącz skaner podatności do SBOM — Grype, Trivy lub Dependency-Track. Ustaw alerty na nowe podatności w komponentach, których używasz.
Krok 3: Podpisywanie artefaktów
Wdróż cosign do podpisywania obrazów kontenerów lub artefaktów buildów. Zacznij od keyless signing z Sigstore — zero zarządzania kluczami.
Krok 4: Release gates
Dodaj automatyczne bramki bezpieczeństwa do pipeline — najpierw jako ostrzeżenia (soft fail), potem jako blokady (hard fail).
Krok 5: Polityki admission
Wdróż polityki w Kubernetes (Kyverno, OPA Gatekeeper) lub innym środowisku runtime, które wymagają ważnych atestacji przed deploymentem.
Podsumowanie
Machine-readable security attestations to nie futurystyczna wizja — to narzędzia dostępne dziś. SLSA, in-toto, Sigstore, CycloneDX — cały ekosystem jest otwartoźródłowy i gotowy do wdrożenia.
ENISA w swoim playbooku formalizuje to, co liderzy DevSecOps wdrażają od lat: bezpieczeństwo musi być weryfikowalne automatycznie, ciągle i maszynowo. Statyczne raporty PDF nie nadążają za tempem współczesnego developmentu. Atestacje maszynowe tak.
Kluczowe wnioski:
- Atestacje zastępują raporty — JSON/YAML zamiast PDF, ciągła weryfikacja zamiast punktowych audytów
- SLSA definiuje poziomy — od podstawowej provenance (L1) po hermetyczne, reprodukowalne buildy (L4)
- SBOM to fundament — bez wiedzy o komponentach nie ma bezpieczeństwa łańcucha dostaw
- Podpisywanie kryptograficzne zapewnia integralność i autentyczność
- Automated gatekeeping blokuje niebezpieczne releasy zanim dotrą do produkcji
- Playbooki ENISA mapują się bezpośrednio na etapy pipeline CI/CD
Potrzebujesz wsparcia we wdrożeniu atestacji bezpieczeństwa w swoim pipeline? Skontaktuj się z naszym zespołem — pomożemy zaprojektować i wdrożyć bezpieczny łańcuch dostaw oprogramowania.
