## Introduction

Le contrôle d'accès basé sur les rôles (RBAC) est l'un des principaux mécanismes de sécurisation d'un cluster Kubernetes. Parmi les objets RBAC, le ClusterRole devient souvent une source de confusion car il accorde des permissions sur l'ensemble du cluster, et non uniquement dans un seul namespace. Lorsqu'une charge de travail ne peut soudainement plus lister les pods, qu'un développeur reçoit une erreur « forbidden », ou qu'un pipeline d'automatisation échoue avec un message d'autorisation, la cause racine réside fréquemment dans un ClusterRole ou un ClusterRoleBinding mal configuré.

Cet article propose une approche pratique et concrète pour dépanner les problèmes liés aux ClusterRole. Vous apprendrez à confirmer les refus d'accès à l'aide de commandes et de journaux, à vérifier que vos liaisons référencent les bons sujets et rôles, et à récupérer en toute sécurité en cas de problème. Nous couvrirons des exemples concrets, des techniques de diagnostic et une liste de vérification reproductible que vous pourrez intégrer à votre flux de travail opérationnel. À la fin, vous serez en mesure de diagnostiquer et de résoudre la plupart des problèmes RBAC en toute confiance.

## Inventaire de la version et de l'environnement

Avant de commencer le dépannage, documentez la version de Kubernetes et la topologie de votre cluster. Le comportement des ClusterRole est resté stable au fil des versions, mais les versions d'API, les feature gates et les valeurs par défaut spécifiques à la distribution peuvent influencer le RBAC.

Commencez par vérifier la version du serveur :

```bash
kubectl version --short
```

Sortie attendue (exemple) :

```
Client Version: v1.27.3
Kustomize Version: v5.0.1
Server Version: v1.27.3
```

Ensuite, listez les nœuds et les namespaces pertinents pour le problème :

```bash
kubectl get nodes
kubectl get namespaces
```

Exemple de sortie :

```
NAME     STATUS   ROLES           AGE   VERSION
node-1   Ready    control-plane   10d   v1.27.3
node-2   Ready    <none>          10d   v1.27.3

NAME          STATUS   AGE
default       Active   10d
kube-system   Active   10d
my-app        Active   5d
```

Prérequis pour suivre ce guide :

- Un cluster Kubernetes en cours d'exécution. Le RBAC est généralement disponible et stable dans Kubernetes v1.19 et versions ultérieures, mais les versions antérieures peuvent également fonctionner.
- kubectl configuré avec un accès approprié pour inspecter les objets RBAC. Vous avez besoin au minimum des permissions `get`, `list` et `describe` sur les `roles`, `clusterroles`, `rolebindings`, `clusterrolebindings` et `serviceaccounts`.
- Accès aux journaux du serveur d'API si un diagnostic approfondi est nécessaire. Cela implique généralement l'accès aux nœuds du plan de contrôle ou à un système d'agrégation de journaux.
- Compréhension de base des concepts RBAC : Role, ClusterRole, RoleBinding, ClusterRoleBinding et ServiceAccount.

## Chemin de configuration sécurisé

Lors de la création ou de la modification de ClusterRoles, appliquez toujours le principe du moindre privilège. N'accordez que les permissions requises pour le fonctionnement de la charge de travail et limitez ces permissions autant que possible. Évitez les permissions génériques (« * ») sauf en cas de nécessité absolue. Préférez Role et RoleBinding pour les accès limités à un namespace ; utilisez ClusterRole et ClusterRoleBinding uniquement pour les ressources à l'échelle du cluster (comme les nœuds ou les volumes persistants) ou pour les accès non liés à un namespace.

### Exemple : un ClusterRole étroitement limité pour lire les pods dans tous les namespaces

Supposons que vous ayez une application s'exécutant dans le namespace `my-app` qui a besoin de lister et de surveiller les pods dans tous les namespaces à des fins de surveillance. Au lieu d'accorder des droits étendus de cluster-admin, créez un ClusterRole dédié avec uniquement les verbes nécessaires.

Créez un fichier nommé `pod-reader-clusterrole.yaml` :

```yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: pod-reader
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list", "watch"]
```

Appliquez-le :

```bash
kubectl apply -f pod-reader-clusterrole.yaml
```

Sortie attendue :

```
clusterrole.rbac.authorization.k8s.io/pod-reader created
```

