infra / kubernetes
RBAC et sécurité des accès
Explication
Ce que vous allez apprendre
- Comprendre pourquoi RBAC répond à une question différente ("qui a le droit ?") des leçons précédentes
- Distinguer les trois briques de RBAC : ServiceAccount, Role et RoleBinding
- Choisir entre une portée namespace (
Role) et une portée cluster (ClusterRole) - Appliquer le principe du moindre privilège plutôt que d'accorder des permissions "au cas où"
- Vérifier concrètement une permission avec
kubectl auth can-iplutôt que deviner
Dans quel contexte ?
Un stagiaire reçoit un accès kubectl sur le cluster de l'entreprise pour déboguer un problème sur son application. Sans RBAC configuré, le compte hérite par défaut de permissions bien trop larges : il pourrait, par une simple faute de frappe, supprimer le namespace production entier au lieu du namespace sandbox qu'il visait. RBAC existe précisément pour limiter chaque identité, humaine ou applicative, au strict nécessaire — ici, seulement lire et modifier les ressources du namespace sandbox, rien de plus.
Une question différente de tout ce qu'on a vu
D'abord, jusqu'ici, le cours s'est concentré sur "comment faire fonctionner" des applications. Cette leçon aborde une question différente : qui a le droit de faire quoi sur le cluster ?
Des exemples concrets du risque
Un développeur devrait-il pouvoir supprimer un namespace de production ? Une application devrait-elle pouvoir lister les Secrets de tous les autres namespaces ? Sans contrôle, la réponse par défaut est souvent "oui, tout le monde peut tout faire", ce qui est dangereux.
L'outil qui répond à ce problème
RBAC (Role-Based Access Control) permet de définir des permissions précises, fondées sur des rôles.
| Brique RBAC | Rôle |
|---|---|
ServiceAccount | Une identité, utilisée par une application pour parler à l'API |
Role / ClusterRole | Un ensemble de permissions, sans être attaché à personne |
RoleBinding / ClusterRoleBinding | Le lien entre une identité et un Role |
Prérequis
Cette leçon suppose les namespaces déjà connus : la distinction entre Role (limité à un namespace) et ClusterRole (à l'échelle du cluster) n'a de sens que si cette notion est déjà claire.
La première des trois briques
RBAC repose sur trois éléments à apprendre à combiner. Le ServiceAccount est une identité, utilisée par une application (et non par un humain) pour s'authentifier auprès de l'API Kubernetes.
La deuxième et la troisième brique
Le Role décrit un ensemble de permissions, comme "peut lire les pods, ne peut rien modifier", sans être attaché à personne. Le RoleBinding relie les deux : il dit "ce ServiceAccount reçoit les permissions de ce Role".
Piège fréquent
Accorder par réflexe un ClusterRole alors qu'un simple Role namespacé suffirait est l'erreur de sécurité la plus fréquente avec RBAC : ça revient à donner les clés de tout l'immeuble à quelqu'un qui n'a besoin que d'accéder à un seul appartement.
Pourquoi séparer ces trois éléments
Cette séparation permet de réutiliser un même Role pour plusieurs identités, ou de changer les permissions d'une identité sans toucher à la définition du rôle.
Une portée à bien choisir
Role/RoleBinding s'appliquent à l'intérieur d'un seul namespace ; ClusterRole/ClusterRoleBinding s'appliquent à l'échelle de tout le cluster.
L'erreur de sécurité la plus fréquente
Accorder par réflexe des permissions au niveau cluster alors qu'un namespace suffirait est une erreur fréquente. Le principe à suivre est celui du moindre privilège : chaque identité ne doit recevoir que le strict nécessaire pour fonctionner, jamais plus "au cas où".
Vérifier concrètement plutôt que deviner
Enfin, relire un ensemble de règles YAML pour deviner ce qu'une identité peut réellement faire est source d'erreurs. kubectl auth can-i permet de poser directement la question à l'API : "cette identité peut-elle faire cette action précise ?"
Maintenant que les accès sont contrôlés, la leçon suivante aborde un autre type de besoin : des applications qui ont besoin d'une identité stable, avec les StatefulSets.
Commandes & code
RBAC : ServiceAccount, Role, RoleBinding
RBAC (Role-Based Access Control) définit QUI peut faire QUOI sur QUELLES ressources.
# serviceaccount.yaml - identité utilisée par une application pour parler à l'API Kubernetes
apiVersion: v1
kind: ServiceAccount
metadata:
name: api-sa
namespace: staging# role.yaml - permissions limitées à UN namespace
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: pod-reader
namespace: staging
rules:
- apiGroups: [""]
resources: ["pods", "pods/log"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["configmaps"]
verbs: ["get", "list"]# rolebinding.yaml - lie le Role au ServiceAccount
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: api-sa-pod-reader
namespace: staging
subjects:
- kind: ServiceAccount
name: api-sa
namespace: staging
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io# ClusterRole + ClusterRoleBinding - permissions à l'échelle du CLUSTER entier
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: node-viewer
rules:
- apiGroups: [""]
resources: ["nodes"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: ci-node-viewer
subjects:
- kind: ServiceAccount
name: ci-bot
namespace: ci
roleRef:
kind: ClusterRole
name: node-viewer
apiGroup: rbac.authorization.k8s.io# Utiliser le ServiceAccount dans un Deployment (principe du moindre privilège)
apiVersion: apps/v1
kind: Deployment
metadata:
name: api-deployment
namespace: staging
spec:
template:
spec:
serviceAccountName: api-sa
automountServiceAccountToken: true # false si l'app n'a jamais besoin de parler à l'API
containers:
- name: api
image: myorg/api:1.4.2kubectl apply -f serviceaccount.yaml -f role.yaml -f rolebinding.yaml
# Vérifier concrètement ce qu'un compte peut faire (très utile en debug/audit)
kubectl auth can-i list pods --as=system:serviceaccount:staging:api-sa -n staging
kubectl auth can-i delete deployments --as=system:serviceaccount:staging:api-sa -n stagingRésumé
Role/RoleBinding= portée namespace ;ClusterRole/ClusterRoleBinding= portée cluster.- Chaque application doit avoir son propre
ServiceAccountavec le minimum de permissions. automountServiceAccountToken: falsepar défaut si l'app n'appelle jamais l'API Kubernetes.kubectl auth can-i --as=est l'outil de vérification/débogage RBAC de référence.
Exercices pratiques
Mission : empêcher le stagiaire de supprimer la production par erreur
Objectif : Créer un accès RBAC strictement limité au namespace sandbox pour un stagiaire, et vérifier concrètement ses permissions plutôt que de les deviner.
Contexte
Un stagiaire vient de recevoir un accès kubectl pour déboguer une application dans le namespace sandbox. Sans configuration RBAC dédiée, son compte hériterait de permissions bien trop larges, avec le risque réel qu'une faute de frappe supprime une ressource du namespace production au lieu de sandbox. Il faut créer une identité limitée au strict nécessaire, uniquement lire les pods et leurs logs dans sandbox, puis vérifier que cette limitation fonctionne réellement.