Introduction
Faire fonctionner le RBAC Kubernetes en production est différent de l'activer dans un cluster de test. Les erreurs d'accès peuvent bloquer les charges de travail, accorder plus de privilèges que prévu ou laisser des autorisations obsolètes qui survivent à une revue d'incident. Ce guide est une liste de vérification opérationnelle pratique pour travailler avec le RBAC Kubernetes en production. Il couvre l'inventaire de la version et de l'environnement, les modifications de configuration sécuritaires, la vérification et les diagnostics, les modes de défaillance et la récupération, ainsi qu'une liste de vérification opérationnelle quotidienne.
Chaque section comprend des commandes concrètes, les sorties attendues, les signaux de défaillance et les étapes 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 le résultat et documenter comment récupérer si l'état attendu n'est pas atteint.
Inventaire de la version et de l'environnement
Avant de toucher aux objets RBAC, établissez la version du cluster, la disponibilité de l'API et l'état actuel des ressources RBAC. Cet inventaire crée une base de référence et vous aide à remarquer les dérives plus tard.
Commencez par la version du cluster :
kubectl version --short
Exemple de sortie attendue :
Client Version: v1.29.2
Kustomize Version: v5.0.4-0.20230601165947-6ce0bf390ce3
Server Version: v1.29.2
Si les versions majeures du client et du serveur diffèrent de plus d'une version mineure, certains champs RBAC peuvent être indisponibles ou se comporter différemment. Par exemple, l'annotation kubernetes.io/bootstrapping a été dépréciée mais peut encore apparaître dans les clusters mis à niveau depuis des versions plus anciennes.
Vérifiez que l'API RBAC est activée (elle l'est par défaut dans toutes les versions de Kubernetes prises en charge) en listant les rôles dans un espace de noms (namespace) :
kubectl get roles -n kube-system
Si vous voyez No resources found, l'espace de noms peut n'avoir aucun rôle, ou vous n'avez peut-être pas la permission de lister les rôles. Vérifiez vos propres permissions avec :
kubectl auth can-i list roles -n kube-system
Cela devrait renvoyer yes pour un cluster-admin ou un utilisateur disposant des droits appropriés.
Ensuite, inventoriez les rôles existants, les liaisons de rôles, les rôles de cluster et les liaisons de rôles de cluster. Utilisez des commandes en lecture seule et enregistrez la sortie dans des fichiers pour une comparaison ultérieure :
kubectl get roles,rolebindings --all-namespaces -o yaml > rbac-namespaced-backup.yaml
kubectl get clusterroles,clusterrolebindings -o yaml > rbac-cluster-backup.yaml
Pour un résumé lisible par l'humain, utilisez :
kubectl get rolebindings,clusterrolebindings --all-namespaces
Recherchez les liaisons qui accordent l'accès à des comptes de service en dehors de leur propre espace de noms, en particulier dans kube-system, kube-public et tout espace de noms default. Ce sont des sources courantes de privilèges inattendus.
Consultez les notes de version RBAC de la version Kubernetes pour tout changement. Par exemple, dans Kubernetes 1.24, la projection héritée serviceAccountToken a été entièrement remplacée par BoundServiceAccountTokenVolume. Si vos charges de travail utilisent encore des jetons hérités, les décisions RBAC peuvent être basées sur un ancien sujet de jeton.
Enfin, enregistrez l'état actuel avec des horodatages :
date -u +"Inventory run: %Y-%m-%dT%H:%M:%SZ"
kubectl get clusterroles --show-labels
Conservez ces sauvegardes dans un emplacement sécurisé, pas dans le cluster lui-même.
Chemin de configuration sécuritaire
Les changements RBAC consistent à accorder ou révoquer l'accès. Une fausse manœuvre peut casser une charge de travail en cours d'exécution ou ouvrir un trou de sécurité. Le chemin de configuration sécuritaire est une séquence d'observer, planifier, appliquer, vérifier et documenter.
Étape 1 : Lire la configuration actuelle
Avant de modifier un rôle, voyez quels privilèges il possède déjà :
kubectl get role my-app-role -n my-namespace -o yaml
Si le rôle est lié à plusieurs sujets, listez toutes les liaisons :
kubectl get rolebinding -n my-namespace -o yaml | grep -B5 -A5 "name: my-app-role"
Étape 2 : Faire le plus petit changement
Supposons que le rôle my-app-role accorde actuellement get, list et watch sur les déploiements, mais qu'une nouvelle fonctionnalité nécessite create sur les pods. Au lieu d'accorder * sur toutes les ressources, ajoutez uniquement la permission requise.
Créez un nouveau fichier de rôle ou patchez l'existant. L'utilisation d'un flux de travail GitOps est recommandée. Pour un patch rapide :
kubectl patch role my-app-role -n my-namespace --type='json' -p='[{"op": "add", "path": "/rules/0/verbs", "value": ["get", "list", "watch", "create"]}]'
Important : Ce qui précède ajoute create à la première règle. Si la première règle n'est peut-être pas la règle des déploiements, inspectez d'abord le YAML et ajustez le chemin en conséquence. Une approche plus sûre consiste à éditer le manifeste localement et à l'appliquer :
# my-app-role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: my-app-role
namespace: my-namespace
rules:
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["pods"]
verbs: ["create"]
Appliquez-le :
kubectl apply -f my-app-role.yaml
Étape 3 : Utiliser dry-run pour prévisualiser les changements
Avant d'appliquer tout changement, exécutez un dry-run pour voir ce qui se passerait :
kubectl apply -f my-app-role.yaml --dry-run=client -o yaml
Cela imprime l'objet qui serait envoyé au serveur d'API. Pour une validation plus précise, utilisez --dry-run=server si votre cluster le prend en charge :
kubectl apply -f my-app-role.yaml --dry-run=server
Le serveur validera l'objet par rapport au schéma de l'API et aux webhooks d'admission sans le persister.
Étape 4 : Appliquer et vérifier immédiatement
Après l'application, vérifiez le rôle :
kubectl get role my-app-role -n my-namespace -o yaml
Utilisez kubectl auth can-i pour tester l'accès en tant que sujet. Si le sujet est un compte de service nommé my-app-sa dans my-namespace, exécutez :
kubectl auth can-i create pods --as=system:serviceaccount:my-namespace:my-app-sa -n my-namespace
Cela devrait renvoyer yes.
Étape 5 : Documenter le changement
Enregistrez le changement dans le journal des modifications de votre équipe ou le système de gestion des incidents. Incluez la date, la raison, le diff exact et le plan de retour en arrière (rollback).
Vérification et diagnostics
La vérification va au-delà de la simple existence de l'objet. Vous devez vous assurer que la décision RBAC correspond à votre intention et qu'il n'y a pas de conséquences imprévues.
Vérifier les permissions effectives avec auth can-i
La manière la plus directe est d'usurper l'identité du sujet :
kubectl auth can-i --list --as=system:serviceaccount:my-namespace:my-app-sa -n my-namespace
Cela liste toutes les permissions que le compte de service possède dans cet espace de noms. Recherchez les verbes que vous n'aviez pas l'intention d'accorder.
Pour une permission spécifique :
kubectl auth can-i update deployments/scale --as=system:serviceaccount:my-namespace:my-app-sa -n my-namespace
Si cela renvoie no, vérifiez pourquoi.
Tracer les liaisons de rôles
Pour voir tous les sujets liés à un rôle :
kubectl get rolebinding -n my-namespace -o json | jq '.items[] | select(.roleRef.name=="my-app-role") | .subjects'
Cela montre les comptes de service, utilisateurs ou groupes qui reçoivent les permissions du rôle.
Vérifier les journaux d'audit du serveur d'API
Si la journalisation d'audit est activée (comme elle devrait l'être en production pour les charges de travail critiques en matière de sécurité), recherchez les demandes refusées :
# Exemple de ligne de journal d'audit pour une demande refusée :
{"kind":"Event","apiVersion":"audit.k8s.io/v1","level":"RequestResponse","auditID":"1234","stage":"ResponseComplete","requestURI":"/api/v1/namespaces/my-namespace/pods","verb":"create","user":{"username":"system:serviceaccount:my-namespace:my-app-sa","groups":["system:serviceaccounts","system:serviceaccounts:my-namespace"]},"responseStatus":{"code":403,"reason":"Forbidden"}}
Utilisez votre outil d'agrégation de journaux pour filtrer les réponses 403 et les corréler avec les changements RBAC.
Utiliser des outils de linting de politique RBAC
Des outils comme kubectl-who-can (d'Aqua Security) ou rakkess peuvent vous aider à comprendre qui peut faire quoi :
kubectl who-can create pods -n my-namespace
Exemple de sortie attendue :
ROLE NAMESPACE SUBJECT
my-app-role my-namespace ServiceAccount/my-app-sa
Cela confirme que seul le sujet prévu a cette permission.
Vérifier avec un pod de test réel
Pour les permissions critiques, créez un pod temporaire utilisant le compte de service et tentez l'action :
kubectl run test-pod --image=bitnami/kubectl:latest --restart=Never -n my-namespace --overrides='{"spec":{"serviceAccountName":"my-app-sa"}}' --command -- sleep 3600
kubectl exec -it test-pod -n my-namespace -- kubectl auth can-i create pods -n my-namespace
Si la sortie est yes, la permission est effective. Nettoyez le pod de test :
kubectl delete pod test-pod -n my-namespace
Modes de défaillance et récupération
Les défaillances RBAC peuvent provoquer des pannes d'application ou des incidents de sécurité. Voici des modes de défaillance courants et des étapes de récupération.
Défaillance : La charge de travail reçoit 403 Forbidden
Symptôme : Les pods plantent ou les applications consignent des erreurs 403 Forbidden lors de l'accès à l'API Kubernetes.
Diagnostic : Vérifiez les journaux du pod :
kubectl logs my-app-pod -n my-namespace --tail=50
Recherchez des lignes comme :
Error: GET https://kubernetes.default.svc:443/api/v1/namespaces/my-namespace/pods: 403 Forbidden
Ensuite, vérifiez les permissions du compte de service :
kubectl auth can-i --list --as=system:serviceaccount:my-namespace:my-app-sa -n my-namespace
Récupération : Identifiez le verbe/ressource manquant dans l'erreur et ajoutez-le au rôle lié au compte de service. Utilisez le chemin de configuration sécuritaire ci-dessus. Après l'application, redémarrez le pod ou attendez que le client réessaie.
Défaillance : L'utilisateur ne peut pas effectuer une action
Symptôme : Un développeur signale que kubectl get pods renvoie Error from server (Forbidden): pods is forbidden...
Diagnostic : Vérifiez l'identité de l'utilisateur et les appartenances aux groupes :
kubectl auth whoami
Si cela renvoie l'utilisateur, vérifiez ses permissions avec :
kubectl auth can-i list pods --as=developer-sara -n dev
Vérifiez également les liaisons de rôles pour l'utilisateur :
kubectl get rolebindings,clusterrolebindings -o json | jq '.items[] | select(.subjects[]?.name=="developer-sara")'
Récupération : Si l'utilisateur devrait avoir la permission, créez ou mettez à jour une liaison de rôle. Sinon, refusez la demande et expliquez la politique.
Défaillance : Escalade de privilèges accidentelle
Symptôme : Un rôle ou un rôle de cluster a été modifié pour inclure les verbes ou ressources *, ou une liaison de rôle a été créée pour un sujet non prévu.
Diagnostic : Utilisez votre piste d'audit GitOps ou les journaux d'audit du cluster pour trouver le changement. Comparez avec la sauvegarde de l'étape d'inventaire :
diff -u rbac-cluster-backup.yaml <(kubectl get clusterroles,clusterrolebindings -o yaml)
Récupération : Annulez le changement en appliquant le manifeste précédent depuis le contrôle de version :
kubectl apply -f known-good-rolebinding.yaml
Si le cluster a été compromis, vous devrez peut-être révoquer tous les jetons et faire tourner les informations d'identification. Suivez votre plan de réponse aux incidents.
Défaillance : Liaisons de rôles obsolètes après suppression d'un espace de noms
Symptôme : L'espace de noms a été supprimé, mais les liaisons de rôles de cluster référençant des comptes de service dans cet espace de noms persistent.
Diagnostic : Listez les liaisons de rôles de cluster et recherchez les sujets avec des espaces de noms inexistants :
kubectl get clusterrolebindings -o json | jq '.items[] | select(.subjects[]?.namespace != null and (.subjects[]?.namespace | IN( ($kubectl get namespaces -o json | jq -r '.items[].metadata.name') ) | not))'
Ceci est une requête jq complexe ; une approche plus simple consiste à examiner manuellement les liaisons suspectes.
Récupération : Supprimez ou mettez à jour la liaison obsolète :
kubectl delete clusterrolebinding stale-binding
Défaillance : Permission RBAC manquante casse une mise à niveau
Symptôme : Après la mise à niveau d'un chart ou d'un opérateur, celui-ci échoue avec des erreurs de permission.
Diagnostic : Vérifiez les journaux de l'opérateur et comparez les permissions requises avec le rôle installé. De nombreux opérateurs ont un ensemble documenté de rôles de cluster ; consultez leur manifeste d'installation.
Récupération : Mettez à jour le rôle de cluster de l'opérateur pour inclure les nouvelles permissions. Si vous utilisez un chart, réexécutez helm upgrade avec les valeurs mises à jour qui spécifient le RBAC requis.
Liste de vérification opérationnelle
Utilisez cette liste régulièrement (chaque semaine ou après tout changement) pour maintenir l'hygiène RBAC.
1. Inventorier les rôles et liaisons
Exécutez :
kubectl get roles,rolebindings,clusterroles,clusterrolebindings --all-namespaces -o yaml > rbac-full-backup-$(date +%Y%m%d).yaml
Stockez la sauvegarde en lieu sûr et diff contre la semaine précédente pour repérer les changements.
2. Vérifier les rôles trop permissifs
Recherchez tout rôle ou rôle de cluster avec * dans les verbes ou ressources :
kubectl get clusterroles -o json | jq '.items[] | select(.rules[]?.verbs[]? == "*" or .rules[]?.resources[]? == "*") | .metadata.name'
Examinez chaque résultat et justifiez le besoin. Remplacez * par des listes explicites lorsque c'est possible.
3. Valider l'utilisation des comptes de service
Assurez-vous que chaque compte de service est lié à au moins un rôle et a un objectif clair :
kubectl get serviceaccounts --all-namespaces
Vérifiez les comptes de service non utilisés :
kubectl get pods --all-namespaces -o json | jq -r '.items[] | .spec.serviceAccountName' | sort -u
Comparez les deux listes pour trouver les comptes de service non utilisés par aucun pod.
4. Tester les permissions critiques
Pour les comptes de service clés (CI/CD, surveillance, gitops), exécutez :
kubectl auth can-i --list --as=system:serviceaccount:ci-namespace:ci-sa
Vérifiez que les permissions correspondent à la charge de travail prévue.
5. Auditer les liaisons pour les utilisateurs externes
Si vous utilisez des utilisateurs OIDC ou basés sur certificats, listez toutes les liaisons de rôles de cluster avec des sujets utilisateurs :
kubectl get clusterrolebindings -o json | jq '.items[] | select(.subjects[]?.kind == "User")'
Assurez-vous que chaque liaison est toujours nécessaire.
6. Vérifier les rôles par défaut et de bootstrapping
Certains clusters ont des liaisons system:basic-user ou system:discovery qui peuvent accorder plus que souhaité. Examinez :
kubectl get clusterrolebindings | grep -E 'system:basic-user|system:discovery'
7. Vérifier RBAC avec des outils de politique
Exécutez un outil de politique comme kube-rbac-proxy, kubescape ou les politiques OPA Gatekeeper par rapport aux configurations RBAC. Par exemple, avec kubescape :
kubescape scan framework nsa --include-namespaces kube-system
8. Documenter les exceptions et approbations
Tenez un registre des exceptions RBAC. Dans le registre, incluez :
| Élément | Approbateur | Date | Expiration | Lien vers l'approbation |
|---|---|---|---|---|
developer-sara ajouté au rôle de cluster view pour le débogage de garde | Priya Shah, responsable d'ingénierie | 2025-05-14 | 2025-05-21 | https://tickets.example.com/INC-1234 |
Compte de service CI accordé create sur deployments dans staging | Marcus Chen, responsable DevOps | 2025-05-10 | Permanent avec revue trimestrielle | https://wiki.example.com/rbac/ci-staging |
Conclusion
Le RBAC Kubernetes en production nécessite une attention continue. La liste de vérification de cet article vous donne une manière structurée d'inventorier les permissions, d'apporter des modifications sûres, de vérifier les résultats et de récupérer des défaillances. Les principes clés sont :
- Toujours observer et sauvegarder avant de modifier les objets RBAC.
- Faire le plus petit changement qui répond à l'exigence.
- Utiliser dry-run et l'usurpation d'identité pour vérifier avant et après.
- Garder une piste d'audit et planifier des revues régulières.
- Avoir un plan de retour en arrière pour chaque changement.
En suivant ces pratiques, vous pouvez maintenir une posture RBAC sécurisée et opérationnelle. Commencez par une vérification à faible risque : exécutez kubectl auth can-i --list --as=system:serviceaccount:default:default dans un espace de noms non productif pour voir ce que le compte de service par défaut peut faire. Ensuite, étendez votre inventaire et corrigez toute surprise.
Un flux de travail technique 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.