Introduction
Les échecs d'autorisation Kubernetes sont généralement silencieux jusqu'à ce qu'un développeur ne puisse pas déployer, qu'un compte de service ne puisse pas lire une ConfigMap, ou qu'un attaquant exploite une liaison trop permissive. Cet article fournit une liste de contrôle opérationnelle pour l'autorisation Kubernetes avec des exemples pratiques qui vous font passer d'un problème observé à un résultat vérifié. Il s'adresse aux développeurs, consultants DevOps et équipes techniques de startups qui exploitent des clusters et doivent gérer en toute sécurité le contrôle d'accès basé sur les rôles (RBAC), les politiques d'admission et les accès API.
La liste de contrôle relie les opérations d'autorisation Kubernetes, les listes de contrôle, les bonnes pratiques et la maintenance à des commandes concrètes, des sorties attendues, des signaux d'échec et des décisions 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 au lieu de secrets, vérifier chaque résultat et documenter les chemins de récupération avant qu'un incident ne survienne.
Tout au long de ce guide, nous utilisons un exemple courant : une startup exploitant un cluster de production sur Kubernetes 1.28 avec une application web et une API backend. Les espaces de noms incluent web, api et infra. Nous utiliserons un compte de service nommé web-sa et un utilisateur développeur alice. Toutes les commandes supposent que kubectl est configuré avec des droits d'administrateur de cluster appropriés pour l'inspection, mais nous montrerons comment opérer avec le moindre privilège lorsque cela est possible.
Inventaire de la version et de l'environnement
Avant de modifier les paramètres d'autorisation, vous devez savoir exactement ce qui est en cours d'exécution. Le comportement d'autorisation change entre les versions de Kubernetes, et un RBAC mal configuré peut être masqué par des serveurs API obsolètes ou des contrôleurs d'admission incompatibles.
Prérequis et observation en lecture seule
La première étape de toute opération d'autorisation consiste à enregistrer la version du cluster, les drapeaux du serveur API liés à l'autorisation et l'état actuel du RBAC. Exécutez ces commandes et enregistrez la sortie avec horodatage :
kubectl version --short
kubectl get --raw /metrics | grep apiserver_authorization
Sortie attendue pour un cluster sain sur Kubernetes 1.28 :
Client Version: v1.28.0
Server Version: v1.28.0
apiserver_authorization_decision_total{result="allow",verb="get",resource="pods"} 42
apiserver_authorization_decision_total{result="deny",verb="list",resource="secrets"} 2
Si la métrique du serveur montre des refus inattendus pour des opérations de lecture sur des ressources courantes, c'est un signal pour auditer les règles RBAC. Ensuite, inspectez le mode d'autorisation du serveur API. Cela est généralement configuré dans le manifeste kube-apiserver ou l'unité systemd.
kubectl -n kube-system get pod -l component=kube-apiserver -o yaml | grep -A5 'command:'
Recherchez --authorization-mode=RBAC,Node ou similaire. Si AlwaysAllow est présent, l'autorisation est effectivement désactivée pour toutes les requêtes sauf celles gérées par le contrôle d'admission. En production, c'est une constatation critique.
Plus petit changement justifié
Ne changez pas les modes d'autorisation sans fenêtre de maintenance et plan de rollback. Si vous devez activer RBAC sur un cluster qui utilisait AlwaysAllow, créez d'abord un ensemble complet de rôles et de liaisons dans un environnement de staging, vérifiez-les par rapport à une copie du trafic de production, puis changez de mode avec le redémarrage du serveur API.
Par exemple, pour vérifier que RBAC est actif et appliqué, exécutez :
kubectl auth can-i list pods --as system:serviceaccount:web:web-sa -n web
Sortie attendue pour un compte de service correctement restreint qui n'a pas la permission de lister :
no
Si la sortie est yes et que vous attendiez no, examinez les liaisons dans l'espace de noms web.
Chemin de configuration sûr
Les changements de configuration d'autorisation doivent suivre un chemin allant des tests locaux à la production avec vérification à chaque étape. Le principe clé est de séparer l'observation de l'intervention : capturez d'abord l'état actuel, protégez les informations d'identification et ne modifiez qu'un seul élément ciblé lorsque son rayon d'impact et son chemin de récupération sont compris.
Test local avec un seul manifeste
Commencez avec un rôle et une liaison de rôle minimaux dans un espace de noms de test dédié. Supposons que vous vouliez accorder au compte de service web-sa la permission de lire les ConfigMaps dans l'espace de noms web mais rien d'autre. Créez le fichier manifeste suivant web-configmap-reader.yaml :
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: web
name: configmap-reader
rules:
- apiGroups: [""]
resources: ["configmaps"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
namespace: web
name: web-sa-configmap-reader
subjects:
- kind: ServiceAccount
name: web-sa
namespace: web
roleRef:
kind: Role
name: configmap-reader
apiGroup: rbac.authorization.k8s.io
Appliquez-le à un cluster de test local (comme kind ou minikube) :
kubectl apply -f web-configmap-reader.yaml --dry-run=client -o yaml
kubectl apply -f web-configmap-reader.yaml
Vérifiez ensuite la permission avec auth can-i :
kubectl auth can-i get configmaps --as system:serviceaccount:web:web-sa -n web
Attendu : yes.
kubectl auth can-i get secrets --as system:serviceaccount:web:web-sa -n web
Attendu : no.
Cela valide que la règle est correctement délimitée avant de passer à un environnement partagé.
Déploiement contrôlé par version
Une fois le test local réussi, stockez le manifeste dans Git avec un processus de revue. Utilisez un outil comme Kustomize ou Helm pour gérer la ressource. Par exemple, une surcouche Kustomize pour la production peut ajuster l'espace de noms ou ajouter des étiquettes. Appliquez à un cluster de staging qui reflète le RBAC de production et exécutez une série de tests positifs et négatifs.
Après vérification en staging, appliquez à la production avec une commande enregistrée et une sortie attendue :
kubectl apply -f deploy/prod/web-configmap-reader.yaml
Sortie attendue :
role.rbac.authorization.k8s.io/configmap-reader unchanged
rolebinding.rbac.authorization.k8s.io/web-sa-configmap-reader configured
Vérifiez ensuite immédiatement que le compte de service peut lister les ConfigMaps et ne peut toujours pas lister les Secrets :
kubectl auth can-i list configmaps --as system:serviceaccount:web:web-sa -n web
kubectl auth can-i list secrets --as system:serviceaccount:web:web-sa -n web
Attendu : yes puis no.
Si la deuxième commande renvoie yes, annulez immédiatement la liaison :
kubectl delete rolebinding web-sa-configmap-reader -n web
Vérification et diagnostic
Les problèmes d'autorisation se manifestent souvent par des erreurs API déroutantes. Un pod peut échouer avec un message Forbidden, ou un contrôleur peut cesser de réconcilier. La clé est de collecter des preuves avant de changer quoi que ce soit.
Diagnostiquer une requête refusée
La première étape consiste à reproduire le refus du point de vue de l'identité affectée. Si un développeur signale qu'il ne peut pas déployer, demandez-lui d'exécuter :
kubectl auth can-i create deployments --as alice -n api
Si la sortie est no, inspectez les rôles et liaisons d'Alice :
kubectl get rolebindings,clusterrolebindings -o wide | grep alice
kubectl describe clusterrolebinding alice-api-binding
Cela montre les rôles attribués. Inspectez ensuite les règles du rôle :
kubectl describe clusterrole alice-api-role
Sortie attendue pour un rôle qui accorde la création de déploiements :
Name: alice-api-role
Labels: <none>
Annotations: <none>
PolicyRule:
Resources Non-Resource URLs Resource Names Verbs
--------- ----------------- -------------- -----
deployments.apps [] [] [create]
Si le verbe create est manquant, c'est la cause racine. Vous pouvez également consulter le journal d'audit API s'il est activé. Recherchez des entrées avec "verb":"create","resource":"deployments","user":"alice","stage":"ResponseComplete","responseStatus":{"code":403}. Cela confirme que la décision a été prise au stade de l'autorisation.
Utiliser kubectl auth reconcile
Lorsque vous avez de nombreux rôles et liaisons, l'inspection manuelle est sujette aux erreurs. Utilisez kubectl auth reconcile pour comparer l'état souhaité dans vos manifestes avec l'état réel du cluster. Cette commande est sûre car elle ne fait qu'ajouter ou mettre à jour des règles ; elle ne supprime pas les permissions à moins d'utiliser le drapeau --remove-extra-permissions.
Tout d'abord, générez une base de référence du RBAC actuel :
kubectl get roles,rolebindings,clusterroles,clusterrolebindings -A -o yaml > rbac-backup-$(date +%Y%m%d).yaml
Ensuite, exécutez la réconciliation avec vos fichiers source de vérité :
kubectl auth reconcile -f deploy/prod/rbac/
Sortie attendue pour un cluster présentant une dérive :
clusterrole.rbac.authorization.k8s.io/alice-api-role reconciled
rolebinding.rbac.authorization.k8s.io/web-sa-configmap-reader reconciled
Après la réconciliation, réexécutez les vérifications auth can-i pour vous assurer que les permissions prévues sont en vigueur et qu'aucune permission non intentionnelle n'a été ajoutée. Examinez toujours la sortie du diff avant d'appliquer avec --remove-extra-permissions.
Modes d'échec et récupération
Les mauvaises configurations d'autorisation peuvent provoquer des pannes immédiates ou des vulnérabilités de sécurité latentes. Cette section couvre trois modes d'échec courants et la récupération étape par étape.
Mode d'échec 1 : ClusterRoleBinding trop permissif
Symptôme : Un pod compromis peut lire tous les secrets du cluster.
Détection : Effectuez un audit de permissions en utilisant kubectl auth can-i --list pour un compte de service suspect :
kubectl auth can-i --list --as system:serviceaccount:web:web-sa -n web
La sortie attendue inclut list secrets dans tous les espaces de noms si la liaison est trop large.
Récupération : Identifiez la ClusterRoleBinding fautive :
kubectl get clusterrolebindings -o yaml | grep -B5 -A10 web-sa
Supprimez la liaison :
kubectl delete clusterrolebinding web-sa-cluster-admin
Revérifiez ensuite :
kubectl auth can-i list secrets --as system:serviceaccount:web:web-sa -n web
kubectl auth can-i list secrets --as system:serviceaccount:web:web-sa -n api
Attendu : no pour les deux.
Enfin, appliquez une RoleBinding à moindre privilège comme décrit dans la section Chemin de configuration sûr.
Mode d'échec 2 : Permission manquante provoquant un échec de démarrage de pod
Symptôme : Un nouveau pod échoue avec Error: configmaps "app-config" is forbidden: User "system:serviceaccount:api:api-sa" cannot get resource "configmaps" in API group "" in the namespace "api".
Détection : Les événements du pod montrent l'erreur :
kubectl describe pod api-deployment-7f8c9d5b6-abcde -n api
Recherchez les événements FailedMount ou FailedSync avec le message interdit.
Récupération : Ajoutez la permission manquante au compte de service api-sa. Créez un rôle et une liaison de rôle exactement comme nécessaire, appliquez, puis redémarrez le déploiement :
kubectl apply -f api-configmap-reader.yaml
kubectl rollout restart deployment/api-deployment -n api
kubectl rollout status deployment/api-deployment -n api
Sortie attendue pour un déploiement réussi :
deployment "api-deployment" successfully rolled out
Si le déploiement ne réussit pas, vérifiez les journaux du pod pour le type d'erreur précédent. Si une autre erreur interdite apparaît, répétez l'analyse des permissions.
Mode d'échec 3 : Contrôleur d'admission webhook bloquant les requêtes légitimes
Symptôme : Même avec un RBAC correct, les requêtes sont refusées avec un message comme admission webhook "validation.example.com" denied the request.
Détection : Vérifiez la configuration du webhook d'admission et son service associé :
kubectl get validatingwebhookconfigurations
kubectl describe validatingwebhookconfiguration validation-example-com
Examinez les politiques d'échec et si le service webhook est joignable. Si le webhook a failurePolicy: Fail et que le service backend est en panne, toutes les requêtes correspondantes sont refusées.
Récupération : Si le webhook n'est pas nécessaire pour la requête spécifique, vous pouvez temporairement modifier sa failurePolicy en Ignore après avoir évalué les implications de sécurité :
kubectl patch validatingwebhookconfiguration validation-example-com --type='json' -p='[{"op": "replace", "path": "/webhooks/0/failurePolicy", "value": "Ignore"}]'
Réessayez ensuite la requête en échec. Si elle réussit, corrigez le service backend du webhook. Une fois restauré, rétablissez la politique d'échec :
kubectl patch validatingwebhookconfiguration validation-example-com --type='json' -p='[{"op": "replace", "path": "/webhooks/0/failurePolicy", "value": "Fail"}]'
Documentez toujours ces changements temporaires et assurez-vous que la surveillance alerte sur les échecs du webhook.
Liste de contrôle des opérations
Utilisez la liste de contrôle suivante avant et après tout changement d'autorisation. Chaque élément comprend une commande ou une étape de vérification avec la sortie attendue.
| # | Élément de la liste de contrôle | Commande / vérification | Sortie attendue |
|---|---|---|---|
| 1 | Enregistrer la version du cluster et le mode d'autorisation | kubectl version --short et inspecter les drapeaux du serveur API | Version serveur v1.28.0 ; --authorization-mode=RBAC,Node |
| 2 | Sauvegarder l'état RBAC actuel | kubectl get roles,rolebindings,clusterroles,clusterrolebindings -A -o yaml > rbac-backup-$(date +%Y%m%d).yaml | Fichier créé sans erreurs |
| 3 | Identifier l'identité et l'espace de noms affectés | kubectl auth can-i --list --as system:serviceaccount:web:web-sa -n web | Liste des permissions pour le compte de service |
| 4 | Tester le changement dans un cluster local avec essai à blanc d'abord | kubectl apply -f web-configmap-reader.yaml --dry-run=client -o yaml | Sortie YAML sans erreurs |
| 5 | Appliquer le changement avec contrôle de version | kubectl apply -f deploy/prod/web-configmap-reader.yaml | rolebinding... configured |
| 6 | Vérifier la permission positive | kubectl auth can-i get configmaps --as system:serviceaccount:web:web-sa -n web | yes |
| 7 | Vérifier la permission négative (moindre privilège) | kubectl auth can-i get secrets --as system:serviceaccount:web:web-sa -n web | no |
| 8 | Vérifier la dérive des permissions non intentionnelles | kubectl auth reconcile -f deploy/prod/rbac/ --dry-run=client -o yaml | Montre les différences sans appliquer |
| 9 | Examiner les journaux d'audit si disponibles | grep 'responseStatus":{"code":403' /var/log/kubernetes/audit/audit.log | Requêtes refusées pertinentes |
| 10 | Documenter le changement et le plan de rollback | Mettre à jour le runbook avec kubectl delete rolebinding web-sa-configmap-reader -n web comme rollback | Runbook créé |
| 11 | Surveiller après le changement | kubectl get events -n web --sort-by='.lastTimestamp' | Aucun nouvel événement Forbidden |
Cette liste de contrôle garantit que chaque changement d'autorisation est observable, réversible et aligné sur le moindre privilège.
Conclusion
Les opérations d'autorisation Kubernetes exigent une approche délibérée et limitée à la version. La liste de contrôle de cet article vous aide à vérifier l'environnement, à tester les changements en toute sécurité, à diagnostiquer les refus, à récupérer des échecs et à maintenir le moindre privilège. Chaque étape comprend des commandes concrètes et des sorties attendues afin que les opérateurs puissent suivre et s'adapter à leurs propres clusters.
Commencez par une amélioration à faible risque : auditez un seul compte de service à l'aide de kubectl auth can-i --list, identifiez les sur-permissions et remplacez les liaisons larges par des rôles étroitement ciblés. Enregistrez l'état actuel, appliquez le changement dans un cluster de staging d'abord, vérifiez les opérations autorisées et refusées, et documentez la commande de rollback.
Un flux de travail d'autorisation fiable rend les échecs visibles, protège les informations d'identification sensibles, limite les changements à la ressource prévue et définit la vérification de récupération avant qu'un incident ne force une décision précipitée. En intégrant ces pratiques dans vos opérations, vous réduisez le risque de temps d'arrêt et de violations de sécurité.