🔒 S2E06 — DevSecOps Pipeline Security guardrails automatisés

Intégration native de la sécurité
Public cible : DevSecOps Engineers, Security Architects, Platform Engineers

Synopsis

Intégrer la sécurité dès le code et tout au long du pipeline. Passer des gates bloquantes à des guardrails automatisés. Security-as-Code partout.


Anti-pattern → Pattern

Pipeline réactif (à éviter)

flowchart TD
    A["Dev Code"] --> B["Build"]
    B --> C["Tests Unitaires"]
    C --> D["Package"]
    D --> E["Security Scan"]
    E --> F{"Vulnérabilités ?"}
    F -- "Oui" --> G["Blocage & Rework"]
    F -- "Non" --> H["Déploiement"]

Pipeline natif sécurisé (recommandé)

flowchart TD
    A["Pre-commit hooks rapides"] --> B["Feedback IDE"]
    B --> C["Policy-as-Code par défaut"]
    C --> D["Scans intégrés CI/CD"]
    D --> E["Sécurité runtime + observabilité"]

5 Anti-patterns et correctifs

1) Gates fin de chaîne → Guardrails continus

  • À éviter : unique scan bloquant en fin de pipeline
  • À faire : hooks, templates sécurisés, policies par défaut

2) Scanner tout → Prioriser par le risque

  • À éviter : scans exhaustifs lents et bruyants
  • À faire : profondeur selon criticité, chemins métiers critiques

3) Silos sécurité → Security Champions

  • À éviter : dépendance à une équipe centrale
  • À faire : champions formés et mandatés dans chaque squad

4) Compliance snapshot → Continuous compliance

  • À éviter : audits ponctuels et dérive entre deux dates
  • À faire : GitOps + OPA + tableaux de bord en continu

5) Security theater → Security engineering

  • À éviter : empilement d’outils, métriques de façade
  • À faire : intégration, automatisation, métriques orientées risque

Architecture cible

flowchart TD
  subgraph IDE["IDE & Pré-commit"]
    P1["Plugins sécurité"]
    P2["Hooks pré-commit"]
    P3["Templates sécurisés"]
  end
  subgraph CI["Pipeline CI/CD"]
    C1["SAST rapide"]
    C2["Scan dépendances"]
    C3["Détection secrets"]
    C4["Policy validation"]
    C5["Scan images"]
    C6["Signature artefacts"]
  end
  subgraph RUN["Production"]
    R1["Runtime security"]
    R2["Monitoring sécurité"]
    R3["Réponse incidents"]
  end
  IDE --> CI --> RUN

Implémentation prête à l’emploi

Pré-commit (Security Foundations)

# .pre-commit-config.yaml
repos:
  - repo: https://github.com/zricethezav/gitleaks
    rev: v8.18.0
    hooks:
      - id: gitleaks
        args: ["--verbose"]
  - repo: https://github.com/returntocorp/semgrep
    rev: v1.45.0
    hooks:
      - id: semgrep
        args: ["--config=auto","--error","--skip-unknown-extensions"]

CI GitHub Actions (Security-as-Code)

# .github/workflows/devsecops.yml
name: DevSecOps Pipeline
on: [push, pull_request]

jobs:
  security-left-shift:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: SAST (Semgrep)
        run: semgrep --config=auto --error .

      - name: Dépendances (npm + Python)
        run: |
          if [ -f package.json ]; then npm audit --audit-level=critical || true; fi
          if [ -f requirements.txt ]; then pipx run safety check -r requirements.txt || true; fi

      - name: Secrets (GitLeaks)
        run: |
          gitleaks detect --source . --report-path gitleaks.json
          test ! -s gitleaks.json

      - name: Build image
        run: |
          docker build -f Dockerfile.secure -t $IMAGE_NAME .

      - name: Scan image (Trivy)
        run: |
          trivy image --exit-code 1 --severity HIGH,CRITICAL $IMAGE_NAME
          trivy image --ignore-unfixed $IMAGE_NAME

      - name: Signature (Cosign)
        run: cosign sign --yes $IMAGE_NAME

Dockerfile sécurisé

# Dockerfile.secure
FROM node:18-alpine AS builder
RUN addgroup -S nodejs && adduser -S nodejs -G nodejs
USER nodejs
WORKDIR /app
COPY --chown=nodejs:nodejs package*.json ./
RUN npm ci --only=production && npm cache clean --force
COPY --chown=nodejs:nodejs . .
RUN npm run build

FROM gcr.io/distroless/nodejs18-debian11:nonroot
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
USER nonroot
EXPOSE 3000
CMD ["dist/index.js"]

Policy-as-Code OPA (Rego)

package kubernetes.security

deny[msg] {
  input.kind == "Pod"
  input.spec.securityContext.privileged == true
  msg := "Containers privilégiés interdits"
}

deny[msg] {
  input.kind == "Pod"
  container := input.spec.containers[_]
  not container.resources.limits.memory
  msg := sprintf("Container %s: limites mémoire requises", [container.name])
}

deny[msg] {
  input.kind == "Pod"
  container := input.spec.containers[_]
  not startswith(container.image, "registry.company.com/")
  msg := sprintf("Container %s: image non approuvée", [container.name])
}

Sécurité runtime Kubernetes (extrait)

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: falco
  namespace: security-system
spec:
  template:
    spec:
      containers:
        - name: falco
          image: falcosecurity/falco:latest
          env:
            - name: FALCO_GRPC_ENABLED
              value: "true"

Maturité et indicateurs

Paliers

  • Basique : scans pipeline, hooks simples, scan d’images
  • Intégré : Policy-as-Code, champions, rapports auto
  • Avancé : sécurité runtime, threat modeling automatisé
  • Optimisé : insights prédictifs, opérations sans friction

Observabilité

  • Durée scans sécurité
  • Taux de violations policies
  • Dérive de conformité
  • Incidents sécurité et MTTR
  • Adhésion développeurs

Références

  • OWASP DevSecOps Guide
  • NIST Cybersecurity Framework
  • CIS Controls v8
  • CNCF Kubernetes Security Guide
  • Martin Fowler — Pipeline Patterns
  • Google Cloud — Container Security Best Practices

Outils : Semgrep, Trivy, Falco, OPA, GitLeaks, Cosign