E-NO Logo
EN FR
Kubernetes Secrets security 9 Min Read

Renforcer la sécurité des Kubernetes Secrets avec des exemples pratiques

calendar_today Published: 2026-07-10
update Last Updated: 2026-07-10
analytics SEO Efficiency: 100%
Technical guide illustration for Renforcer la sécurité des Kubernetes Secrets avec des exemples pratiques.

Introduction

Les Kubernetes Secrets contiennent des identifiants, tokens, clés d'API et autres configurations sensibles. Traitez-les comme des "joyaux de la couronne". Ce guide pratique montre comment appliquer Kubernetes Secrets hardening dans des clusters réels, à l'aide de YAML et de commandes kubectl. Vous apprendrez à réduire le rayon d'impact via le RBAC, à éviter d'exposer des Secrets dans les environnements des pods, à activer le chiffrement au repos, à restreindre l'exposition réseau, et à ajouter des contrôles simples et répétés.

Ce que vous allez faire :

  • Inventorier et classifier les Secrets par sensibilité et propriétaire
  • Activer le chiffrement au repos pour les Secrets dans le data store de l'API server
  • Appliquer le moindre privilège via RBAC et comptes de service par workload
  • Consommer les Secrets via des fichiers plutôt que des variables d'environnement
  • Ajouter des NetworkPolicies par défaut en deny avec des autorisations explicites
  • Exécuter des contrôles simples, peu risqués, pour valider le durcissement

Astuce SEO/termes usuels : ce guide illustre Kubernetes Secrets security, Kubernetes Secrets hardening, Kubernetes Secrets access control, Kubernetes Secrets permissions et, plus largement, la gestion de Kubernetes Secrets secrets dans des environnements de production.

Vue d'ensemble du flux

Adoptez un déroulé par étapes que vous pouvez appliquer namespace par namespace : 1) inventaire et classification, 2) chiffrement au repos, 3) verrouillage RBAC et comptes de service, 4) usage sûr des Secrets dans les pods, 5) confinement réseau, 6) contrôles et rotation.

1) Inventorier et classifier les Secrets

Commencez par lister les Secrets sur tous les namespaces et étiqueter les propriétaires.

Lister les Secrets avec leurs types :

kubectl get secrets -A -o wide

Ajouter des labels homogènes pour pouvoir requêter par propriétaire et usage :

kubectl label secret db-credentials owner=payments purpose=database -n team-apps --overwrite

Créer de nouveaux Secrets avec un nommage clair et un bon périmètre :

kubectl create secret generic db-credentials \
  --from-literal=username=app \
  --from-literal=password='S3cr3t!' \
  -n team-apps

Bonnes pratiques : préférez des Secrets dédiés par application/composant plutôt que des Secrets partagés entre applications. Cela réduit le rayon d'impact et simplifie Kubernetes Secrets access control.

2) Chiffrer les Secrets au repos

Les Secrets sont stockés par l'API server. Activez l'encryption au repos pour qu'ils soient chiffrés sur disque.

Exemple d'EncryptionConfiguration (fournisseur aescbc) :

apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
- resources:
  - secrets
  providers:
  - aescbc:
      keys:
      - name: key1
        secret: <base64-encoded-32-byte-key>
  - identity: {}

Étapes clés :

  • Placer le fichier EncryptionConfiguration sur les nœuds du plan de contrôle.
  • Configurer l'API server pour l'utiliser (par exemple via --encryption-provider-config).
  • Redémarrer l'API server et ré-encrypter les données existantes si nécessaire.

Sur des clusters managés, utilisez le paramètre de la plateforme qui active le chiffrement des Secrets.

3) Verrouiller le RBAC et les comptes de service

N'accordez la lecture de Secrets qu'aux workloads qui en ont besoin, et si possible seulement sur des noms précis.

ServiceAccount sans montage automatique du token :

apiVersion: v1
kind: ServiceAccount
metadata:
  name: web-sa
  namespace: team-apps
automountServiceAccountToken: false

Role autorisant la lecture d'un seul Secret par nom :

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: read-db-credentials
  namespace: team-apps
rules:
- apiGroups: ['']
  resources: ['secrets']
  resourceNames: ['db-credentials']
  verbs: ['get']

RoleBinding pour ce ServiceAccount :

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: web-sa-read-db-credentials
  namespace: team-apps
