Sécurité
Blog
Sécurité11 min

Kubernetes Security : la checklist du DSI

Jean-Luc Dubouchet18 décembre 2025

Kubernetes Security : la checklist du DSI

Kubernetes par défaut n'est pas sécurisé. C'est un excellent moteur pour déployer des applications, mais c'est à vous de construire les garde-fous. Nous avons vu des clusters en production sans aucune network policy (traffic réseau non filtré), sans audit logging (aucune traçabilité), sans RBAC (n'importe qui peut tout faire). C'est un risque RGPD/LPD massif.

Voici la checklist concrète que chaque DSI devrait appliquer.

Pourquoi Kubernetes security est non-négociable

Trois raisons :

  1. Blast radius : un cluster Kubernetes concentre potentiellement 100+ applications critiques. Une faille = accès à tout.
  2. Audit trail : RGPD et LPD exigent que vous prouviez qui a changé quoi, où et quand. Sans audit, vous êtes auditable.
  3. Supply chain : 99% des images viennent de tiers. Vous devez valider qu'elles ne contiennent pas de malware.

Chez Hikube.cloud, notre plateforme Kubernetes souveraine intègre ces standards de sécurité. Mais peu importe la plateforme, les principes restent identiques.

Checklist sécurité Kubernetes

1. RBAC : contrôle d'accès granulaire

Problème : Par défaut, tout utilisateur Kubernetes peut faire n'importe quoi.

Solution : Role-based Access Control (RBAC).

# Exemple : développeur peut déployer dans le namespace "staging" uniquement
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: staging
  name: dev-deployer
rules:
- apiGroups: ["apps"]
  resources: ["deployments"]
  verbs: ["get", "list", "create", "patch"]
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list", "logs"]
  # Pas de "delete", pas de "exec" (exécuter code en pod)
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: dev-deployer-binding
  namespace: staging
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: dev-deployer
subjects:
- kind: User
  name: dev-team@company.ch

Points clés :

  • Principle of least privilege : chaque utilisateur/service account a juste ce qu'il faut
  • Jamais de cluster-admin sauf pour les vrais admins (5 personnes max)
  • Audit tous les RBAC changes (git ou système centralisé)

Status : - Configuré pour tous les rôles (admin, dev, ops, contractors)

2. Pod Security Standards (PSS)

Problème : N'importe quel pod peut tourner en root, accéder à l'hôte, etc.

Solution : Pod Security Standards (remplace PSP depuis K8s 1.25+).

# Pod restrictif (recommandé pour production)
apiVersion: v1
kind: Pod
metadata:
  name: secure-app
spec:
  securityContext:
    runAsNonRoot: true
    runAsUser: 1000
    fsReadOnlyRootFilesystem: true
    seccompProfile:
      type: RuntimeDefault
  containers:
  - name: app
    image: myapp:1.0
    securityContext:
      allowPrivilegeEscalation: false
      readOnlyRootFilesystem: true
      capabilities:
        drop: ["ALL"]
    resources:
      limits:
        memory: "256Mi"
        cpu: "250m"
      requests:
        memory: "128Mi"
        cpu: "100m"

Points clés :

  • runAsNonRoot: true : pas de root
  • readOnlyRootFilesystem: true : filesystem en lecture seule
  • allowPrivilegeEscalation: false : pas d'escalade
  • capabilities: drop ALL : zéro privilèges spéciaux
  • Ressources définies (limits + requests)

Enforce au niveau namespace :

apiVersion: apiserver.config.k8s.io/v1
kind: AdmissionConfiguration
plugins:
- name: PodSecurity
  configuration:
    apiVersion: pod-security.admission.config.k8s.io/v1beta1
    kind: PodSecurityAdmissionConfiguration
    defaults:
      enforce: "restricted"          # Production
      audit: "restricted"
      warn: "restricted"
    exemptions:
      namespaces: ["kube-system", "kube-public"]

Status : - Pod Security Standards enforced à "restricted" sur tous les namespaces production

3. Network Policies : isoler le traffic

Problème : Par défaut, tout pod peut parler à tout pod (no lateral segmentation).

Solution : Network Policies = firewall au niveau pod.

# Deny tout par défaut
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-ingress
  namespace: production
spec:
  podSelector: {}
  policyTypes:
  - Ingress
---
# Allow uniquement API → Database
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-api-to-db
  namespace: production
spec:
  podSelector:
    matchLabels:
      tier: database
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          tier: api
    ports:
    - protocol: TCP
      port: 5432

Points clés :

  • Commencer par "deny all" (par défaut)
  • Whitelister explicitement chaque connexion
  • Tester avec kubectl logs ou monitoring

Status : - Network policies appliquées pour tous les services critiques

4. Image scanning & vulnerability management

Problème : Vos images contiennent potentiellement des vulnérabilités connues.

Solution : Scanner tout avant de déployer.

# Exemple avec Trivy (open source)
apiVersion: batch/v1
kind: CronJob
metadata:
  name: trivy-image-scan
spec:
  schedule: "0 2 * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: trivy
            image: aquasec/trivy:latest
            args:
            - "image"
            - "--exit-code=1"  # fail si vulnérabilité critique trouvée
            - "--severity=CRITICAL,HIGH"
            - "myregistry.azurecr.io/myapp:latest"
          restartPolicy: OnFailure

Ou via CI/CD (meilleure approche) : scanner au build, bloquer le push si vulnérabilité.

Points clés :

  • Scanner au build (CI) et avant déploiement (runtime)
  • Baseline acceptable défini (ex. max vulnérabilités "medium")
  • Processus de patch régulier

Status : - Image scanning en place avant tout déploiement production

5. Secrets management : ne jamais en clair

Problème : Secrets hardcodés en clair en YAML = disaster.

