## Introduction Le contrôle d'accès basé sur les rôles (RBAC) de Kubernetes est le mécanisme principal pour réguler l'accès aux ressources du cluster. Il répond à deux questions fondamentales : qui peut faire quoi, et où peut-il le faire ? Sans une stratégie RBAC solide, un cluster peut rapidement devenir un incident de sécurité en puissance, que ce soit à cause d'un conteneur compromis, d'un employé mécontent ou d'une simple erreur humaine. Une configuration RBAC bien mise en œuvre garantit que les utilisateurs et les applications n'ont que les permissions dont ils ont besoin, rien de plus. Ce principe du moindre privilège n'est pas seulement un plus ; c'est une exigence pour les cadres de conformité comme SOC 2, ISO 27001 et PCI DSS. Cela rend également les opérations quotidiennes plus sûres, car un compte de service trop permissif ne peut pas supprimer accidentellement un namespace de production. Cet article est un guide pratique du RBAC Kubernetes. Nous expliquerons les composants de base, montrerons comment ils interagissent et détaillerons un chemin de mise en œuvre sûr avec des exemples concrets. Vous apprendrez à vérifier votre configuration RBAC, à diagnostiquer les problèmes courants et à récupérer après des échecs. À la fin, vous disposerez d'une liste de contrôle opérationnelle pour garder votre cluster sécurisé et conforme. ## Inventaire de la version et de l'environnement Avant de plonger dans la configuration RBAC, faites le point sur votre environnement Kubernetes. Le RBAC est stable et activé par défaut depuis Kubernetes v1.8, mais les versions plus récentes peuvent introduire de nouveaux groupes d'API ou en déprécier d'anciens. Pour ce guide, nous supposons : - Version du cluster Kubernetes 1.24 ou ultérieure. - Client kubectl version correspondante ou plus récente que le cluster. - Accès au cluster avec des privilèges cluster-admin pour la configuration initiale. - Une compréhension claire de votre base d'utilisateurs : utilisateurs humains (via des fournisseurs d'authentification) et comptes de service pour les applications. Vérifiez la version de votre cluster : ```bash kubectl version --short ``` Sortie attendue (exemple) : ```text Client Version: v1.28.0 Server Version: v1.28.0 ``` Identifiez le mécanisme d'authentification en place. Kubernetes ne gère pas nativement les comptes d'utilisateurs ; l'identité provient de systèmes externes comme les certificats clients X.509, les fournisseurs OpenID Connect (OIDC) ou l'IAM cloud. Les comptes de service, en revanche, sont gérés par Kubernetes lui-même. Listez les comptes de service existants dans le namespace par défaut : ```bash kubectl get serviceaccounts ``` Sortie attendue (exemple) : ```text NAME SECRETS AGE default 0 10d ``` Le RBAC est additif : il n'y a pas de règles de refus. Si un utilisateur a plusieurs liaisons de rôle, ses permissions effectives sont l'union de toutes les permissions accordées. Cela signifie que vous devez faire attention à ne pas accorder accidentellement plus d'accès que prévu via des rôles qui se chevauchent. Planifiez la conception de vos rôles autour des fonctions réelles : développeurs, opérateurs, auditeurs, systèmes CI/CD, etc. Chaque fonction doit correspondre à un ensemble clair d'actions autorisées sur des ressources spécifiques dans des namespaces spécifiques. Enfin, assurez-vous d'avoir une méthode d'accès de secours avant d'apporter des modifications RBAC. Cela peut être le compte racine d'un fournisseur cloud, un kubeconfig statique avec cluster-admin, ou un utilisateur d'urgence défini dans votre fournisseur d'identité. Perdre tout accès administratif à un cluster est un scénario de récupération douloureux entièrement évitable avec une bonne planification. ## Chemin de configuration sûr Une approche sûre du RBAC est incrémentale. Commencez par des rôles minimaux et ne les étendez que lorsqu'un besoin clair se présente. Évitez les permissions génériques telles que `*` pour les ressources ou les verbes sauf en cas de nécessité absolue, et limitez toujours les permissions à la plus petite frontière possible, généralement un namespace. ### Composants de base du RBAC Le RBAC repose sur quatre types d'objets : - **Role** : définit les permissions au sein d'un seul namespace. - **ClusterRole** : définit les permissions à l'échelle du cluster ou pour des ressources cluster-scoped comme les nœuds ou les volumes persistants. Un ClusterRole peut également être utilisé pour accorder l'accès à travers tous les namespaces. - **RoleBinding** : accorde un Role à des sujets (utilisateurs, groupes ou comptes de service) dans un namespace spécifique. - **ClusterRoleBinding** : accorde un ClusterRole à des sujets à l'échelle du cluster. Ces objets sont soit namespacés, soit cluster-scoped : - Role et RoleBinding sont namespacés ; ils ne s'appliquent qu'au namespace dans lequel ils sont créés. - ClusterRole et ClusterRoleBinding sont cluster-scoped ; ils s'appliquent à l'ensemble du cluster. Comprendre cette distinction est essentiel pour concevoir un modèle de permissions sécurisé. ### Exemple pas à pas : restreindre l'accès à un namespace Supposons qu'une équipe de développement doive déployer et gérer des applications dans le namespace `dev`. Ils ne doivent pas voir ni modifier les ressources des autres namespaces. Nous allons créer un Role avec des permissions pour gérer les ressources de charge de travail courantes, puis le lier à la fois à un groupe d'utilisateurs humains et à un compte de service. #### Créer le Role Créez un fichier `dev-role.yaml` : ```yaml apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: namespace: dev name: developer rules: - apiGroups: ["", "apps", "batch"] resources: ["pods", "deployments", "services", "configmaps", "secrets", "jobs"] verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] - apiGroups: [""] resources: ["pods/log"] verbs: ["get", "list"] ``` Appliquez-le : ```bash kubectl apply -f dev-role.yaml ``` Sortie attendue : ```text role.rbac.authorization.k8s.io/developer created ``` Ce Role accorde un accès en lecture/écriture aux pods, déploiements, services, configmaps, secrets et jobs dans le namespace `dev`, mais rien d'autre. Notez que les `secrets` sont inclus car le déploiement d'applications nécessite souvent de lire des secrets, mais demandez-vous si vos développeurs ont réellement besoin de lire les données des secrets ou seulement de les référencer. S'ils n'ont besoin que de monter des secrets dans des pods, ils n'ont pas besoin des permissions `get` ou `list` sur les secrets. Limiter l'accès aux secrets est une étape de durcissement courante. #### Lier le Role aux sujets Créez `dev-rolebinding.yaml` : ```yaml apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: developer-binding namespace: dev subjects: - kind: Group name: dev-team apiGroup: rbac.authorization.k8s.io - kind: ServiceAccount name: deployer namespace: dev roleRef: kind: Role name: developer apiGroup: rbac.authorization.k8s.io ``` Appliquez-le : ```bash kubectl apply -f dev-rolebinding.yaml ``` Sortie attendue : ```text rolebinding.rbac.authorization.k8s.io/developer-binding created ``` Désormais, tout membre du groupe `dev-team` (tel que défini dans votre fournisseur d'authentification) et tout pod s'exécutant avec le compte de service `deployer` dans le namespace `dev` peut gérer ces ressources. Ils ne peuvent cependant pas accéder à une ressource dans d'autres namespaces. ### ClusterRole pour un accès en lecture seule à travers tous les namespaces Parfois, vous avez besoin d'un rôle en lecture seule qui couvre l'ensemble du cluster, par exemple pour les auditeurs ou les tableaux de bord de surveillance. Un ClusterRole est approprié ici car la frontière de permission est à l'échelle du cluster. Créez `view-clusterrole.yaml` : ```yaml apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: view-only rules: - apiGroups: ["*"] resources: ["*"] verbs: ["get", "list", "watch"] ``` Appliquez : ```bash kubectl apply -f view-clusterrole.yaml ``` Sortie attendue : ```text clusterrole.rbac.authorization.k8s.io/view-only created ``` Ce ClusterRole permet de lire toutes les ressources dans tous les groupes d'API. Il ne permet pas `create`, `update` ou `delete`. Cependant, il permet de lire les secrets, ce qui peut être trop permissif pour certains auditeurs. En pratique, vous voudrez peut-être exclure les secrets de ce rôle ou créer un rôle séparé pour les données sensibles. Nous en discuterons dans la section des pièges. Liez-le à un seul utilisateur, disons `auditor@example.com` : Créez `view-clusterrolebinding.yaml` : ```yaml apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: view-only-binding subjects: - kind: User name: auditor@example.com apiGroup: rbac.authorization.k8s.io roleRef: kind: ClusterRole name: view-only apiGroup: rbac.authorization.k8s.io ``` Appliquez : ```bash kubectl apply -f view-clusterrolebinding.yaml ``` Sortie attendue : ```text clusterrolebinding.rbac.authorization.k8s.io/view-only-binding created ``` Maintenant, `auditor@example.com` peut lire toutes les ressources à l'échelle du cluster. Si vous devez accorder le même accès en lecture seule au sein d'un seul namespace, vous créeriez un Role avec des règles identiques et le lieriez avec un RoleBinding dans ce namespace. C'est un motif courant : définir un ClusterRole une fois, puis le lier dans plusieurs namespaces à l'aide de RoleBindings. Par exemple, vous pourriez lier le ClusterRole `view-only` à un groupe dans le namespace `dev` uniquement : ```yaml apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: dev-view-only namespace: dev subjects: - kind: Group name: dev-auditors apiGroup: rbac.authorization.k8s.io roleRef: kind: ClusterRole name: view-only apiGroup: rbac.authorization.k8s.io ``` Cela accorde aux `dev-auditors` un accès en lecture à toutes les ressources dans `dev` uniquement, même si le ClusterRole est cluster-scoped. Cette approche évite de dupliquer les définitions de rôle. ## Vérification et diagnostic Après avoir créé des rôles et des liaisons, vérifiez que les permissions fonctionnent comme prévu. L'outil le plus direct est `kubectl auth can-i`, qui simule une requête en tant qu'utilisateur ou compte de service spécifique. ### Vérifier l'accès en tant qu'utilisateur Vérifiez si `auditor@example.com` peut lister les pods : ```bash kubectl auth can-i list pods --as auditor@example.com ``` Sortie attendue : ```text yes ``` Vérifiez s'il peut supprimer des pods : ```bash kubectl auth can-i delete pods --as auditor@example.com ``` Sortie attendue : ```text no ``` Le drapeau `--as` usurpe l'utilisateur donné pour la vérification d'autorisation. Cela fonctionne indépendamment de vos informations d'identification actuelles, vous pouvez donc tester n'importe quel utilisateur ou groupe. ### Vérifier l'accès pour un compte de service Les comptes de service sont identifiés par le préfixe `system:serviceaccount:`. Pour un compte de service nommé `deployer` dans le namespace `dev`, vous utiliseriez : ```bash kubectl auth can-i create deployments --as system:serviceaccount:dev:deployer -n dev ``` Sortie attendue : ```text yes ``` Vérifiez si le même compte de service peut lire des pods dans un autre namespace, disons `kube-system` : ```bash kubectl auth can-i get pods --as system:serviceaccount:dev:deployer -n kube-system ``` Sortie attendue : ```text no ``` Cela confirme que le Role est correctement limité au namespace `dev`. Vous pouvez également lister toutes les permissions pour un utilisateur ou un compte de service : ```bash kubectl auth can-i --list --as system:serviceaccount:dev:deployer -n dev ``` Cela imprime un tableau de toutes les ressources et verbes autorisés pour ce sujet dans ce namespace. C'est un moyen rapide d'auditer les permissions effectives. ### Examiner les objets RBAC Listez tous les rôles et liaisons de rôle dans un namespace : ```bash kubectl get roles, rolebindings -n dev ``` Sortie attendue (exemple) : ```text NAME CREATED AT role.rbac.authorization.k8s.io/developer 2024-05-01T10:00:00Z NAME ROLE AGE rolebinding.rbac.authorization.k8s.io/developer-binding Role/developer 10m ``` Décrivez un rôle pour voir ses règles complètes : ```bash kubectl describe role developer -n dev ``` Extrait de sortie attendue : ```text Name: developer Namespace: dev Labels: Annotations: PolicyRule: Resources Non-Resource URLs Resource Names Verbs --------- ----------------- -------------- ----- pods [] [] [get list watch create update patch delete] deployments [] [] [get list watch create update patch delete] services [] [] [get list watch create update patch delete] configmaps [] [] [get list watch create update patch delete] secrets [] [] [get list watch create update patch delete] jobs [] [] [get list watch create update patch delete] pods/log [] [] [get list] ``` Cette description montre exactement ce que le rôle permet. Examinez-la attentivement pour détecter des permissions non intentionnelles, en particulier sur les ressources sensibles comme les secrets. ## Pièges courants et comment les éviter Même les administrateurs Kubernetes expérimentés commettent des erreurs avec le RBAC. Voici les pièges les plus fréquents, pourquoi ils surviennent et comment les éviter ou s'en remettre. ### 1. Permissions trop larges avec des caractères génériques **Pourquoi cela arrive :** Utiliser `*` pour les ressources ou les verbes est pratique, surtout lors du débogage. Les développeurs peuvent demander « donnez-moi toutes les permissions » pour que quelque chose fonctionne rapidement. **Comment éviter :** N'utilisez jamais `*` dans les rôles de production, sauf si le rôle est réellement à l'échelle du cluster et en lecture seule pour un auditeur. Même dans ce cas, excluez les secrets. Au lieu de cela, listez des ressources et des verbes spécifiques. Par exemple : ```yaml rules: - apiGroups: [""] resources: ["pods", "services", "configmaps"] verbs: ["get", "list", "watch"] ``` **Récupération :** Si vous découvrez un rôle avec des permissions génériques, remplacez-le immédiatement par un rôle spécifique. Auditez toutes les liaisons pour voir qui a reçu ce rôle et si un abus a eu lieu via les journaux d'audit. ### 2. Sujets manquants ou incorrects dans les liaisons **Pourquoi cela arrive :** Taper un nom d'utilisateur incorrect, utiliser le mauvais type (par exemple, `User` au lieu de `ServiceAccount`), ou référencer un groupe qui n'existe pas dans votre fournisseur d'identité. **Comment éviter :** Vérifiez deux fois les noms et les types des sujets. Utilisez `kubectl auth can-i --list --as ` pour vérifier que le sujet reçoit réellement les permissions attendues. **Récupération :** Corrigez la liaison en corrigeant le sujet. Si le mauvais sujet a reçu l'accès, supprimez la liaison et recréez-la avec le bon. ### 3. Confusion de namespace **Pourquoi cela arrive :** Penser qu'un Role peut être utilisé dans un ClusterRoleBinding, ou créer un Role dans le mauvais namespace. Un Role n'existe que dans son namespace, et un RoleBinding ne peut référencer qu'un Role du même namespace. **Comment éviter :** Documentez clairement à quel namespace appartient chaque rôle. Utilisez des conventions de nommage cohérentes qui incluent le nom du namespace, comme `developer-dev` ou `view-only-prod`. **Récupération :** Si vous avez référencé un Role à partir d'un ClusterRoleBinding (ce qui est invalide), la liaison ne fonctionnera pas. Créez un ClusterRole avec les mêmes règles et liez-le à la place. ### 4. Accorder inutilement l'accès aux secrets **Pourquoi cela arrive :** Le rôle générique `view-only` inclut les secrets. De nombreux développeurs demandent également l'accès aux secrets par commodité. **Comment éviter :** Séparez les secrets dans leur propre rôle avec des sujets très limités. Pour la plupart des charges de travail, les pods n'ont besoin que de références de secrets via des volumes ou des variables d'environnement, pas d'un accès direct `get` ou `list` sur les objets secrets. N'accordez l'accès en lecture aux secrets qu'aux comptes de service spécifiques qui en ont réellement besoin, comme un contrôleur de gestion des secrets. **Récupération :** Retirez les secrets des rôles larges. Créez un rôle dédié `secrets-reader` et liez-le uniquement aux sujets nécessaires. ### 5. Accumulation de rôles et de liaisons inutilisés **Pourquoi cela arrive :** Au fil du temps, les équipes changent, les projets se terminent et les rôles restent. Les rôles inutilisés sont un risque de sécurité car ils peuvent accorder des permissions qui ne sont plus nécessaires. **Comment éviter :** Auditez régulièrement les rôles et les liaisons. Supprimez ceux qui ne sont pas référencés ou dont les sujets n'existent plus. Utilisez des outils comme `kubectl get rolebindings --all-namespaces -o json` pour scripter les audits. **Récupération :** Supprimez simplement les objets inutilisés. Mais assurez-vous d'abord qu'aucun sujet actif n'en dépend en vérifiant les liaisons. ### 6. Se verrouiller hors du cluster **Pourquoi cela arrive :** Modifier ou supprimer le ClusterRoleBinding `cluster-admin`, ou supprimer toutes les liaisons pour les utilisateurs administratifs. **Comment éviter :** Maintenez toujours un compte de secours en dehors du RBAC Kubernetes, comme l'utilisateur racine d'un fournisseur cloud ou un kubeconfig statique stocké en toute sécurité. Avant de modifier des liaisons administratives critiques, testez l'accès avec `kubectl auth can-i` en utilisant un utilisateur non administrateur. **Récupération :** Si vous êtes verrouillé, utilisez votre méthode de secours pour restaurer l'accès administrateur. Recréez ensuite les RoleBindings ou ClusterRoleBindings nécessaires. ### 7. Ignorer les groupes d'API **Pourquoi cela arrive :** Oublier que de nombreuses ressources sont dans des groupes d'API non core comme `apps/v1` pour les déploiements ou `networking.k8s.io/v1` pour les politiques réseau. Utiliser une chaîne vide `""` pour `apiGroups` ne couvre que les ressources core comme les pods et les services. **Comment éviter :** Spécifiez toujours le bon groupe d'API pour chaque ressource. Par exemple : ```yaml - apiGroups: ["apps"] resources: ["deployments", "statefulsets"] verbs: ["get", "list", "watch"] ``` **Récupération :** Si la permission est refusée pour une ressource, vérifiez son groupe d'API avec `kubectl api-resources` et mettez à jour le rôle en conséquence. ## Liste de contrôle opérationnelle Maintenir une posture RBAC sécurisée nécessite des examens réguliers. La liste de contrôle suivante attribue un propriétaire et une fréquence à chaque tâche, garantissant la responsabilité. | Tâche | Propriétaire | Commande / Action | Fréquence | |-------|--------------|-------------------|-----------| | Examiner tous les rôles et liaisons de cluster | Priya Shah, responsable sécurité | `kubectl get clusterrolebindings -o yaml` | Mensuelle | | Lister tous les rôles dans chaque namespace | Carlos Mendes, administrateur plateforme | `kubectl get roles --all-namespaces` | Mensuelle | | Lister toutes les liaisons de rôle dans chaque namespace | Carlos Mendes, administrateur plateforme | `kubectl get rolebindings --all-namespaces` | Mensuelle | | Vérifier les permissions génériques | Priya Shah, responsable sécurité | `kubectl get clusterroles -o yaml \| grep -B5 '\*'` | Hebdomadaire | | Vérifier l'utilisation des comptes de service | Janet Okafor, ingénieure DevOps | `kubectl get serviceaccounts --all-namespaces` | Hebdomadaire | | Tester l'accès pour les utilisateurs critiques | Lin Wei, administrateur plateforme | `kubectl auth can-i --list --as ` | À chaque changement | | Rotation des jetons de compte de service | Système automatisé | Selon la configuration du cluster | Trimestrielle | | Examiner les journaux d'audit pour les requêtes refusées | Priya Shah, responsable sécurité | Rechercher dans les journaux d'audit `"decision":"forbid"` | Hebdomadaire | De plus, respectez ces principes : - Créez toujours des rôles avec le moindre privilège requis. - Préférez Role et RoleBinding pour l'accès limité à un namespace. - Utilisez ClusterRole et ClusterRoleBinding uniquement pour les ressources à l'échelle du cluster ou lorsque l'accès doit couvrir tous les namespaces. - Évitez d'utiliser le compte de service par défaut pour les applications ; créez des comptes de service dédiés avec un RBAC spécifique. - Supprimez régulièrement les rôles et liaisons inutilisés. - Documentez l'objectif de chaque rôle, ses sujets et le propriétaire qui l'a demandé. Pour les journaux d'audit, configurez votre serveur API pour journaliser les décisions d'autorisation. Un exemple de politique d'audit pour journaliser les requêtes refusées pour les pods : ```yaml apiVersion: audit.k8s.io/v1 kind: Policy rules: - level: Metadata verbs: ["*"] resources: - group: "" resources: ["pods"] omitStages: - "RequestReceived" ``` Inspectez ensuite les journaux pour les entrées avec `"decision":"forbid"` afin d'identifier les tentatives non autorisées. ## Conclusion Le RBAC Kubernetes est un outil puissant pour sécuriser votre cluster, mais il nécessite une conception délibérée et une maintenance continue. En comprenant son architecture et en suivant de bonnes pratiques, vous pouvez garantir que chaque utilisateur et application n'a que les permissions nécessaires à sa fonction. Commencez par un inventaire clair de votre environnement. Mettez en œuvre des rôles et des liaisons de manière incrémentale, en évitant les caractères génériques et les octrois trop permissifs. Vérifiez régulièrement l'accès à l'aide de `kubectl auth can-i`. Ayez un plan de récupération pour les erreurs de configuration et attribuez une propriété claire pour les tâches d'hygiène RBAC. Utilisez la liste de contrôle fournie pour maintenir une posture sécurisée au fil du temps. Avec ces pratiques en place, vous pouvez gérer l'accès à vos clusters Kubernetes en toute confiance, réduisant le risque de violations de sécurité et d'incidents opérationnels.