subjects:
- kind: ServiceAccount
  name: web-sa
  namespace: team-apps
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: read-db-credentials

Vérification rapide :

kubectl auth can-i get secret db-credentials \
  --as=system: serviceaccount: team-apps: web-sa \
  -n team-apps

4) Utiliser les Secrets en toute sécurité dans les pods

Privilégiez le montage des Secrets en fichiers plutôt que leur exposition en variables d'environnement. Les variables peuvent fuiter dans les logs, rapports de crash et /proc.

Pod montant un Secret en fichiers en lecture seule :

apiVersion: v1
kind: Pod
metadata:
  name: web
  namespace: team-apps
spec:
  serviceAccountName: web-sa
  automountServiceAccountToken: false
  containers:
  - name: app
    image: your-registry/web:1.0.0
    volumeMounts:
    - name: db-secret
      mountPath: /var/run/secrets/app
      readOnly: true
    env:
    - name: DB_USER_FILE
      value: /var/run/secrets/app/username
    - name: DB_PASS_FILE
      value: /var/run/secrets/app/password
  volumes:
  - name: db-secret
    secret:
      secretName: db-credentials

Dans votre application, lisez le contenu des fichiers au démarrage au lieu d'utiliser des variables d'environnement. Si vous devez utiliser des variables, limitez-les aux seuls conteneurs qui en ont réellement besoin et évitez les projections globales de type envFrom.

Secrets immuables pour prévenir les modifications accidentelles :

apiVersion: v1
kind: Secret
metadata:
  name: db-credentials
  namespace: team-apps
type: Opaque
immutable: true
data:
  username: YXBw
  password: UzNjcjN0IQ==

Pour la rotation, créez un nouveau Secret (par ex. db-credentials-v2), mettez à jour le Deployment pour le référencer, puis supprimez l'ancien après vérification.

5) Contenir l'exposition réseau

Les NetworkPolicies ne protègent pas directement les Secrets, mais elles limitent les mouvements latéraux et réduisent le risque d'exfiltration depuis un pod compromis.

Deny-all par défaut en ingress et egress :

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-all
  namespace: team-apps
spec:
  podSelector: {}
  policyTypes:
  - Ingress
  - Egress

Autoriser la sortie uniquement vers le DNS (adaptez selon votre cluster) :

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-dns-egress
  namespace: team-apps
spec:
  podSelector: {}
  policyTypes:
  - Egress
  egress:
  - to:
    - namespaceSelector:
        matchLabels:
          kubernetes.io/metadata.name: kube-system
      podSelector:
        matchLabels:
          k8s-app: kube-dns
    ports:
    - protocol: UDP
      port: 53
    - protocol: TCP
      port: 53

Ajoutez ensuite des politiques d'autorisation explicites pour les dépendances nécessaires.

6) Ajouter des contrôles rapides et des audits

Exécutez régulièrement ces vérifications légères.

Qui peut lire quels Secrets :

# Lister les permissions effectives d'un ServiceAccount
kubectl auth can-i --list \
  --as=system: serviceaccount: team-apps: web-sa \
  -n team-apps | grep secrets || true

Trouver les pods qui référencent des Secrets via des variables d'environnement (jq) :