Liez maintenant ce ClusterRole à un compte de service spécifique dans le namespace `my-app`. Créez `pod-reader-binding.yaml` :

```yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: pod-reader-binding-my-app
subjects:
- kind: ServiceAccount
  name: app-sa
  namespace: my-app
roleRef:
  kind: ClusterRole
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io
```

Appliquez la liaison :

```bash
kubectl apply -f pod-reader-binding.yaml
```

Sortie attendue :

```
clusterrolebinding.rbac.authorization.k8s.io/pod-reader-binding-my-app created
```

Cette liaison accorde au compte de service `app-sa` dans le namespace `my-app` la capacité de `get`, `list` et `watch` les pods dans tous les namespaces. C'est un point de départ sûr car cela limite les verbes et les types de ressources.

Si vous devez accorder des permissions uniquement dans un seul namespace, utilisez un Role avec un RoleBinding au lieu d'un ClusterRole avec un ClusterRoleBinding. Par exemple, pour permettre à `app-sa` de lire les pods uniquement dans `my-app` :

```yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: pod-reader-ns
  namespace: my-app
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: pod-reader-ns-binding
  namespace: my-app
subjects:
- kind: ServiceAccount
  name: app-sa
  namespace: my-app
roleRef:
  kind: Role
  name: pod-reader-ns
  apiGroup: rbac.authorization.k8s.io
```

Appliquez ceci avec `kubectl apply -f` (combinez les deux sections dans un seul fichier). Cela maintient la portée des permissions limitée au namespace.

## Vérification et diagnostics

Après avoir appliqué les modifications RBAC, vérifiez que les permissions effectives correspondent à votre intention. La commande `kubectl auth can-i` simule une requête API pour un utilisateur ou un compte de service et renvoie `yes` ou `no`. C'est le moyen le plus rapide de vérifier si un compte de service dispose d'une permission spécifique.

### Vérifier les permissions effectives avec `kubectl auth can-i`

Vérifiez si le compte de service `app-sa` dans le namespace `my-app` peut lister les pods dans tous les namespaces :

```bash
kubectl auth can-i list pods --as=system:serviceaccount:my-app:app-sa --all-namespaces
```

Sortie attendue si autorisé :

```
yes
```

Vérifiez s'il peut obtenir des pods dans le namespace `kube-system` :

```bash
kubectl auth can-i get pods --as=system:serviceaccount:my-app:app-sa -n kube-system
```

Sortie attendue :

```
yes
```

Vérifiez maintenant s'il peut créer des pods (ce qui devrait être refusé) :

```bash
kubectl auth can-i create pods --as=system:serviceaccount:my-app:app-sa
```

Sortie attendue :

```
no
```

Vous pouvez également demander une liste complète des permissions d'un utilisateur avec `kubectl auth can-i --list` :

```bash
kubectl auth can-i --list --as=system:serviceaccount:my-app:app-sa
```

Cela produit un tableau montrant toutes les actions autorisées. C'est utile lorsque vous n'êtes pas sûr des permissions d'un sujet.

### Inspecter les détails du ClusterRole et du ClusterRoleBinding

Un autre diagnostic utile est `kubectl describe clusterrole` et `kubectl describe clusterrolebinding`. Ces commandes affichent les règles et les sujets dans un format lisible.

```bash
kubectl describe clusterrole pod-reader
```

Extrait de sortie d'exemple :

```
Name:         pod-reader
Labels:       <none>
Annotations:  <none>
PolicyRule:
  Resources  Non-Resource URLs  Resource Names  Verbs
  ---------  -----------------  --------------  -----
  pods       []                 []              [get list watch]
```

```bash
kubectl describe clusterrolebinding pod-reader-binding-my-app
```

Extrait de sortie d'exemple :

```
Name:         pod-reader-binding-my-app
Labels:       <none>
Annotations:  <none>
Role:
  Kind:  ClusterRole
  Name:  pod-reader
Subjects:
  Kind            Name     Namespace
  ----            ----     ---------
  ServiceAccount  app-sa   my-app
```

### Vérifier les journaux du serveur d'API pour les refus