Solution : Secrets chiffrés ou externalisés.

# ❌ MAUVAIS : secret en clair
apiVersion: v1
kind: Secret
metadata:
  name: db-secret
data:
  password: YWRtaW4xMjM=  # base64, facilement décodable
---
# ✅ BON : secret chiffré avec Sealed Secrets
apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
  name: db-secret
spec:
  encryptedData:
    password: AgBvK3x4K9... # chiffré avec clé publique cluster

Ou externalisé :

apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: db-secret
spec:
  secretStoreRef:
    name: vault-backend
  target:
    name: db-secret
  data:
  - secretKey: password
    remoteRef:
      key: postgres/password

Points clés :

  • Jamais base64 (ce n'est pas du chiffrement)
  • Sealed Secrets ou External Secrets
  • Secrets en RBAC : pas d'accès par défaut
  • Rotation régulière (tous les 90 jours)
  • Audit qui accède aux secrets

Status : - Tous les secrets chiffrés ou externalisés. Zéro secret en clair en repo.

6. Audit logging : traçabilité complète

Problème : Aucune traçabilité de qui a changé quoi.

Solution : Audit logging activé.

# Configuration API server
--audit-log-path=/var/log/audit/audit.log
--audit-log-maxage=7
--audit-log-maxbackup=3
--audit-log-maxsize=100
--audit-policy-file=/etc/kubernetes/audit-policy.yaml

Avec policy :

apiVersion: audit.k8s.io/v1
kind: Policy
rules:
# Log tous les changesets en production
- level: RequestResponse
  namespaces: ["production", "staging"]
  verbs: ["create", "update", "patch", "delete"]
  omitStages:
  - RequestReceived
---
# Log les accès sensibles (secrets, RBAC)
- level: RequestResponse
  resources: ["secrets", "clusterroles", "clusterrolebindings"]
  verbs: ["get", "list", "watch"]
---
# Autre : minimal logging
- level: Metadata

Points clés :

  • Audit immuable (pas de delete/modification)
  • Centralisé (ELK, Splunk, DataDog)
  • Défini par policy (trop de logs = useless)
  • Rétention 30-90 jours minimum (RGPD)
  • Alertes sur actions sensibles

Status : - Audit logging activé et centralisé

7. Supply chain security : signaturas & attestations

Problème : Comment vérifier que l'image que vous déployez vient vraiment de votre build CI ?

Solution : Container image signing.

# Signer l'image à la fin du build
cosign sign --key cosign.key ghcr.io/myorg/myapp:v1.0

# En production, vérifier la signature avant déploiement
cosign verify --key cosign.pub ghcr.io/myorg/myapp:v1.0

Ou via admission controller (automatique) :

apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
  name: image-signature-verification
webhooks:
- name: verify.sigstore.dev
  rules:
  - operations: ["CREATE", "UPDATE"]
    apiGroups: [""]
    apiVersions: ["v1"]
    resources: ["pods"]
  failurePolicy: Fail
  clientConfig:
    service:
      name: sigstore-webhook
      namespace: sigstore-system
      path: "/verify"

Points clés :

  • Signer au build
  • Vérifier en admission (avant déploiement)
  • Blanche liste les registries de confiance

Status : - Image signing et verification en place

8. Runtime security : détecter l'anormal

Problème : Un attaquant pourrait créer un pod normal puis faire des choses malveillantes à l'intérieur.

Solution : Runtime detection (ex. Falco).

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: falco
  namespace: falco
spec:
  selector:
    matchLabels:
      app: falco
  template:
    metadata:
      labels:
        app: falco
    spec:
      hostNetwork: true
      dnsPolicy: ClusterFirstWithHostNet
      containers:
      - name: falco
        image: falcosecurity/falco:latest
        securityContext:
          privileged: true
        volumeMounts:
        - name: docker-sock
          mountPath: /host/var/run/docker.sock
        - name: proc
          mountPath: /host/proc
      volumes:
      - name: docker-sock
        hostPath:
          path: /var/run/docker.sock
      - name: proc
        hostPath:
          path: /proc

Falco alertera sur : exécution de shell inattendu, accès anormal aux fichiers système, connections réseau suspectes, etc.

Status : - Runtime detection (Falco ou équivalent) en place

Compliance : LPD et ISO 27001

Ces checklists ci-dessus satisfont les exigences :

Exigence Controlée par
Authentification & autorisation RBAC
Isolation des données Network Policies + Pod Security
Confidentialité Secrets chiffrés
Audit trail Audit logging
Intégrité images Image signing
Détection intrusion Runtime security

Pour un audit LPD/ISO 27001, vous devez documenter :

  • Toutes les policies en place
  • Evidence des tests
  • Logs d'audit sur 90 jours
  • Plan de réponse à incidents

Hikube.cloud intègre tous ces contrôles de sécurité. Pour les installations on-premise, la documentation et formation sont essentielles.

Roadmap de 6 mois

Mois 1-2 : RBAC + Pod Security Standards Mois 3 : Network Policies + Image scanning Mois 4 : Secrets + Audit logging Mois 5 : Image signing + Runtime security Mois 6 : Audit compliance, documentation

Conclusion

Kubernetes security n'est pas un projet ponctuel. C'est une mentalité. Chaque changement doit passer par security review. Chaque produit doit respecter les standards.

Si vous avez un cluster sans ces contrôles, commencez par RBAC et Pod Security. Ce sont les 80% du gain.


À lire aussi :


Cet article vous a été utile ? Découvrez comment Hidora peut vous accompagner : Professional Services · Managed Services · SLA Expert

Cet article vous parle ?

Hidora peut vous accompagner sur ce sujet.

Besoin d'un accompagnement ?

Parlons de votre projet. 30 minutes, sans engagement.