Les Pod Security Standards (PSS) définissent 3 niveaux de restrictions de sécurité pour vos pods Kubernetes : Privileged (aucune restriction), Baseline (bloque les escalades évidentes), et Restricted (hardening maximal). Ce guide vous explique quand utiliser chaque niveau et comment les appliquer sans casser vos applications.
Qu’est-ce que Pod Security Standards ?
Section intitulée « Qu’est-ce que Pod Security Standards ? »Pod Security Standards (PSS) est le standard officiel Kubernetes pour définir les niveaux de sécurité des pods. Pensez-y comme à des “profils de sécurité prédéfinis” que vous pouvez appliquer à vos namespaces.
Pourquoi c’est important ?
Section intitulée « Pourquoi c’est important ? »Par défaut, Kubernetes autorise des configurations dangereuses :
| Configuration par défaut | Risque |
|---|---|
Pod en root (UID 0) | Escalade de privilèges si le conteneur est compromis |
privileged: true autorisé | Accès complet à l’hôte |
Montage de / possible | Lecture/écriture du système hôte |
hostNetwork: true autorisé | Écoute sur les ports de l’hôte |
Les PSS bloquent ces configurations selon leur niveau de restriction.
Les 3 niveaux PSS
Section intitulée « Les 3 niveaux PSS »Niveau Privileged
Section intitulée « Niveau Privileged »Aucune restriction — Ce niveau autorise tout, y compris les configurations les plus dangereuses.
Quand l’utiliser :
- Namespaces système (
kube-system) - Outils d’infrastructure (monitoring agents, CNI, CSI drivers)
- Jamais pour des applications métier
# Ce pod est autorisé en PrivilegedapiVersion: v1kind: Podmetadata: name: privileged-podspec: containers: - name: debug image: ubuntu securityContext: privileged: true # Accès root complet à l'hôte runAsUser: 0 # Exécution en rootNiveau Baseline
Section intitulée « Niveau Baseline »Restrictions minimales — Bloque les escalades de privilèges les plus dangereuses tout en restant compatible avec la majorité des workloads.
Ce qui est bloqué :
| Configuration | Pourquoi c’est bloqué |
|---|---|
privileged: true | Accès complet à l’hôte |
hostPID: true | Voir les processus de l’hôte |
hostIPC: true | Accès à la mémoire partagée de l’hôte |
hostNetwork: true | Écoute sur les ports de l’hôte |
| Capabilities dangereuses | SYS_ADMIN, NET_RAW, etc. |
Quand l’utiliser :
- Applications legacy ne supportant pas Restricted
- Première étape de migration depuis Privileged
- Environnements de développement
# Ce pod est compatible BaselineapiVersion: v1kind: Podmetadata: name: baseline-podspec: containers: - name: app image: nginx:1.25 securityContext: runAsUser: 1000 # Non-root recommandé allowPrivilegeEscalation: falseNiveau Restricted
Section intitulée « Niveau Restricted »Hardening maximal — Applique les meilleures pratiques de sécurité. C’est le niveau recommandé pour la production.
Ce qui est exigé :
| Exigence | Valeur requise |
|---|---|
runAsNonRoot | true |
allowPrivilegeEscalation | false |
seccompProfile | RuntimeDefault ou Localhost |
capabilities.drop | ALL |
| Volumes autorisés | Seulement configMap, secret, emptyDir, persistentVolumeClaim, projected |
Quand l’utiliser :
- Applications de production
- Workloads manipulant des données sensibles
- Préparation à la certification CKS
# Ce pod est conforme RestrictedapiVersion: v1kind: Podmetadata: name: restricted-podspec: securityContext: runAsNonRoot: true seccompProfile: type: RuntimeDefault containers: - name: app image: nginx:1.25-alpine securityContext: runAsUser: 1000 runAsGroup: 1000 allowPrivilegeEscalation: false readOnlyRootFilesystem: true capabilities: drop: - ALLComment appliquer PSS ?
Section intitulée « Comment appliquer PSS ? »Kubernetes applique les Pod Security Standards via Pod Security Admission (PSA), un admission controller intégré depuis la version 1.25.
Les 3 modes d’application
Section intitulée « Les 3 modes d’application »| Mode | Comportement | Usage |
|---|---|---|
enforce | Bloque les pods non conformes | Production |
audit | Enregistre dans les audit logs | Migration |
warn | Affiche un warning à l’utilisateur | Développement |
Appliquer PSS à un namespace
Section intitulée « Appliquer PSS à un namespace »Méthode 1 : Labels sur le namespace
apiVersion: v1kind: Namespacemetadata: name: production labels: # Applique Restricted en mode enforce pod-security.kubernetes.io/enforce: restricted pod-security.kubernetes.io/enforce-version: latest
# Audit les violations Restricted pod-security.kubernetes.io/audit: restricted pod-security.kubernetes.io/audit-version: latest
# Avertit pour Restricted pod-security.kubernetes.io/warn: restricted pod-security.kubernetes.io/warn-version: latestMéthode 2 : kubectl label
# Appliquer Restricted sur un namespace existantkubectl label namespace production \ pod-security.kubernetes.io/enforce=restricted \ pod-security.kubernetes.io/warn=restricted \ pod-security.kubernetes.io/audit=restricted
# Vérifier les labelskubectl get namespace production -o yaml | grep pod-securityMigrer vers Restricted sans casser vos applications
Section intitulée « Migrer vers Restricted sans casser vos applications »-
Audit d’abord : identifiez les violations
Appliquez d’abord en mode
audit+warnpour voir ce qui casserait :Fenêtre de terminal kubectl label namespace monapp \pod-security.kubernetes.io/audit=restricted \pod-security.kubernetes.io/warn=restrictedCréez un pod de test et observez les warnings :
Fenêtre de terminal kubectl run test --image=nginx -n monapp# Warning: would violate "restricted:latest"... -
Corrigez vos Deployments
Pour chaque violation identifiée, mettez à jour le
securityContext:spec:securityContext:runAsNonRoot: trueseccompProfile:type: RuntimeDefaultcontainers:- name: appsecurityContext:allowPrivilegeEscalation: falsereadOnlyRootFilesystem: truerunAsUser: 1000capabilities:drop: ["ALL"] -
Testez en staging
Déployez avec les nouveaux
securityContextet validez que l’application fonctionne. -
Appliquez Restricted en enforce
Une fois tous les pods conformes :
Fenêtre de terminal kubectl label namespace production \pod-security.kubernetes.io/enforce=restricted \--overwrite
Erreurs fréquentes et solutions
Section intitulée « Erreurs fréquentes et solutions »Erreur 1 : “container has runAsNonRoot and image will run as root”
Section intitulée « Erreur 1 : “container has runAsNonRoot and image will run as root” »Cause : L’image utilise root mais vous avez runAsNonRoot: true.
Solution :
securityContext: runAsUser: 1000 # Forcer un UID non-root runAsGroup: 1000 runAsNonRoot: trueErreur 2 : “seccompProfile is required”
Section intitulée « Erreur 2 : “seccompProfile is required” »Cause : Le niveau Restricted exige un profil seccomp.
Solution :
spec: securityContext: seccompProfile: type: RuntimeDefaultErreur 3 : “unrestricted capabilities”
Section intitulée « Erreur 3 : “unrestricted capabilities” »Cause : Vous n’avez pas droppé toutes les capabilities.
Solution :
containers:- name: app securityContext: capabilities: drop: ["ALL"] # Si vraiment nécessaire, ajoutez explicitement : # add: ["NET_BIND_SERVICE"]Comparatif des 3 niveaux
Section intitulée « Comparatif des 3 niveaux »| Configuration | Privileged | Baseline | Restricted |
|---|---|---|---|
privileged: true | ✅ | ❌ | ❌ |
hostNetwork/PID/IPC | ✅ | ❌ | ❌ |
hostPath volumes | ✅ | ✅ | ❌ |
| Root (UID 0) | ✅ | ✅ | ❌ |
allowPrivilegeEscalation | ✅ | ✅ | ❌ |
| Capabilities dangereuses | ✅ | ❌ | ❌ |
| Seccomp requis | ❌ | ❌ | ✅ |
À retenir
Section intitulée « À retenir »- 3 niveaux : Privileged (tout autorisé), Baseline (bloque le pire), Restricted (hardening maximal)
- Production = Restricted : C’est le niveau recommandé par la documentation Kubernetes
- Migration progressive : Utilisez
auditetwarnavantenforce - Pod Security Admission : L’admission controller natif qui applique les PSS via des labels
- CKS : Les PSS représentent 20% du domaine “Minimize Microservice Vulnerabilities”