Retour au cours

infra / kubernetes

RBAC et sécurité des accès

Leçon 151 exercice

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-i plutô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 RBACRôle
ServiceAccountUne identité, utilisée par une application pour parler à l'API
Role / ClusterRoleUn ensemble de permissions, sans être attaché à personne
RoleBinding / ClusterRoleBindingLe 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.

yaml
# serviceaccount.yaml - identité utilisée par une application pour parler à l'API Kubernetes
apiVersion: v1
kind: ServiceAccount
metadata:
  name: api-sa
  namespace: staging
yaml
# 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"]
yaml
# 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
yaml
# 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
yaml
# 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.2
bash
kubectl 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 staging

Résumé

  • Role/RoleBinding = portée namespace ; ClusterRole/ClusterRoleBinding = portée cluster.
  • Chaque application doit avoir son propre ServiceAccount avec le minimum de permissions.
  • automountServiceAccountToken: false par 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

1 disponible
1

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.

Résoudre l’exercice →