Aller au contenu principal
KubernetesDevOpsSécuritéFormation

RBAC : qui a accès à quoi

30 min de lecture Apprendre Kubernetes — Chapitre 7

Maîtrise le RBAC Kubernetes : Roles, ClusterRoles, Bindings et contrôle d'accès granulaire.

🎯 Objectif : À la fin de ce chapitre, tu sauras configurer le RBAC Kubernetes pour contrôler précisément qui fait quoi dans ton cluster. ⏱️ Durée estimée : 50 minutes | Niveau : Avancé

Tu as un cluster Kubernetes qui tourne. Les Pods se déploient, les Services répondent, tout roule. Puis un dev junior exécute kubectl delete namespace production un vendredi à 17h. Game over.

Le RBAC — Role-Based Access Control — c’est le mécanisme natif de Kubernetes pour éviter ce genre de catastrophe. Il répond à une question simple : qui a le droit de faire quoi, et où ? Sans RBAC correctement configuré, chaque utilisateur et chaque Pod a potentiellement les clés du royaume.

Pourquoi le RBAC est non négociable

Dans un cluster partagé par plusieurs équipes, le RBAC n’est pas un nice-to-have. C’est la première ligne de défense.

Sans RBAC, un ServiceAccount compromis dans un Pod peut lister les Secrets de tout le cluster, modifier des Deployments, voire supprimer des namespaces entiers. Le principe est simple : chaque utilisateur, chaque application ne reçoit que les permissions strictement nécessaires à son travail. C’est le moindre privilège, appliqué à Kubernetes.

🔥 Cas réel : En 2021, Tesla a subi une intrusion via un dashboard Kubernetes exposé sans authentification. Les attaquants ont accédé aux credentials AWS stockés dans le cluster et miné du crypto sur l’infra cloud. Un RBAC strict + des ServiceAccounts verrouillés auraient bloqué la propagation.

Le RBAC protège contre trois scénarios concrets :

  • L’erreur humaine — un dev qui supprime la mauvaise ressource dans le mauvais namespace
  • La compromission applicative — un Pod hacké qui tente d’explorer le cluster
  • L’escalade de privilèges — un utilisateur qui accède à des Secrets auxquels il ne devrait pas toucher

Comprendre les quatre objets RBAC

Le RBAC Kubernetes repose sur quatre ressources qui fonctionnent en duo : les rôles définissent les permissions, les bindings les attribuent à des sujets.

Role définit un ensemble de permissions dans un namespace précis. Tu déclares quelles API groups, quelles ressources et quels verbes sont autorisés. Un Role dans le namespace staging n’a aucun effet sur production.

ClusterRole fait la même chose, mais à l’échelle du cluster entier. Il est indispensable pour les ressources non-namespacées comme les Nodes ou les PersistentVolumes.

RoleBinding associe un Role (ou un ClusterRole) à un sujet — utilisateur, groupe ou ServiceAccount — dans un namespace donné. ClusterRoleBinding fait la même association, mais avec une portée cluster-wide.

💡 Tip DevOps : Tu peux lier un ClusterRole via un simple RoleBinding. L’effet ? Les permissions du ClusterRole sont restreintes au namespace du binding. C’est le pattern idéal pour réutiliser un même ClusterRole dans plusieurs namespaces sans accorder un accès global.

Les sujets peuvent être de trois types :

  • User — identité externe (gérée par ton provider OIDC, certificat x509, etc.)
  • Group — regroupement logique d’utilisateurs
  • ServiceAccount — identité des Pods, native à Kubernetes

🧠 À retenir : Kubernetes ne gère pas les utilisateurs. Il n’y a pas de ressource User dans l’API. L’authentification est toujours déléguée à un système externe (certificats, OIDC, webhook). Le RBAC ne gère que l’autorisation.

Commandes essentielles

Avant d’écrire du YAML, tu dois savoir diagnostiquer. La commande kubectl auth can-i est ton meilleur allié pour vérifier les permissions effectives d’un sujet.

Pour tester si un ServiceAccount a le droit de lister les Pods dans un namespace :

kubectl auth can-i list pods \
  --namespace production \
  --as system:serviceaccount:production:backend-sa

Pour afficher toutes les permissions d’un sujet dans un namespace donné :

kubectl auth can-i --list \
  --namespace production \
  --as system:serviceaccount:production:backend-sa

Pour voir tous les RoleBindings et ClusterRoleBindings qui s’appliquent dans un namespace :

kubectl get rolebindings,clusterrolebindings \
  --namespace production \
  -o wide

⚠️ Attention : kubectl auth can-i avec --as nécessite que ton propre utilisateur ait le droit d’impersonation. Dans un cluster managé (EKS, GKE, AKS), c’est généralement le cas pour les admins, mais pas pour les développeurs.

Cas concret : sécuriser une équipe backend en production

Ton entreprise a trois équipes : backend, frontend et data. L’équipe backend doit pouvoir déployer dans production (Deployments + Services), voir les Pods pour le debug, mais ne doit pas toucher aux Secrets, ConfigMaps ou autres namespaces.

