Introduction
Helm est le gestionnaire de paquets de facto pour Kubernetes, mais sa capacité à déployer rapidement des applications complexes crée également des risques de sécurité s'il n'est pas géré avec soin. Un chart fonctionnel dans un cluster de développement peut introduire des secrets, des autorisations RBAC trop larges ou des dépôts non fiables en production. Ce guide présente des étapes concrètes pour durcir Helm du point de vue du praticien, en s'adressant aux développeurs, consultants DevOps et équipes techniques de startups.
Vous apprendrez à inventorier votre environnement Helm, configurer des paramètres par défaut sécurisés, gérer les secrets en toute sécurité, vérifier les versions et récupérer des défaillances courantes. Chaque recommandation inclut une commande ou un extrait de configuration exécutable, le résultat attendu et une procédure de récupération. L'objectif est la sécurité opérationnelle : observer avant de modifier, limiter le rayon d'impact, utiliser des espaces réservés plutôt que de vrais secrets, vérifier les résultats et documenter les étapes de récupération avant d'en avoir besoin.
Ce guide suppose Helm 3.12 ou ultérieur, Kubernetes 1.27 ou ultérieur et un contexte kubectl fonctionnel. Certains exemples font référence à GitLab CI/CD ou Docker lorsque cela affecte les prérequis ou l'observabilité, mais l'accent reste mis sur Helm lui-même.
Inventaire de la version et de l'environnement
Avant de modifier quoi que ce soit, vous devez avoir une image précise de votre déploiement Helm actuel. Connaître votre version exacte, votre topologie et votre configuration vous aide à choisir des options de sécurité compatibles et évite de casser un environnement déjà fonctionnel.
Vérifier la version Helm et le contexte Kubernetes
Exécutez ces deux commandes avec un accès en lecture seule :
helm version --short
kubectl config current-context
La sortie attendue ressemble à :
v3.12.0+g123abc
my-prod-cluster
Si vous voyez une chaîne de version Helm v2, arrêtez et passez à Helm v3 avant de continuer. Helm v2 utilisait un composant côté serveur appelé Tiller avec des autorisations de cluster étendues, et il a atteint sa fin de vie en novembre 2020. La migration vers Helm v3 supprime toute cette surface d'attaque.
Enregistrez la version et le contexte dans votre document d'exploitation, avec la date du jour. Cela facilite le dépannage et vous donne un point de restauration.
Inventorier les versions Helm existantes
Listez les versions dans tous les espaces de noms :
helm ls --all-namespaces
Exemple de sortie :
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
nginx-ing ingress 2 2023-10-01 14:22:31.123456 +0000 UTC deployed ingress-nginx-4.7.1 1.8.1
my-app default 5 2023-10-05 09:10:11.987654 +0000 UTC deployed my-app-1.2.0 2.0.0
Notez le nom du chart, la version de l'application et l'espace de noms. Cette liste vous indique quelles charges de travail pourraient être affectées par un changement. Si vous n'avez pas la permission de lister les versions dans tous les espaces de noms, corrigez votre RBAC Kubernetes avant de continuer ; aucune étape de durcissement Helm ne devrait nécessiter des droits d'administrateur de cluster.
Identifier qui peut accéder à Helm
Helm délègue l'autorisation au RBAC Kubernetes. Vérifiez vos propres permissions :
kubectl auth can-i list secrets --namespace default
Sortie attendue : yes ou no. La ressource secrets est l'endroit où Helm stocke les métadonnées des versions par défaut. Si la réponse est no, vous ne pouvez pas gérer les versions dans cet espace de noms. Cartographiez les rôles de chaque développeur ou compte de service avant de restreindre quoi que ce soit.
Changement le plus petit justifié
Une fois l'inventaire réalisé, choisissez une amélioration ciblée. Par exemple, si vous trouvez une ancienne installation Helm v2, la mise à niveau vers v3 est le seul changement. Si toutes les versions utilisent les paramètres par défaut, vous pouvez commencer par activer --atomic sur les installations dans votre pipeline CI. Notez le résultat attendu avant d'exécuter quoi que ce soit.
Chemin de configuration sécurisé
Les paramètres par défaut de Helm privilégient la commodité au détriment de la sécurité. Cette section montre comment configurer Helm et vos charts pour réduire les risques sans perturber les flux de travail normaux.
Sécuriser la configuration du client Helm
Helm stocke son cache de dépôts et ses paramètres dans votre répertoire personnel. Le fichier de configuration principal est ~/.config/helm/helm.yaml. Définissez des permissions restrictives sur ce répertoire :
chmod 700 ~/.config/helm
chmod 600 ~/.config/helm/helm.yaml
Sur Windows, utilisez les contrôles ACL équivalents pour %USERPROFILE%\AppData\Roaming\helm.
Ajouter des dépôts explicitement et épingler les versions
Évitez d'installer des charts à partir de dépôts inconnus. Ajoutez uniquement des dépôts de confiance et vérifiez leur contenu :
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update
helm search repo bitnami/nginx --versions | head -n 5
La sortie de recherche affiche les versions disponibles. Épinglez votre installation sur une version de chart spécifique au lieu d'utiliser latest :
helm install my-nginx bitnami/nginx --version 15.1.1 --namespace web
L'épinglage empêche un chart mis à jour silencieusement d'introduire une dépendance vulnérable. Si vous devez utiliser un chart local, vérifiez sa provenance avec helm verify après l'avoir signé.
Définir les valeurs avec un fichier de valeurs, pas des indicateurs en ligne de commande
Les indicateurs --set en ligne de commande sont faciles à mal orthographier et exposent les valeurs dans l'historique du shell. Utilisez un fichier de valeurs versionné :
# values-prod.yaml
replicaCount: 3
service:
type: ClusterIP
resources:
limits:
cpu: "1"
memory: 512Mi
Installez avec le fichier :
helm install my-nginx bitnami/nginx --version 15.1.1 --values values-prod.yaml --namespace web
Cette approche rend la configuration révisable et auditable. Ne committez pas de vrais secrets dans ce fichier ; utilisez des espaces réservés ou une solution de gestion des secrets décrite plus loin.
Utiliser des installations et mises à niveau atomiques
L'indicateur --atomic annule automatiquement une version si l'opération échoue. Cela empêche les états à moitié déployés en production :
helm upgrade --install my-nginx bitnami/nginx --version 15.1.1 --values values-prod.yaml --namespace web --atomic --timeout 5m
Résultat attendu : soit la version est déployée avec succès, soit Helm revient à la révision précédente et affiche une erreur. Si la commande expire, augmentez --timeout ou vérifiez l'état des pods avec kubectl get pods -n web.
Gestion des secrets
Helm stocke les métadonnées des versions dans des Secrets Kubernetes par défaut. Ces secrets sont encodés en base64, pas chiffrés, donc toute personne ayant un accès en lecture à l'espace de noms peut les décoder. Pour les secrets applicatifs, les charts nécessitent souvent des mots de passe, jetons ou clés API. Leur gestion sécurisée est essentielle.
Ce que Helm stocke dans les Secrets
Lorsque vous exécutez helm install, Helm crée un Secret comme sh.helm.release.v1.my-nginx.v1 dans l'espace de noms de la version. Il contient le manifeste du chart, les valeurs et les hooks. Inspectez-en un (sans exposer de données sensibles publiquement) :
kubectl get secret sh.helm.release.v1.my-nginx.v1 -n web -o jsonpath='{.data.release}' | base64 -d | gzip -d | head -c 200
Cela montre les données stockées. Comme elles sont seulement encodées en base64, vous devez les chiffrer au repos. Activez le chiffrement des Secrets Kubernetes à l'aide d'un fournisseur KMS, ou utilisez un outil comme Sealed Secrets ou Vault pour gérer les valeurs avant qu'elles n'atteignent Helm.
Modèles de gestion de secrets externes
Ne mettez pas de secrets applicatifs directement dans values.yaml ou dans les secrets de version Helm. Utilisez plutôt l'un de ces modèles :
- Kubernetes External Secrets : Stockez les secrets dans AWS Secrets Manager, GCP Secret Manager ou HashiCorp Vault, et synchronisez-les dans les Secrets Kubernetes. Le chart référence le nom du Secret, pas la valeur.
- Plugin Helm Secrets : Chiffrez le fichier de valeurs avec SOPS ou age avant de le committer dans git.
Par exemple, avec le plugin Helm Secrets utilisant SOPS et age :
# Créer un fichier de valeurs chiffré
helm secrets encrypt secrets.yaml > secrets.yaml.enc
# Déchiffrer et installer
helm secrets install my-app ./chart -f secrets.yaml.enc -n prod
Le plugin déchiffre en mémoire et transmet les valeurs à Helm sans écrire de texte en clair sur le disque. Vérifiez que le chiffrement a fonctionné en contrôlant que le fichier commence par ENC[AES256_GCM,data:.
Utiliser les Secrets Kubernetes pour les informations d'identification
Si vous devez transmettre des informations d'identification à un chart, créez d'abord un Secret Kubernetes, puis référencez-le dans les valeurs du chart :
kubectl create secret generic app-creds --from-literal=password='ChangeMe123!' --namespace prod
Dans votre fichier de valeurs :
existingSecret: app-creds
Le chart doit prendre en charge existingSecret. Beaucoup de charts officiels le font. Cela garde le mot de passe hors de l'historique des versions Helm et de l'historique de votre shell. Faites tourner le mot de passe régulièrement ; par exemple, tous les 90 jours.
Vérification et diagnostic
Après un changement, vérifiez qu'il a fait ce que vous vouliez et n'a rien cassé d'autre. Helm fournit des commandes intégrées pour cela, et vous pouvez les compléter avec des vérifications Kubernetes.
Dry-run avant application
Chaque installation ou mise à niveau doit commencer par un dry-run. Cela rend les modèles et vous montre exactement ce qui serait créé ou modifié :
helm upgrade --install my-nginx bitnami/nginx --version 15.1.1 --values values-prod.yaml --namespace web --dry-run
La sortie inclut chaque ressource Kubernetes et les valeurs utilisées. Cherchez les permissions inattendues, les secrets codés en dur ou les limites de ressources. Si vous voyez un secret avec un vrai mot de passe en clair, arrêtez et corrigez la configuration du chart.
Linter le chart
Si vous développez un chart, exécutez helm lint avant l'empaquetage :
helm lint ./my-chart
La sortie attendue inclut 1 chart(s) linted, 0 chart(s) failed lorsque tout est propre. Les avertissements concernant des champs requis manquants, un mauvais YAML ou des défauts non sécurisés doivent être traités. Ajoutez une étape de lint à votre pipeline CI dans GitLab ou GitHub Actions.
Tester la version
Utilisez helm test pour exécuter les tests du chart dans un cluster actif :
helm test my-nginx -n web
Si le chart définit des tests, vous verrez les journaux des pods et un statut de réussite/échec. Pour les charts sans tests, vérifiez manuellement les ressources clés :
kubectl get pods -n web
kubectl get secrets -n web
Assurez-vous que seuls les pods attendus fonctionnent et qu'aucun secret supplémentaire n'existe.
Vérifier les permissions RBAC créées par le chart
Après l'installation, examinez les objets RBAC :
kubectl get roles,rolebindings,clusterroles,clusterrolebindings -n web
Cherchez les ClusterRoles ou ClusterRoleBindings qui accordent un accès à l'échelle du cluster. Supprimez ceux qui ne sont pas nécessaires. Par exemple, si un chart crée un ClusterRole juste pour lister les pods dans un espace de noms, remplacez-le par un Role.
Modes de défaillance et récupération
Même un durcissement minutieux peut mal tourner. Cette section décrit les défaillances courantes, leurs symptômes et comment récupérer sans perdre de données ni de disponibilité.
La mise à niveau échoue et laisse la version dans un état d'échec
Symptôme : helm upgrade renvoie une erreur, et helm ls montre la version avec STATUS: failed.
Récupération : Revenez à la dernière bonne révision.
helm rollback my-nginx 3 -n web
Vérifiez les révisions disponibles avec helm history my-nginx -n web. Si le rollback échoue également, vous devrez peut-être supprimer la version en échec et réinstaller à partir de votre fichier de valeurs. Avant de supprimer, exportez l'état actuel :
helm get manifest my-nginx -n web > my-nginx-manifest.yaml
Cela préserve le YAML pour inspection.
Secret introuvable pour la version
Symptôme : helm ls fonctionne, mais helm status ou helm rollback renvoie Error: release: not found ou similaire.
Cause : Le Secret Kubernetes sous-jacent a été supprimé accidentellement, ou son nom a été modifié.
Récupération : Recréez la version à partir de votre source de vérité. Installez à nouveau le chart avec les mêmes valeurs :
helm install my-nginx bitnami/nginx --version 15.1.1 --values values-prod.yaml --namespace web
Cela crée une nouvelle révision de version. Pour éviter cela, restreignez les permissions de suppression sur les Secrets dans les espaces de noms de production à un petit ensemble d'opérateurs seulement.
Refus RBAC après resserrement des permissions
Symptôme : Un développeur ou un pipeline CI obtient soudainement Error: query: failed to query with labels: secrets is forbidden lors de l'exécution de helm ls.
Cause : Vous avez restreint les permissions de lecture des Secrets mais avez oublié que Helm doit lire les secrets de version.
Récupération : Accordez les permissions minimales nécessaires. Pour un développeur travaillant dans l'espace de noms dev :
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: helm-user
namespace: dev
rules:
- apiGroups: [""]
resources: ["secrets", "configmaps"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
Liez-le à l'utilisateur ou au compte de service. Évitez les rôles à l'échelle du cluster pour les utilisateurs Helm. Révisez ces permissions trimestriellement pour vous assurer qu'elles correspondent aux besoins actuels.
Le chart extrait une image malveillante
Symptôme : Les pods plantent ou se comportent de manière suspecte après une mise à niveau ; l'analyse d'image signale des vulnérabilités.
Récupération : Revenez immédiatement à la révision précédente avec helm rollback. Ensuite, inspectez la source du chart. Utilisez l'analyse d'images dans votre pipeline CI (par exemple, Trivy, Snyk) et épinglez les balises d'image par digest dans votre fichier de valeurs :
image:
repository: nginx
tag: 1.25.3@sha256:abcdef123456...
Pièges courants et comment les éviter
Plusieurs erreurs récurrentes nuisent à la sécurité Helm. Les reconnaître permet de gagner du temps et de prévenir les incidents de sécurité.
1. Utiliser Helm v2 avec Tiller
Pourquoi cela arrive : des clusters hérités n'ont jamais été migrés, ou des scripts appellent encore helm init. Comment éviter : passez à Helm v3, qui a supprimé Tiller et utilise des appels directs à l'API Kubernetes. Vérifiez s'il existe des binaires helm2 dans vos runners CI et remplacez-les.
2. Committer de vrais secrets dans git
Pourquoi cela arrive : les développeurs utilisent values.yaml par commodité et committent accidentellement des mots de passe ou des jetons. Comment éviter : utilisez des espaces réservés dans les fichiers de valeurs et un outil de gestion des secrets comme Helm Secrets, Sealed Secrets ou External Secrets. Ajoutez des hooks de pré-commit pour rechercher des modèles de secrets (par exemple, gitleaks). Si un secret est committé, faites-le tourner immédiatement et nettoyez l'historique git.
3. RBAC trop large pour les comptes de service Helm
Pourquoi cela arrive : des correctifs rapides accordent cluster-admin à un compte de service CI pour que Helm puisse déployer n'importe où. Comment éviter : accordez le moindre privilège nécessaire. Pour la CI, créez un espace de noms dédié avec un Role et un RoleBinding, pas un ClusterRole. Utilisez kubectl auth can-i --list pour examiner les permissions. Révisez mensuellement.
4. Ignorer la provenance et la signature des charts
Pourquoi cela arrive : les équipes ajoutent des dépôts sans vérifier l'authenticité, croyant que stable ou bitnami sont sûrs par défaut. Comment éviter : vérifiez les signatures des charts avec helm verify après avoir configuré les clés pgp, ou utilisez des fichiers de provenance. Préférez les dépôts ayant un bon historique de sécurité et épinglez les versions de chart.
5. Gonflement des versions et secrets inutilisés
Pourquoi cela arrive : plusieurs mises à niveau laissent de nombreux anciens Secrets de révision, augmentant la surface d'attaque si un ancien secret contient des données sensibles. Comment éviter : limitez l'historique des versions avec --history-max 10 lors des installations ou mises à niveau. Listez périodiquement les versions et nettoyez avec helm uninstall pour les applications obsolètes. Exemple :
helm upgrade my-nginx bitnami/nginx --values values-prod.yaml --namespace web --history-max 10
Liste de contrôle des opérations
Utilisez cette liste avant et après tout changement de sécurité Helm. Attribuez un responsable unique pour chaque élément et révisez la liste mensuellement ou après tout changement significatif.
| Élément | Responsable | Fréquence | Commande / Vérification | Résultat attendu |
|---|---|---|---|---|
| Confirmer que la version Helm est v3+ | Responsable DevOps (ex. Priya Shah) | Trimestriel | helm version --short | v3.12.0 ou ultérieur |
| Confirmer que le contexte kubectl est correct | Opérateur de garde | Avant chaque changement | kubectl config current-context | Nom du cluster de production |
| Lister toutes les versions et espaces de noms | Responsable DevOps | Mensuel | helm ls --all-namespaces | Aucune version inattendue |
| Vérifier le RBAC pour les utilisateurs Helm | Administrateur Kubernetes (ex. Mark Chen) | Mensuel | kubectl auth can-i --list -n <namespace> | Pas de cluster-admin pour les utilisateurs réguliers |
| Vérifier que les secrets sont chiffrés au repos | Ingénieur sécurité | Trimestriel | kubectl get secrets -o yaml et vérifier la config KMS | Les secrets ne sont pas en clair |
| Analyser les images des charts pour les vulnérabilités | Ingénieur sécurité | Hebdomadaire en CI | trivy image <image> | Aucune découverte critique ou élevée |
| Réviser et faire tourner les secrets applicatifs | Propriétaire de l'application (ex. Sarah Lopez) | 90 jours | Suivre la procédure de l'outil de gestion des secrets | Tous les secrets ont tourné avec succès |
| Tester la procédure de rollback | Responsable DevOps | Mensuel | helm rollback <release> <revision> --dry-run | La commande réussit sans erreurs |
| Réviser la provenance des charts | Responsable DevOps | Lors de l'ajout de nouveaux dépôts | helm verify <chart> | Signature valide |
| Mettre à jour Helm et les plugins | Responsable DevOps | Mensuel | helm version, vérifier les versions des plugins | Dernière version stable installée |
Conclusion
Le durcissement de la sécurité Helm n'est pas une correction ponctuelle mais un ensemble de pratiques continues : connaître son environnement, configurer en toute sécurité, gérer les secrets avec chiffrement, vérifier chaque changement et se préparer aux défaillances. Chaque recommandation de ce guide est versionnée, observable et réversible lorsque cela est possible.
Commencez par une vérification à faible risque : exécutez helm ls --all-namespaces, enregistrez la sortie, vérifiez votre version Helm et examinez qui a accès aux secrets de version Helm. Choisissez ensuite le prochain changement le plus petit justifié, comme épingler les versions de chart ou activer --atomic dans votre pipeline CI.
Un flux de travail de durcissement fiable rend les défaillances visibles, protège les valeurs sensibles, limite les changements à la ressource prévue et définit la vérification de récupération avant qu'un incident ne force la décision. Réexaminez votre posture de sécurité Helm trimestriellement et ajustez-la à mesure que votre parc Kubernetes se développe.