Chapitre 12
12 - Securite DevOps
12 - Securite DevOps
Chapitre 12 : Securite DevOps
12.1 DevSecOps Pipeline
12.1.1 Shift Left Security
Le "Shift Left" consiste a integrer la securite le plus tot possible dans le cycle de developpement :
Plan → Code → Build → Test → Deploy → Operate
│ │ │ │ │ │
│ │ │ │ │ │
Secure SAST SCA DAST Image Runtime
Design Audit Signing Security
12.1.2 SAST (Static Application Security Testing)
SAST analyse le code source sans l'executer :
# GitHub Actions - SAST with Semgrep
name: SAST
on: [pull_request]
jobs:
semgrep:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: semgrep/semgrep-action@v1
with:
config: p/python p/owasp-top-ten p/secrets
publishToken: ${{ secrets.SEMGREP_TOKEN }}
Outils SAST populaires :
- Semgrep : Regles personnalisables, large couverture
- SonarQube : Analyse de qualite et securite
- CodeQL (GitHub) : Analyse semantique avancee
- Checkmarx : Solution enterprise
- Fortify : Analyse de vulnerabilites
12.1.3 DAST (Dynamic Application Security Testing)
DAST teste l'application en cours d'execution :
# GitLab CI - DAST with OWASP ZAP
stages:
- dast
dast:
stage: dast
image: owasp/zap2docker-stable
script:
- zap-full-scan.py -t https://staging.example.com -r report.html
artifacts:
paths:
- report.html
12.1.4 Dependency Scanning
Analyse des vulnerabilites dans les dependances :
# GitHub Actions - Dependency Review
name: Dependency Review
on: [pull_request]
jobs:
dependency-review:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/dependency-review-action@v3
with:
fail-on-severity: high
deny-licenses: LGPL-2.0
Exemple de vulnerabilite detectee :
Package: lodash@4.17.20
Severity: CRITICAL (CVE-2021-23337)
CVSS: 9.1
Recommendation: Upgrade to 4.17.21+
12.2 HashiCorp Vault
12.2.1 Architecture Vault
Vault est un gestionnaire de secrets enterprise :
Application ──> Vault API ──> Auth Method (Kubernetes, LDAP, JWT)
│
Secret Engine
│
Storage Backend
(Consul, Raft, S3)
Composants cles :
- Auth Methods : Kubernetes, LDAP, JWT, AppRole
- Secret Engines : KV, Database, AWS, PKI, Transit
- Audit Device : Journalisation de tous les acces
- Storage Backend : Raft (integre), Consul, S3
12.2.2 Deploiement Vault sur Kubernetes
# vault-helm-values.yaml
server:
ha:
enabled: true
replicas: 3
raft:
enabled: true
config: |
ui = true
listener "tcp" {
address = "0.0.0.0:8200"
cluster_address = "0.0.0.0:8201"
tls_disable = true
}
storage "raft" {
path = "/vault/data"
}
service_registration "kubernetes" {}
service:
enabled: true
ingress:
enabled: true
hosts:
- vault.example.com
ui:
enabled: true
12.2.3 Dynamic Secrets
Les secrets dynamiques sont generes a la demande :
# Activer le secret engine Database
vault secrets enable database
# Configurer la connexion PostgreSQL
vault write database/config/postgres-db \
plugin_name=postgresql-database-plugin \
allowed_roles="app-role" \
connection_url="postgresql://{{username}}:{{password}}@postgres:5432/mydb" \
username="vault-admin" \
password="secret"
# Creer un role
vault write database/roles/app-role \
db_name=postgres-db \
creation_statements="CREATE USER \"{{name}}\" WITH PASSWORD '{{password}}' VALID UNTIL '{{expiration}}'; GRANT SELECT ON ALL TABLES IN SCHEMA public TO \"{{name}}\";" \
default_ttl="1h" \
max_ttl="24h"
# Generer un credential
vault read database/creds/app-role
# Key Value
# --- -----
# lease_id database/creds/app-role/abc123
# lease_duration 1h
# password aB3xY7z...
# username v-token-app-role-xyz789
12.2.4 Vault Agent Injector
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-with-secrets
annotations:
vault.hashicorp.com/agent-inject: "true"
vault.hashicorp.com/role: "app"
vault.hashicorp.com/agent-inject-secret-db-creds: "database/creds/app-role"
vault.hashicorp.com/agent-inject-template-db-creds: |
{{- with secret "database/creds/app-role" -}}
export DB_USERNAME="{{ .Data.username }}"
export DB_PASSWORD="{{ .Data.password }}"
{{- end -}}
spec:
template:
metadata:
annotations:
vault.hashicorp.com/agent-inject: "true"
spec:
serviceAccountName: app
containers:
- name: app
image: myapp:latest
env:
- name: DB_USERNAME
valueFrom:
secretKeyRef:
name: dynamic-db-creds
key: username
12.2.5 Transit Engine (Chiffrement)
# Activer le transit engine
vault secrets enable transit
# Creer une cle de chiffrement
vault write -f transit/keys/app-key
# Chiffrer des donnees
vault write transit/encrypt/app-key plaintext=$(base64 <<< "sensitive-data")
# Dechiffrer
vault write transit/decrypt/app-key ciphertext="vault:v1:abc123..."
12.3 OPA/Gatekeeper et Kyverno
12.3.1 OPA (Open Policy Agent)
OPA est un moteur de politique generaliste :
# deny-no-roles.rego
package kubernetes.admission
deny[msg] {
input.request.operation == "CREATE"
not input.request.object.spec.containers[_].securityContext.runAsNonRoot
msg = sprintf("Container %v must run as non-root", [input.request.object.metadata.name])
}
deny[msg] {
input.request.operation == "CREATE"
input.request.object.spec.containers[_].resources.limits == {}
msg = sprintf("Container %v must have resource limits", [input.request.object.metadata.name])
}
12.3.2 Gatekeeper
Gatekeeper est l'implementation Kubernetes d'OPA :
# constraint-template.yaml
apiVersion: templates.gatekeeper.sh/v1beta1
kind: ConstraintTemplate
metadata:
name: k8srequiredlabels
spec:
crd:
spec:
names:
kind: K8sRequiredLabels
validation:
openAPIV3Schema:
type: object
properties:
labels:
type: array
items:
type: string
targets:
- target: admission.k8s.gatekeeper.sh
rego: |
package k8srequiredlabels
violation[{"msg": msg}] {
input.review.object.metadata.labels[required_label] == ""
required_label := input.parameters.labels[_]
msg := sprintf("Missing label: %v", [required_label])
}
---
# constraint.yaml
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sRequiredLabels
metadata:
name: require-team-label
spec:
match:
kinds:
- apiGroups: [""]
kinds: ["Namespace"]
namespaces:
- "production"
parameters:
labels:
- "team"
- "cost-center"
12.3.3 Kyverno
Kyverno est un policy engine natif Kubernetes :
# kyverno-policy.yaml
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-labels
spec:
validationFailureAction: Enforce
background: true
rules:
- name: check-team-label
match:
any:
- resources:
kinds:
- Pod
- Deployment
namespaces:
- production
validate:
message: "Label 'team' is required in production"
pattern:
metadata:
labels:
team: "?*"
- name: block-privileged
match:
any:
- resources:
kinds:
- Pod
validate:
message: "Privileged containers are not allowed"
pattern:
spec:
containers:
- securityContext:
privileged: false
- name: require-resource-limits
match:
any:
- resources:
kinds:
- Deployment
validate:
message: "Resource limits are required"
pattern:
spec:
template:
spec:
containers:
- resources:
limits:
memory: "?*"
cpu: "?*"
12.4 Securite de la Supply Chain
12.4.1 SBOM (Software Bill of Materials)
Un SBOM est une liste de tous les composants d'un logiciel :
# Generer un SBOM CycloneDX avec Syft
syft packages myapp:latest -o cyclonedx-json > sbom.json
# Analyser le SBOM
grype sbom:sbom.json --fail-on=high
# Exemple de SBOM
cat sbom.json | jq '.components[] | {name, version, type}'
{
"name": "flask",
"version": "2.3.2",
"type": "library"
}
{
"name": "python",
"version": "3.11.0",
"type": "application"
}
12.4.2 Image Signing avec Cosign
Cosign permet de signer et verifier des images conteneurs :
# Generer une paire de cles
cosign generate-key-pair
# Signer une image
cosign sign --key cosign.key myregistry.io/myapp:latest
# Verifier une signature
cosign verify --key cosign.pub myregistry.io/myapp:latest
# Verification dans un pipeline
cosign verify-attestation --key cosign.pub myregistry.io/myapp:latest | jq .
12.4.3 SLSA Framework
SLSA (Supply chain Levels for Software Artifacts) definit des niveaux de securite :
Level 1: Build process documented
Level 2: Signed provenance
Level 3: Hardened build platform
Level 4: Hermetic, reproducible builds
Implementation SLSA 3 avec GitHub Actions :
# .github/workflows/slsa.yml
name: SLSA
on:
workflow_dispatch:
push:
branches: [main]
jobs:
build:
permissions:
id-token: write
contents: read
actions: read
uses: slsa-framework/slsa-github-generator/.github/workflows/builder_go_slsa3.yml@v1.9.0
with:
go-version: 1.21
evaluated-envs: "GOFLAGS=-v"
12.4.4 Notary
Notary est un systeme de confiance pour les images conteneurs :
# Initialiser un repository
notary init myregistry.io/myapp
# Signer une nouvelle version
notary add myregistry.io/myapp v1.2.3 --publish
# Verifier
notary verify myregistry.io/myapp@v1.2.3
12.5 Conformite
12.5.1 CIS Benchmarks
Les CIS (Center for Internet Security) Benchmarks sont des guides de securite :
# Executer CIS Benchmark avec kube-bench
kubectl apply -f https://raw.githubusercontent.com/aquasecurity/kube-bench/main/job.yaml
# Resultats
kubectl logs job/kube-bench
# [PASS] 1.1.1 Ensure that the API server pod specification file permissions are set to 644 or more restrictive
# [FAIL] 1.2.2 Ensure that the --basic-auth-file argument is not set
# [WARN] 1.2.5 Ensure that the --kubelet-https argument is set to true
12.5.2 SOC 2 Compliance
SOC 2 est un standard d'audit pour les fournisseurs de services :
Les 5 principes Trust Service Criteria :
- Security : Protection contre les acces non autorises
- Availability : Disponibilite du systeme
- Processing Integrity : Traitement autorise et complete
- Confidentiality : Protection des informations confidentielles
- Privacy : Collecte et traitement des donnees personnelles
Exemple de controles SOC 2 DevOps :
# Code Review Policy
code_review:
required_approvers: 2
required_checks:
- semgrep-sast
- dependency-review
- snyk-scan
# Access Control
access_control:
ci_cd:
- github_actions: ["ci", "cd"]
- vault: ["read-db-creds", "read-kv"]
- kubernetes: ["view", "exec"]
# Audit Logging
audit:
- github_audit_log: true
- vault_audit_log: true
- kubernetes_audit_log: true
- retention_days: 365
12.6 Resume
- Le DevSecOps integre la securite a chaque etape du pipeline
- SAST analyse le code, DAST teste l'application en cours d'execution
- Vault centralise la gestion des secrets avec des secrets dynamiques
- OPA/Gatekeeper et Kyverno permettent le Policy as Code sur Kubernetes
- Les SBOM (CycloneDX) listent tous les composants logiciels
- Cosign signe les images conteneurs pour garantir leur integrite
- SLSA definit les niveaux de securite de la supply chain
- CIS Benchmarks et SOC 2 sont les standards de conformite