Lorsqu'une charge de travail signale une erreur d'accès refusé, l'inspection des journaux du serveur d'API peut fournir une confirmation définitive. Si vous avez accès aux nœuds du plan de contrôle, recherchez les lignes contenant le nom du compte de service et la ressource. Le format exact des journaux varie selon la version de Kubernetes, mais voici un exemple tiré d'un journal `kube-apiserver` :

```
2023-08-15T10:20:30.123456Z authorization.go:123] RBAC DENY: user="system:serviceaccount:my-app:app-sa" verb="create" resource="pods" namespace="default"
```

Si vos journaux sont agrégés (par exemple, avec un système de journalisation centralisé), recherchez le nom du compte de service ou le type de ressource. Cela confirmera le refus et montrera les détails exacts de la requête, tels que le verbe, la ressource et le namespace.

## Pièges courants et comment les éviter

Les erreurs de configuration RBAC suivent souvent quelques schémas prévisibles. Comprendre ces pièges courants peut vous faire gagner un temps de débogage considérable.

### Piège 1 : Des permissions manquantes provoquent des erreurs « forbidden »

**Ce qui se passe :** Les applications ou les utilisateurs reçoivent des erreurs telles que :

```
Error: pods is forbidden: User "system:serviceaccount:my-app:app-sa" cannot create resource "pods" in API group "" in the namespace "default"
```

**Pourquoi cela arrive :** Le sujet (compte de service, utilisateur ou groupe) ne dispose pas du verbe requis sur la ressource en question. Cela peut être dû au fait que le Role ou le ClusterRole n'inclut pas la règle nécessaire, ou que le sujet n'est lié à aucun rôle qui l'accorde.

**Comment éviter :** Avant de déployer une charge de travail, définissez explicitement les permissions dont elle a besoin et créez le Role/ClusterRole et la liaison appropriés. Testez avec `kubectl auth can-i` en tant que compte de service avant la mise en production.

**Comment récupérer :** Utilisez `kubectl auth can-i --list --as=system:serviceaccount:<namespace>:<serviceaccount>` pour voir les permissions actuelles du sujet. Identifiez la règle manquante et ajoutez-la au Role ou ClusterRole concerné. Réappliquez ensuite les manifestes.

### Piège 2 : Liaison mal configurée (mauvais sujet ou rôle)

**Ce qui se passe :** Un ClusterRole existe avec les bonnes règles, mais le sujet reçoit toujours des erreurs « forbidden ».

**Pourquoi cela arrive :** Le ClusterRoleBinding peut référencer un mauvais nom de compte de service, un mauvais namespace ou un mauvais rôle. Par exemple, un champ de sujet peut contenir une faute de frappe, ou le `roleRef` peut pointer vers un Role au lieu d'un ClusterRole.

**Comment éviter :** Vérifiez toujours le YAML des liaisons. Utilisez `kubectl describe clusterrolebinding <name>` pour inspecter les sujets et la référence de rôle. Vérifiez également que le compte de service référencé existe réellement avec `kubectl get serviceaccount <name> -n <namespace>`.

**Comment récupérer :** Corrigez le manifeste de liaison et réappliquez-le. Par exemple, si le nom du compte de service était mal orthographié, corrigez-le et exécutez `kubectl apply -f binding.yaml`.

### Piège 3 : Sur-permission accidentelle ou changement cassant

**Ce qui se passe :** Un changement RBAC récent accorde trop d'accès ou supprime des permissions nécessaires à une charge de travail existante, provoquant des échecs inattendus.

**Pourquoi cela arrive :** Les changements peuvent être effectués à la hâte, sans révision, ou par quelqu'un qui ne comprend pas pleinement l'impact. Par exemple, remplacer un ClusterRole spécifique par un plus large comme `cluster-admin` peut ouvrir le cluster.

**Comment éviter :** Conservez tous les manifestes RBAC dans un système de contrôle de version. Exigez des revues de code pour tout changement de rôles et de liaisons. Utilisez des outils comme `kubectl diff` avant d'appliquer.

**Comment récupérer :** Si les manifestes sont dans un contrôle de version, revenez à la version précédente et réappliquez. Sinon, vous pourrez peut-être reconstruire l'état précédent à partir d'une sauvegarde ou d'un `kubectl get clusterrole <name> -o yaml` pris avant le changement. Exemple de restauration :

```bash
kubectl apply -f previous-clusterrole.yaml
```

### Piège 4 : Liaison à un utilisateur ou un groupe qui n'existe plus