kubectl get pods -A -o json | jq -r '
  .items[]
  | select((.spec.containers // [])
      | map(.env // [] | map(has("valueFrom") and .valueFrom.secretKeyRef != null) | any)
      | any)
  | [.metadata.namespace, .metadata.name] | @tsv'

Lister les Secrets non immuables :

kubectl get secrets -A -o json | jq -r '
  .items[] | select(.immutable != true) | [.metadata.namespace, .metadata.name] | @tsv'

Détecter les Roles/ClusterRoles trop larges lisant de nombreux Secrets :

kubectl get role, clusterrole -A -o yaml | grep -n 'resources: \[secrets\]' -n || true

Confirmez la configuration d'encryption au repos en inspectant les flags de l'API server et le fichier du provider d'encryption sur les nœuds du plan de contrôle, ou l'option équivalente en cluster managé.

Plan pilote local

Démarrez petit pour mesurer les progrès et limiter les risques.

Périmètre

  • Namespace : team-apps
  • Workload : un Deployment unique nommé web qui a besoin de db-credentials

Critères de succès

  • Seul le ServiceAccount web-sa peut lire le Secret db-credentials dans team-apps
  • Aucun pod dans team-apps ne consomme des Secrets via des variables d'environnement
  • Le namespace a une NetworkPolicy deny-all avec des autorisations explicites

Étapes

  1. Créer le namespace et le compte de service
kubectl create namespace team-apps
kubectl apply -f - <<'EOF'
apiVersion: v1
kind: ServiceAccount
metadata:
  name: web-sa
  namespace: team-apps
automountServiceAccountToken: false
EOF
  1. Créer le Secret
kubectl create secret generic db-credentials \
  --from-literal=username=app \
  --from-literal=password='S3cr3t!' \
  -n team-apps
  1. Appliquer le RBAC de moindre privilège
kubectl apply -f - <<'EOF'
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: read-db-credentials
  namespace: team-apps
rules:
- apiGroups: ['']
  resources: ['secrets']
  resourceNames: ['db-credentials']
  verbs: ['get']
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: web-sa-read-db-credentials
  namespace: team-apps
subjects:
- kind: ServiceAccount
  name: web-sa
  namespace: team-apps
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: read-db-credentials
EOF
  1. Déployer l'application en montant les Secrets comme fichiers
kubectl apply -f - <<'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
  namespace: team-apps
spec:
  replicas: 1
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      serviceAccountName: web-sa
      automountServiceAccountToken: false
      containers:
      - name: app
        image: your-registry/web:1.0.0
        volumeMounts:
        - name: db-secret
          mountPath: /var/run/secrets/app
          readOnly: true
        env:
        - name: DB_USER_FILE
          value: /var/run/secrets/app/username
        - name: DB_PASS_FILE
          value: /var/run/secrets/app/password
      volumes:
      - name: db-secret
        secret:
          secretName: db-credentials
EOF
  1. Appliquer deny-all et autoriser le DNS
kubectl apply -f - <<'EOF'
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-all
  namespace: team-apps
spec:
  podSelector: {}
  policyTypes: [Ingress, Egress]
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-dns-egress
  namespace: team-apps
spec:
  podSelector: {}
  policyTypes: [Egress]
  egress:
  - to:
    - namespaceSelector:
        matchLabels:
          kubernetes.io/metadata.name: kube-system
      podSelector:
        matchLabels:
          k8s-app: kube-dns
    ports:
    - protocol: UDP
      port: 53
    - protocol: TCP
      port: 53
EOF
  1. Valider
# Seul web-sa peut lire db-credentials
kubectl auth can-i get secret db-credentials \
  --as=system: serviceaccount: team-apps: web-sa \
  -n team-apps

# Le SA par défaut ne doit pas pouvoir
kubectl auth can-i get secret db-credentials \
  --as=system: serviceaccount: team-apps: default \
  -n team-apps

# Aucun pod ne consomme des Secrets via env vars
kubectl get pods -n team-apps -o json | jq -r '
  .items[]
  | select((.spec.containers // [])
      | map(.env // [] | map(has("valueFrom") and .valueFrom.secretKeyRef != null) | any)
      | any)
  | .metadata.name' | wc -l

# Les objets NetworkPolicy existent
kubectl get networkpolicy -n team-apps
  1. Documenter la rotation de db-credentials
  • Créer db-credentials-v2
  • Mettre à jour le Deployment pour référencer db-credentials-v2
  • Redéployer les pods et vérifier
  • Supprimer db-credentials après validation

Plan de rollback

  • Conserver le Secret précédent jusqu'à validation complète
  • En cas d'échec, rétablir le Deployment sur l'ancien Secret et relancer les tests

Conclusion

Vous disposez désormais d'une démarche pratique pour durcir la sécurité des Kubernetes Secrets : inventaire, chiffrement au repos, RBAC de moindre privilège, limitation des variables d'environnement, confinement réseau et contrôles répétables. Démarrez par un namespace pilote, mesurez, puis étendez progressivement.

Métriques à suivre en continu :

  • Nombre de Secrets par namespace et présence des labels propriétaire
  • Nombre de Roles lisant des Secrets arbitraires vs noms spécifiques
  • Pods consommant des Secrets via variables d'environnement vs montages fichiers
  • Namespaces couverts par des NetworkPolicies deny-all

Cette approche par étapes rend les changements sûrs et observables, tout en améliorant votre posture de sécurité pas à pas.

Article Quality Score

Reader usefulness 100%
  • check_circle Reader-ready guide
  • check_circle Practical examples included
  • check_circle Clean SEO article URL