Voici le Role qui traduit exactement ce besoin :

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: production
  name: backend-deployer
rules:
  - apiGroups: ["apps"]
    resources: ["deployments"]
    verbs: ["get", "list", "watch", "create", "update", "patch"]
  - apiGroups: [""]
    resources: ["services"]
    verbs: ["get", "list", "watch", "create", "update", "patch"]
  - apiGroups: [""]
    resources: ["pods", "pods/log"]
    verbs: ["get", "list", "watch"]

Maintenant, on lie ce Role au groupe backend-team :

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  namespace: production
  name: backend-team-deployer
subjects:
  - kind: Group
    name: backend-team
    apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: backend-deployer
  apiGroup: rbac.authorization.k8s.io

Pour l’application elle-même, on crée un ServiceAccount dédié avec des permissions encore plus restreintes — elle n’a besoin que de lire sa config et ses credentials :

apiVersion: v1
kind: ServiceAccount
metadata:
  namespace: production
  name: order-processor
automountServiceAccountToken: false
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: production
  name: order-processor-role
rules:
  - apiGroups: [""]
    resources: ["configmaps"]
    verbs: ["get"]
    resourceNames: ["order-config"]
  - apiGroups: [""]
    resources: ["secrets"]
    verbs: ["get"]
    resourceNames: ["order-db-credentials"]

Remarque le champ resourceNames : il restreint l’accès à des ressources nommées spécifiquement. Le ServiceAccount ne peut pas lister tous les Secrets du namespace — il ne peut lire que order-db-credentials. C’est le moindre privilège poussé à son maximum.

💡 Tip DevOps : Mets automountServiceAccountToken: false sur tous tes ServiceAccounts par défaut. Si un Pod a réellement besoin du token API, déclare-le explicitement dans sa spec. Ça réduit drastiquement la surface d’attaque en cas de compromission du conteneur.

Pièges fréquents

Le ServiceAccount default qui traîne. Chaque namespace a un SA default. Son token est monté automatiquement dans tous les Pods qui ne spécifient pas de SA. Même sans permissions RBAC explicites, ce token permet de faire des appels à l’API server. Assigne toujours un SA dédié à chaque workload.

Les ClusterRoleBindings trop larges. Un ClusterRoleBinding vers cluster-admin donné à un groupe entier, c’est tentant en dev. En prod, c’est une bombe à retardement. Audite régulièrement avec kubectl get clusterrolebindings -o wide et challenge chaque binding admin.

⚠️ Attention : Le verbe * (wildcard) dans un Role accorde tous les verbes, y compris delete et escalate. Ne l’utilise jamais en production. Sois toujours explicite sur les verbes autorisés.

Oublier les sous-ressources. Tu donnes accès aux pods mais ton dev ne peut pas faire kubectl logs ? C’est parce que les logs sont une sous-ressource : il faut ajouter pods/log dans les resources. Même chose pour pods/exec, pods/portforward, deployments/scale, etc.

Confondre authentification et autorisation. Le RBAC ne gère que l’autorisation. Si tu as un problème de login (Unauthorized), le souci est côté authentification (certificats, tokens OIDC), pas côté RBAC. Le RBAC intervient après — il retourne Forbidden, pas Unauthorized.

🔥 Cas réel : Une équipe SRE avait donné get secrets sans resourceNames à son outil de monitoring. Résultat : l’outil pouvait lire tous les Secrets du namespace, y compris les credentials de base de données. Un attaquant qui compromet le monitoring récupère tout. Toujours restreindre avec resourceNames quand c’est possible.

Exercice pratique

Mets en place un RBAC complet pour ce scénario :

Contexte : Tu gères un cluster avec deux namespaces — staging et production. L’équipe QA doit pouvoir :

  • Lire les Pods, Services et Deployments dans staging
  • Consulter les logs des Pods dans staging
  • N’avoir aucun accès à production

Étapes :

  1. Crée un ServiceAccount qa-viewer dans le namespace staging
  2. Crée un Role avec les permissions en lecture seule nécessaires (n’oublie pas pods/log)
  3. Crée le RoleBinding associé
  4. Vérifie avec kubectl auth can-i que le SA peut lire les Pods dans staging
  5. Vérifie qu’il ne peut pas lire les Pods dans production

Pour valider, cette commande doit retourner yes :

kubectl auth can-i get pods/log \
  --namespace staging \
  --as system:serviceaccount:staging:qa-viewer

Et celle-ci doit retourner no :

kubectl auth can-i list pods \
  --namespace production \
  --as system:serviceaccount:staging:qa-viewer

🧠 À retenir : Un RoleBinding dans staging n’accorde jamais de permissions dans production. C’est l’isolation par namespace — le cœur du modèle de sécurité RBAC.


➡️ La suite : Dans le prochain chapitre, on verrouille les Pods eux-mêmes avec les Pod Security Standards et les NetworkPolicies. On continue ! 🚀

🖥️ Pratique sur ton propre serveur

Pour suivre Apprendre Kubernetes en conditions réelles, tu as besoin d'un VPS. DigitalOcean offre 200$ de crédit gratuit pour démarrer.

Obtenir 200$

Articles liés