**Ce qui se passe :** Les utilisateurs signalent une perte d'accès après un changement de fournisseur d'identité ou après le départ d'un utilisateur de l'organisation.

**Pourquoi cela arrive :** La liaison référence un utilisateur ou un groupe qui n'est plus valide dans le système d'authentification. Kubernetes ne nettoie pas automatiquement ces liaisons.

**Comment éviter :** Auditez périodiquement vos liaisons pour détecter les sujets obsolètes. Utilisez `kubectl get clusterrolebindings -o yaml` et examinez les sujets. Supprimez ou mettez à jour les liaisons dans le cadre des processus de départ des utilisateurs.

**Comment récupérer :** Listez les liaisons et identifiez les sujets obsolètes avec `kubectl get clusterrolebinding -o yaml`. Modifiez ensuite la liaison pour supprimer le sujet obsolète ou le mettre à jour vers la nouvelle identité. Vérifiez avec `kubectl auth can-i --as=<user>`.

## Modes d'échec et récupération

La section précédente a couvert les pièges courants. Nous condensons ici ceux-ci en modes d'échec explicites et procédures de récupération pour une référence rapide en cas d'incident.

### Mode d'échec 1 : Erreurs « forbidden » malgré l'existence d'un ClusterRole

**Symptôme :** Les journaux d'application affichent une erreur telle que :

```
Error: pods is forbidden: User "system:serviceaccount:my-app:app-sa" cannot create resource "pods" in API group "" in the namespace "default"
```

**Diagnostic :**

1. Vérifiez que le compte de service existe :

```bash
kubectl get serviceaccount app-sa -n my-app
```

2. Vérifiez les permissions du compte de service :

```bash
kubectl auth can-i --list --as=system:serviceaccount:my-app:app-sa
```

3. Inspectez le ClusterRole et ses liaisons :

```bash
kubectl describe clusterrole <role-name>
kubectl describe clusterrolebinding <binding-name>
```

**Récupération :** Ajoutez la règle manquante au ClusterRole ou créez une nouvelle liaison s'il n'en existe aucune. Par exemple, si le compte de service doit créer des pods, modifiez le ClusterRole :

```yaml
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list", "watch", "create"]
```

Appliquez le manifeste mis à jour.

### Mode d'échec 2 : La liaison pointe vers un mauvais sujet ou rôle

**Symptôme :** Vous avez un ClusterRole avec les bonnes règles, mais un compte de service reçoit toujours « forbidden ».

**Diagnostic :**

```bash
kubectl describe clusterrolebinding <binding-name>
```

Vérifiez dans la sortie :

- Le nom et le namespace corrects du compte de service sous `Subjects`.
- Le type et le nom corrects du rôle sous `Role`.

Confirmez également que le compte de service existe :

```bash
kubectl get serviceaccount <name> -n <namespace>
```

**Récupération :** Modifiez le YAML de la liaison pour corriger la référence au sujet ou au rôle, puis réappliquez avec `kubectl apply -f binding.yaml`.

### Mode d'échec 3 : Changement trop permissif ou non intentionnel

**Symptôme :** Un changement RBAC récent a accordé trop d'accès ou cassé un flux de travail existant.

**Diagnostic :** Comparez l'état actuel avec le précédent. Si vous avez un contrôle de version, utilisez `git diff` pour voir ce qui a changé. Sinon, utilisez `kubectl get clusterrole <name> -o yaml` pour afficher les règles actuelles.

**Récupération :** Revenez au manifeste précédent :

```bash
kubectl apply -f previous-clusterrole.yaml
```

Si le manifeste précédent n'est pas disponible, modifiez manuellement le ClusterRole ou la liaison pour restaurer les règles prévues.

### Mode d'échec 4 : Sujets obsolètes dans les liaisons

**Symptôme :** Les utilisateurs perdent l'accès après un changement de fournisseur d'identité, ou d'anciens employés conservent l'accès.

**Diagnostic :** Listez toutes les liaisons et inspectez les sujets :

```bash
kubectl get clusterrolebindings -o yaml | grep -A 5 subjects
```

Identifiez les sujets qui ne sont plus valides.

**Récupération :** Modifiez la liaison pour supprimer les sujets obsolètes ou les mettre à jour vers les identités actuelles. Par exemple, si un utilisateur `old-user` n'est plus dans l'entreprise, supprimez ce sujet de la liaison. Vérifiez le changement avec :

