Безопасность цепочки поставок, подписывание образов, SLSA.
Безопасность цепочки поставок ПО критична в эпоху зависимостей и сторонних компонентов. Изучите подписывание образов, SLSA и защиту от атак.
Supply Chain Security — защита программного обеспечения на всех этапах цепочки поставок: от разработки до развёртывания.
Угрозы supply chain:
Известные атаки:
SLSA — фреймворк от Google для обеспечения целостности цепочки поставок.
┌─────────────────────────────────────────────────┐
│ SLSA Levels │
├─────────────────────────────────────────────────┤
│ Level 1: Documented процесс сборки │
│ Level 2: Версионированный исходный код │
│ Level 3: Изолированная среда сборки │
│ Level 4: Двухфакторная проверка изменений │
└─────────────────────────────────────────────────┘
Требования:
Пример:
# .github/workflows/build.yml
name: Build
on:
push:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build
run: |
npm ci
npm run build
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: dist
path: dist/Требования:
Пример:
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # Полная история
- name: Record source version
run: |
echo "COMMIT_SHA=${{ github.sha }}" >> $GITHUB_ENV
echo "BRANCH=${{ github.ref_name }}" >> $GITHUB_ENV
- name: Build with version info
run: |
npm run build -- --version $COMMIT_SHAТребования:
Пример с изоляцией:
jobs:
build:
runs-on: ubuntu-latest
container:
image: node:20-alpine
options: --user 1001 --cap-drop=ALL
steps:
- uses: actions/checkout@v4
- name: Install dependencies
run: npm ci --ignore-scripts
- name: Build
run: npm run build
- name: Generate SLSA provenance
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v2.0.0
with:
base64-subjects: "${{ hashFiles('dist/**') }}"
upload-assets: trueТребования:
Настройка в GitHub:
mainSigstore — проект Linux Foundation для подписывания и верификации артефактов.
Компоненты:
# macOS
brew install cosign
# Linux
wget https://github.com/sigstore/cosign/releases/latest/download/cosign-linux-amd64
sudo mv cosign-linux-amd64 /usr/local/bin/cosign
chmod +x /usr/local/bin/cosign
# GitHub Actions
uses: sigstore/cosign-installer@v3Преимущества keyless:
Подписывание образа:
jobs:
build-and-sign:
runs-on: ubuntu-latest
permissions:
id-token: write # Для keyless signing
contents: read
steps:
- uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to GHCR
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v5
with:
push: true
tags: ghcr.io/my-org/my-app:${{ github.sha }}
digest-file: ./digest.txt
- name: Install Cosign
uses: sigstore/cosign-installer@v3
- name: Sign image
run: |
cosign sign --yes \
ghcr.io/my-org/my-app@$(cat ./digest.txt)Проверка подписи:
# Верификация по OIDC issuer
cosign verify \
--certificate-identity-regexp="https://github.com/my-org/my-app/.github/workflows/build.yml" \
--certificate-oidc-issuer="https://token.actions.githubusercontent.com" \
ghcr.io/my-org/my-app:latest
# Проверка с выводом сертификата
cosign verify \
--certificate-identity-regexp=".*" \
--certificate-oidc-issuer=".*" \
--insecure-ignore-tlog \
ghcr.io/my-org/my-app:latest \
--output-cert certificate.pemГенерация ключевой пары:
cosign generate-key-pair
# Создаёт cosign.key и cosign.pubПодписывание:
cosign sign --key cosign.key ghcr.io/my-org/my-app:latestВерификация:
cosign verify --key cosign.pub ghcr.io/my-org/my-app:latestХранение ключа в KMS:
# AWS KMS
cosign sign --key awskms:///arn:aws:kms:us-east-1:123456789012:key/uuid ghcr.io/my-org/my-app:latest
# GCP KMS
cosign sign --key gcpkms://projects/my-project/locations/global/keyRings/my-kr/cryptoKeys/my-key ghcr.io/my-org/my-app:latest
# Azure Key Vault
cosign sign --key azurekms://my-vault.vault.azure.net/my-key ghcr.io/my-org/my-app:latestProvenance — документ, описывающий как, где и когда был собран артефакт.
Формат: in-toto attestation (SLSA v1.0)
Структура:
{
"_type": "https://in-toto.io/Statement/v1",
"subject": [
{
"name": "my-app",
"digest": {
"sha256": "abc123..."
}
}
],
"predicateType": "https://slsa.dev/provenance/v1",
"predicate": {
"buildDefinition": {
"buildType": "https://github.com/slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v2.0.0",
"externalParameters": {...},
"resolvedDependencies": [...]
},
"runDetails": {
"builder": {...},
"metadata": {...}
}
}
}Использование slsa-github-generator:
name: Build with SLSA
on:
push:
tags:
- 'v*'
jobs:
build:
runs-on: ubuntu-latest
outputs:
digest: ${{ steps.build.outputs.digest }}
steps:
- uses: actions/checkout@v4
- name: Build
id: build
run: |
docker build -t my-app .
docker push ghcr.io/my-org/my-app:latest
echo "digest=$(docker inspect --format='{{index .RepoDigests 0}}' my-app)" >> $GITHUB_OUTPUT
generate-provenance:
needs: build
permissions:
actions: read
id-token: write
contents: read
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@v2.0.0
with:
image: ghcr.io/my-org/my-app
digest: ${{ needs.build.outputs.digest }}
registry-username: ${{ github.actor }}
secrets:
registry-password: ${{ secrets.GITHUB_TOKEN }}Утилита slsa-verifier:
# Установка
wget https://github.com/slsa-framework/slsa-verifier/releases/latest/download/slsa-verifier-linux-amd64
chmod +x slsa-verifier-linux-amd64
# Верификация
./slsa-verifier-linux-amd64 verify-image \
ghcr.io/my-org/my-app:latest \
--source-uri github.com/my-org/my-app \
--source-tag v1.0.0Включение:
Workflow для проверки:
name: Dependency Review
on:
pull_request:
branches: [main]
jobs:
dependency-review:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Dependency Review
uses: actions/dependency-review-action@v4
with:
fail-on-severity: moderate
deny-licenses: GPL-3.0, AGPL-3.0Trivy для контейнеров:
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build image
run: docker build -t my-app .
- name: Run Trivy
uses: aquasecurity/trivy-action@master
with:
image-ref: my-app
format: 'sarif'
output: 'trivy-results.sarif'
severity: 'CRITICAL,HIGH'
- name: Upload to GitHub Security
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: 'trivy-results.sarif'Snyk для зависимостей:
jobs:
security:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run Snyk
uses: snyk/actions/node@master
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
with:
args: --severity-threshold=highГенерация SBOM:
jobs:
sbom:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Generate SBOM
uses: anchore/sbom-action@v0
with:
format: spdx-json
output-file: sbom.json
- name: Upload SBOM
uses: actions/upload-artifact@v4
with:
name: sbom
path: sbom.jsonВерификация SBOM:
# Проверка SBOM через cosign
cosign verify-blob \
--certificate-identity-regexp=".*" \
--certificate-oidc-issuer=".*" \
--signature sbom.sig \
sbom.json# Всегда подписывайте образы перед публикацией
- name: Sign image
run: cosign sign --yes $IMAGE_DIGEST# Изолированная среда
container:
image: node:20-alpine
options: --user 1001 --cap-drop=ALL
# Запрет interactive shell
env:
DEBIAN_FRONTEND: noninteractivejobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Verify image signature
run: |
cosign verify \
--certificate-identity-regexp="https://github.com/my-org/my-app/.github/workflows/build.yml" \
--certificate-oidc-issuer="https://token.actions.githubusercontent.com" \
ghcr.io/my-org/my-app:latest || exit 1
- name: Deploy
run: ./deploy.sh# Еженедельный скан
on:
schedule:
- cron: '0 0 * * 0' # Каждое воскресенье
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Trivy scan
run: trivy fs --severity HIGH,CRITICAL .# Настройка .npmrc для private registry
- name: Setup npm
run: |
echo "//npm.pkg.github.com/:_authToken=${{ secrets.GITHUB_TOKEN }}" > .npmrc
echo "@my-org:registry=https://npm.pkg.github.com" >> .npmrc| Инструмент | Назначение |
|---|---|
| Sigstore/Cosign | Подписывание и верификация |
| SLSA Generator | Генерация provenance |
| SLSA Verifier | Верификация provenance |
| Trivy | Сканирование уязвимостей |
| Snyk | Security scanning зависимостей |
| Anchore/Syft | Генерация SBOM |
| in-toto | Фреймворк для supply chain |
| Grafeas | API для артефактов |
Supply chain security требует многоуровневой защиты:
Безопасность supply chain — не опция, а необходимость в современной разработке.
Вопросы ещё не добавлены
Вопросы для этой подтемы ещё не добавлены.