Aller au contenu principal

Supply Chain Security


1 - Risques Supply Chain

1.1 Attaques récentes

AttaqueAnnéeImpact
SolarWinds202018,000+ organisations
Codecov2021Secrets exposés
Log4Shell2021Millions de systèmes
ua-parser-js2021Malware npm

1.2 Vecteurs d'attaque


2 - Software Composition Analysis (SCA)

2.1 Outils SCA

OutilTypeFeatures
SnykCommercialSCA + Fix PRs
DependabotGitHub natifAuto PRs
OWASP Dependency-CheckOSSCVE scanning
RenovateOSSDependency updates
WhiteSourceCommercialEnterprise

2.2 Snyk

# GitHub Action
- name: Snyk SCA
uses: snyk/actions/node@master
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
with:
command: test
args: --severity-threshold=high --all-projects
# CLI
snyk test

# Monitor (push to dashboard)
snyk monitor

# Fix vulnerabilities
snyk wizard

2.3 Dependabot

# .github/dependabot.yml
version: 2
updates:
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "weekly"
open-pull-requests-limit: 10
groups:
production-dependencies:
patterns:
- "*"
exclude-patterns:
- "@types/*"
- "eslint*"
ignore:
- dependency-name: "aws-sdk"
versions: ["3.x"]

- package-ecosystem: "docker"
directory: "/"
schedule:
interval: "weekly"

- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"

2.4 OWASP Dependency-Check

- name: OWASP Dependency Check
uses: dependency-check/Dependency-Check_Action@main
with:
project: 'my-app'
path: '.'
format: 'HTML'
args: >-
--failOnCVSS 7
--enableRetired

3 - SBOM (Software Bill of Materials)

3.1 Concept

3.2 Formats SBOM

FormatStandardUsage
SPDXISO/IECLarge adoption
CycloneDXOWASPSecurity-focused
SWIDISO/IECSoftware ID

3.3 Générer un SBOM

# Syft (CycloneDX)
syft myapp:latest -o cyclonedx-json > sbom.json

# Trivy (SPDX)
trivy image --format spdx-json --output sbom-spdx.json myapp:latest

# npm (CycloneDX)
npx @cyclonedx/cyclonedx-npm --output-file sbom.xml

3.4 Pipeline avec SBOM

- name: Generate SBOM
run: |
syft $IMAGE -o cyclonedx-json > sbom.json

- name: Scan SBOM for vulnerabilities
run: |
grype sbom:sbom.json --fail-on high

- name: Attest SBOM
run: |
cosign attest --predicate sbom.json \
--type cyclonedx \
--key $COSIGN_KEY \
$IMAGE

4 - Signature et attestation

4.1 Sigstore / Cosign

# Générer une clé
cosign generate-key-pair

# Signer une image
cosign sign --key cosign.key myregistry.io/myapp:v1.0.0

# Vérifier
cosign verify --key cosign.pub myregistry.io/myapp:v1.0.0

# Keyless signing (OIDC)
cosign sign myregistry.io/myapp:v1.0.0

# Vérifier keyless
cosign verify --certificate-identity [email protected] \
--certificate-oidc-issuer https://accounts.google.com \
myregistry.io/myapp:v1.0.0

4.2 SLSA (Supply-chain Levels for Software Artifacts)

LevelRequirements
SLSA 1Documentation du build
SLSA 2Hosted build, authenticated provenance
SLSA 3Source et build hardened
SLSA 4Two-party review, hermetic builds

4.3 SLSA Provenance

# GitHub Action pour SLSA provenance
- name: Generate SLSA Provenance
uses: slsa-framework/slsa-github-generator/.github/workflows/[email protected]
with:
image: ${{ env.IMAGE }}
digest: ${{ env.DIGEST }}
// Exemple de provenance SLSA
{
"_type": "https://in-toto.io/Statement/v0.1",
"predicateType": "https://slsa.dev/provenance/v0.2",
"subject": [{
"name": "myapp",
"digest": { "sha256": "abc123..." }
}],
"predicate": {
"builder": { "id": "https://github.com/actions/runner" },
"buildType": "https://github.com/slsa-framework/slsa-github-generator",
"invocation": {
"configSource": {
"uri": "git+https://github.com/myorg/myapp@refs/heads/main",
"digest": { "sha1": "def456..." }
}
},
"materials": [
{
"uri": "git+https://github.com/myorg/myapp",
"digest": { "sha1": "def456..." }
}
]
}
}

5 - Secure Build Pipeline

5.1 GitHub Actions Hardening

name: Secure Build

on:
push:
branches: [main]

# Permissions minimales
permissions:
contents: read
packages: write
id-token: write # Pour OIDC

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false

# Pin des actions par SHA
- uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4.0.0
with:
node-version: '20'

# Vérifier les checksums
- name: Verify dependencies
run: npm ci --ignore-scripts

# Build hermétique
- name: Build
run: npm run build
env:
NODE_ENV: production

5.2 Dependency Pinning

// package-lock.json - lockfile obligatoire
{
"lockfileVersion": 3,
"packages": {
"node_modules/express": {
"version": "4.18.2",
"resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz",
"integrity": "sha512-...=="
}
}
}
# Dockerfile - Image pinning par digest
FROM node:20-alpine@sha256:abc123def456...

5.3 Reproducible Builds

# Build reproductible
FROM node:20-alpine AS builder
WORKDIR /app

# Copier uniquement package files d'abord
COPY package*.json ./
RUN npm ci --ignore-scripts

# Puis le code
COPY . .
RUN npm run build

# Timestamps constants pour reproductibilité
RUN find /app/dist -type f -exec touch -t 202401010000 {} \;

6 - Admission Controllers

6.1 Kyverno Policies

# Exiger des images signées
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:
- "ghcr.io/myorg/*"
attestors:
- entries:
- keyless:
subject: "https://github.com/myorg/*"
issuer: "https://token.actions.githubusercontent.com"

6.2 OPA Gatekeeper

apiVersion: templates.gatekeeper.sh/v1
kind: ConstraintTemplate
metadata:
name: k8sallowedrepos
spec:
crd:
spec:
names:
kind: K8sAllowedRepos
validation:
openAPIV3Schema:
type: object
properties:
repos:
type: array
items:
type: string
targets:
- target: admission.k8s.gatekeeper.sh
rego: |
package k8sallowedrepos

violation[{"msg": msg}] {
container := input.review.object.spec.containers[_]
not strings.any_prefix_match(container.image, input.parameters.repos)
msg := sprintf("image '%v' not from allowed repos", [container.image])
}

Résumé

Dans ce chapitre, nous avons appris :

  • Les risques supply chain
  • Le SCA (Snyk, Dependabot, OWASP)
  • Les SBOM et leur génération
  • La signature avec Cosign/Sigstore
  • Les niveaux SLSA
  • Les Admission Controllers

Prochaine étape

Dans le prochain chapitre, nous verrons la Gestion des secrets.

→ Chapitre suivant : Gestion des secrets


← Retour à la table des matières