```bash
kubectl auth can-i list pods --as=old-user
```

Cela devrait renvoyer `no` si la liaison a été correctement mise à jour.

## Liste de vérification opérationnelle

Utilisez cette liste de vérification pour prévenir et résoudre rapidement les problèmes de ClusterRole. Chaque élément inclut un responsable unique (une seule personne responsable, pas un groupe) et la fréquence de révision. Dans une organisation typique, l'équipe Plateforme ou Infrastructure possède le RBAC, mais le responsable spécifique peut varier. À titre d'illustration, nous utilisons « Priya Shah, responsable ingénierie » comme responsable. Ajustez les noms et les fréquences selon votre équipe.

| Vérification | Commande / Action | Résultat attendu | Responsable | Fréquence de révision |
|--------------|-------------------|------------------|-------------|----------------------|
| 1. Le ClusterRole existe et les règles sont correctes | `kubectl get clusterrole <name> -o yaml` | Le YAML montre les règles prévues sans caractères génériques | Priya Shah, responsable ingénierie | À chaque sprint (2 semaines) |
| 2. La liaison relie le bon rôle et le bon sujet | `kubectl get clusterrolebinding <name> -o yaml` | Le roleRef et les sujets correspondent au compte de service/utilisateur prévu | Priya Shah, responsable ingénierie | À chaque sprint |
| 3. Le compte de service existe dans le namespace | `kubectl get serviceaccount <name> -n <ns>` | Le compte de service est listé | Priya Shah, responsable ingénierie | Mensuellement |
| 4. Vérification des permissions effectives pour chaque charge de travail critique | `kubectl auth can-i <verb> <resource> --as=system:serviceaccount:<ns>:<sa>` | Renvoie `yes` uniquement pour les actions autorisées ; `no` pour les actions refusées | Priya Shah, responsable ingénierie | Après tout changement RBAC |
| 5. Les journaux du serveur d'API ne montrent aucun refus inattendu | Recherchez les noms de comptes de service et « RBAC DENY » dans les journaux | Aucun refus en dehors des schémas attendus | Priya Shah, responsable ingénierie | Hebdomadairement |
| 6. Un plan de restauration est disponible | Stockez tous les manifestes RBAC dans git et taguez les versions | Les manifestes précédents sont récupérables | Priya Shah, responsable ingénierie | En continu |
| 7. Revue du moindre privilège | `kubectl get clusterrole <name> -o yaml` et inspection manuelle des règles | Aucun verbe générique (« * ») sauf justification explicite | Priya Shah, responsable ingénierie | Trimestriellement |

Intégrez ces vérifications dans votre processus de gestion des changements. Avant de déployer des changements RBAC en production, passez en revue les points 1, 2, 3 et 7. Après le déploiement, effectuez les points 4 et 5 pour confirmer le comportement attendu. En cas de problème, consultez le point 6 pour la restauration.

## Conclusion

Le dépannage des problèmes de ClusterRole Kubernetes nécessite une approche systématique : inventorier votre environnement, mettre en œuvre des configurations au moindre privilège, vérifier avec `kubectl auth can-i` et les journaux, et disposer d'un plan de récupération. Les exemples de ce guide ont montré comment créer un ClusterRole et une liaison limités, vérifier les permissions en tant que compte de service et identifier les échecs courants tels que les règles manquantes, les liaisons mal configurées et les sujets obsolètes. Utilisez la liste de vérification opérationnelle pour maintenir votre modèle RBAC sécurisé et fonctionnel.

Pour en savoir plus, consultez la documentation officielle Kubernetes sur le RBAC et les meilleures pratiques RBAC de votre distribution.

Prochaines étapes pour approfondir vos compétences :

- Dans un cluster de test, reproduisez un refus de permission en créant un pod qui utilise un compte de service sans permissions suffisantes.
- Utilisez `kubectl auth can-i` et les journaux du serveur d'API pour diagnostiquer la permission manquante exacte.
- Appliquez les correctifs décrits ici et observez que la charge de travail fonctionne.
- Établissez un processus de révision pour tous les changements RBAC en utilisant le contrôle de version et la liste de vérification, avec un responsable unique et une fréquence de révision définie.