## Introduction Gérer l'authentification dans les clusters Kubernetes est un exercice d'équilibre. Les équipes doivent accorder aux charges de travail le moindre privilège dont elles ont besoin, faire tourner les identifiants en toute sécurité et maintenir des déploiements rapides. Faire cela à la main dans tous les environnements ne passe pas à l'échelle, et un simple compte de service ou une liaison de rôle mal configuré peut devenir un incident de sécurité ou une panne. Automatiser l'authentification Kubernetes dans un pipeline CI/CD transforme ce risque en un processus reproductible. Au lieu d'appliquer manuellement des fichiers YAML, un pipeline valide, applique et vérifie les ressources d'authentification telles que les comptes de service (Service Accounts), les rôles (Roles), les liaisons de rôle (Role Bindings) et les secrets. Ce guide présente une mise en œuvre pratique, de l'inventaire de l'environnement à la récupération en cas d'échec, avec des commandes concrètes et des extraits de configuration. Cet article s'adresse aux développeurs, consultants DevOps et équipes techniques de startups qui utilisent déjà Kubernetes et souhaitent intégrer la gestion de l'authentification dans leurs flux de livraison. Il couvre le cycle de vie complet : observer l'état actuel, définir des chemins de configuration sûrs, vérifier les changements, gérer les échecs et maintenir une liste de contrôle opérationnelle. L'objectif est la sécurité opérationnelle : observer avant de modifier, limiter le rayon d'impact, utiliser des espaces réservés plutôt que des secrets, vérifier les résultats et documenter la récupération. ## Inventaire des versions et de l'environnement Avant d'écrire du code de pipeline, vous devez savoir avec quoi vous travaillez. Le comportement de l'authentification varie selon les versions de Kubernetes, notamment en ce qui concerne les jetons de compte de service et le RBAC. Commencez par collecter les éléments suivants : - Version du cluster : `kubectl version --short` - Ressources API liées à l'authentification disponibles : `kubectl api-resources | grep -E 'serviceaccounts|roles|rolebindings|secrets'` - Comptes de service actuels et leurs jetons : `kubectl get serviceaccounts --all-namespaces` - Liaisons de rôle existantes : `kubectl get rolebindings --all-namespaces` Enregistrez la sortie et les horodatages. Par exemple, une commande d'inventaire en lecture seule peut ressembler à : ```bash kubectl get serviceaccounts -n production -o yaml > prod-sa-backup-$(date +%Y%m%d).yaml ``` Cela crée une sauvegarde horodatée. N'extrayez jamais de secrets dans les journaux et ne les commitez pas dans le contrôle de source. Si vous devez inspecter un jeton, utilisez `kubectl describe secret -n ` mais évitez d'imprimer la valeur du jeton dans les journaux de CI ; fiez-vous plutôt aux mécanismes intégrés de Kubernetes pour injecter des identifiants dans les pods. Un prérequis crucial est de comprendre la fonctionnalité de projection des jetons de compte de service. Dans Kubernetes 1.21+, la fonctionnalité `BoundServiceAccountTokenVolume` est activée par défaut. Cela modifie la manière dont les jetons sont montés et expirent. Vérifiez avec : ```bash kubectl get --raw /metrics | grep serviceaccount ``` Ou vérifiez les drapeaux du kube-apiserver si vous y avez accès. Cela est important car votre automatisation CI/CD peut avoir besoin de créer des jetons à courte durée de vie ou d'utiliser des volumes projetés. Commande pratique d'inventaire de l'environnement : ```bash kubectl get pods -o wide kubectl describe pod kubectl logs --previous kubectl rollout status deployment/ ``` Commencez toujours par des observations en lecture seule. Par exemple, avant de modifier un compte de service, exécutez : ```bash kubectl auth can-i --list --as=system:serviceaccount:default:my-app ``` Cela affiche les autorisations de ce compte de service. Le plus petit changement justifié est de mettre à jour une seule liaison de rôle ou un seul compte de service à la fois, puis de vérifier l'effet avec une vérification `can-i` ou en observant le comportement de l'application. Gardez le test local petit. Appliquez un manifeste à un namespace de développement, inspectez les ressources générées et vérifiez le trafic avec `kubectl port-forward` ou un service `NodePort` avant de passer à un équilibreur de charge cloud ou à un contrôleur d'entrée. Par exemple : ```bash kubectl apply -f serviceaccount.yaml -n dev kubectl get serviceaccount my-app -n dev -o yaml kubectl run test-pod --image=busybox --restart=Never --rm -it -- /bin/sh # Dans le pod, vérifiez le jeton et l'accès à l'API ``` ## Chemin de configuration sûr Une fois que vous comprenez l'environnement, définissez un chemin sûr pour appliquer les changements d'authentification. Ce chemin doit être versionné, revu par les pairs et testé automatiquement avant d'atteindre la production. La pièce maîtresse de l'authentification dans Kubernetes est le compte de service (Service Account), combiné aux rôles (Roles) et aux liaisons de rôle (Role Bindings). Un chemin de configuration sûr pour ces ressources pourrait être : 1. Définir l'état souhaité dans Git (par exemple, `k8s/auth/prod/serviceaccount.yaml`, `role.yaml`, `rolebinding.yaml`). 2. Utiliser un pipeline CI pour valider la syntaxe des fichiers YAML avec `kubeval` ou `kubeconform`. 3. Faire un essai à blanc (dry-run) de l'application contre un cluster de staging : ```bash kubectl apply --dry-run=client -f k8s/auth/prod/ ``` 4. Appliquer à un namespace de staging et exécuter des tests d'intégration. 5. Approuver et appliquer en production à l'aide d'un outil comme Argo CD, Flux ou kubectl dans un pipeline contrôlé. Exemple de compte de service et de liaison de rôle pour une application en lecture seule : ```yaml # serviceaccount.yaml apiVersion: v1 kind: ServiceAccount metadata: name: read-only-app namespace: production --- # role.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: namespace: production name: read-only-role rules: - apiGroups: [""] resources: ["pods", "services", "configmaps"] verbs: ["get", "list", "watch"] --- # rolebinding.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: read-only-binding namespace: production subjects: - kind: ServiceAccount name: read-only-app namespace: production roleRef: kind: Role name: read-only-role apiGroup: rbac.authorization.k8s.io ``` Avant d'appliquer, vérifiez que les autorisations du rôle correspondent aux besoins de l'application. Pour un déploiement qui doit lire les pods et mettre à jour son propre statut, vous pourriez ajouter `update` sur les pods, mais n'accordez jamais `cluster-admin` à une application limitée à un namespace. Les chemins de configuration sûrs incluent également la gestion des secrets. Au lieu de committer des secrets dans Git, utilisez un outil comme Sealed Secrets ou External Secrets Operator pour chiffrer ou synchroniser les secrets depuis un coffre-fort. Par exemple, avec Sealed Secrets, vous chiffrez un secret localement et committez la version scellée : ```bash kubeseal --format yaml < secret.yaml > sealed-secret.yaml ``` Ensuite, dans le pipeline, le contrôleur le déchiffre dans le cluster. Cela garde le secret hors du contrôle de source tout en permettant le GitOps. Lors de l'application des changements, séparez l'observation de l'intervention. Capturez l'état actuel avec `kubectl get rolebinding -n production -o yaml`, appliquez le changement avec `kubectl apply -f rolebinding.yaml`, puis vérifiez les autorisations avec `kubectl auth can-i list pods --as=system:serviceaccount:production:read-only-app -n production`. Documentez la sortie attendue et le chemin de récupération si la vérification `can-i` échoue (par exemple, revenir au dernier commit). ## Vérification et diagnostic Après avoir appliqué les ressources d'authentification, vous devez vérifier que les changements ont pris effet et que l'application se comporte comme prévu. La vérification se fait à deux niveaux : au niveau de l'API Kubernetes et au niveau de l'application. Au niveau de l'API, utilisez `kubectl auth can-i` pour tester les autorisations d'un compte de service spécifique. Cette commande simule une requête API et renvoie oui ou non : ```bash kubectl auth can-i get pods --as=system:serviceaccount:production:read-only-app -n production # sortie attendue : yes kubectl auth can-i delete pods --as=system:serviceaccount:production:read-only-app -n production # sortie attendue : no ``` Si la sortie ne correspond pas aux attentes, diagnostiquez la liaison de rôle : ```bash kubectl describe rolebinding read-only-binding -n production ``` Vérifiez que le sujet est correct et que la référence de rôle pointe vers le rôle prévu. Les problèmes courants incluent l'utilisation d'un ClusterRole au lieu d'un Role pour un accès limité au namespace, ou l'oubli de définir le namespace dans la RoleBinding. Au niveau de l'application, testez que le pod peut accéder aux ressources dont il a besoin. Déployez un pod de test utilisant le compte de service et exécutez des commandes à l'intérieur : ```yaml apiVersion: v1 kind: Pod metadata: name: auth-test namespace: production spec: serviceAccountName: read-only-app containers: - name: test image: bitnami/kubectl:latest command: ["sleep", "3600"] ``` Ensuite, exécutez une commande dans le pod et lancez : ```bash kubectl exec -it auth-test -n production -- kubectl get pods -n production ``` Si cela réussit, vous devriez voir la liste des pods. Sinon, vérifiez les journaux du pod pour les erreurs d'autorisation : ```bash kubectl logs auth-test -n production # Cherchez des lignes comme : Error from server (Forbidden): pods is forbidden ``` Pour les pipelines CI/CD, écrivez des étapes de vérification automatisées après l'étape d'application. Voici un exemple de script qui applique une mise à jour de compte de service et vérifie les autorisations : ```bash #!/bin/bash set -e NAMESPACE="production" SA="read-only-app" # Appliquer la nouvelle liaison de rôle kubectl apply -f rolebinding.yaml -n $NAMESPACE # Attendre un moment pour la propagation sleep 5 # Vérifier l'autorisation if kubectl auth can-i list pods --as=system:serviceaccount:$NAMESPACE:$SA -n $NAMESPACE | grep -q "yes"; then echo "Autorisation accordée avec succès." else echo "Échec de la vérification d'autorisation. Retour arrière." kubectl rollout undo deployment/my-app -n $NAMESPACE exit 1 fi ``` Ce modèle lie directement la vérification au retour arrière, garantissant qu'un échec de changement d'authentification déclenche une action de récupération. Incluez-le dans votre pipeline comme une étape distincte après le déploiement. ## Modes de défaillance et récupération Même avec une planification minutieuse, les changements d'authentification peuvent mal tourner. Voici les modes de défaillance les plus courants et comment récupérer de chacun. **Défaillance : jeton de compte de service non monté ou invalide.** Cela peut arriver lorsque le compte de service n'existe pas, ou que le pod utilise un ancien jeton qui a expiré. Dans Kubernetes 1.21+, les jetons sont limités dans le temps et doivent être rafraîchis. Diagnostic : ```bash kubectl describe pod -n | grep -A5 "Mounts:" kubectl exec -n -- ls /var/run/secrets/kubernetes.io/serviceaccount ``` Si le répertoire est vide ou si le fichier de jeton est manquant, vérifiez le compte de service : ```bash kubectl get serviceaccount -n -o yaml ``` Récupération : Recréez le compte de service et redéployez le pod. Si vous utilisez des jetons projetés, assurez-vous que la spécification du pod inclut `automountServiceAccountToken: true` (par défaut) et le bon nom de compte de service. **Défaillance : autorisations RBAC trop restrictives ou trop permissives.** Une erreur courante consiste à accorder un ClusterRole large comme `cluster-admin` à un compte de service limité à un namespace. Cela viole le principe du moindre privilège et peut conduire à des failles de sécurité. À l'inverse, l'omission d'un verbe peut casser l'application. Diagnostic : Utilisez `kubectl auth can-i --list` pour voir toutes les autorisations : ```bash kubectl auth can-i --list --as=system:serviceaccount:production:my-app -n production ``` Comparez avec les besoins de l'application. Si l'application échoue avec des erreurs d'interdiction, vérifiez les journaux et les journaux d'audit du serveur API s'ils sont activés. Récupération : Mettez à jour le Role ou la RoleBinding avec les autorisations correctes et réappliquez. Si l'application fonctionnait avant, revenez à la configuration RBAC précédente en utilisant votre historique Git : ```bash git revert kubectl apply -f k8s/auth/prod/ ``` **Défaillance : fuite de secrets dans les journaux de CI.** Si votre pipeline imprime des valeurs de secrets dans les journaux, les attaquants ayant accès aux journaux peuvent compromettre le cluster. Cela arrive souvent lors de l'utilisation de `kubectl get secret -o yaml` dans un pipeline sans masquage. Récupération : Faites immédiatement tourner le secret divulgué. Pour un jeton de compte de service, supprimez le secret et laissez Kubernetes en générer un nouveau, ou utilisez un nouveau compte de service. Ensuite, mettez à jour le pipeline pour éviter d'imprimer des secrets ; utilisez `kubectl get secret -o jsonpath='{.data.token}' | base64 -d` uniquement lorsque cela est nécessaire et ne l'affichez jamais sur stdout. Mieux encore, utilisez des outils comme Sealed Secrets ou un coffre-fort pour éviter de manipuler des secrets bruts dans la CI. **Défaillance : les changements d'authentification cassent d'autres services.** Parce que les rôles et les liaisons ont une portée globale au cluster (même s'ils sont namespacés), un changement dans un namespace peut affecter l'accès inter-namespaces. Par exemple, supprimer une ClusterRoleBinding dont dépend un système de surveillance peut casser la collecte de métriques. Diagnostic : Vérifiez les liaisons de rôle de cluster et cherchez des conséquences inattendues : ```bash kubectl get clusterrolebindings -o wide | grep ``` Récupération : Revenez sur le changement et communiquez avec les équipes concernées. Utilisez une approche de déploiement canari : appliquez le changement d'authentification à un seul namespace ou à un sous-ensemble de charges de travail, surveillez les erreurs, puis déployez progressivement. Pour minimiser les risques, gardez toujours une sauvegarde de l'état précédent. Utilisez `kubectl get` avec `-o yaml` avant de faire des changements, et stockez la sauvegarde dans un emplacement versionné. Pour les outils GitOps comme Argo CD, l'historique des manifestes d'application sert de mécanisme de retour arrière. ## Pièges courants et comment les éviter Plusieurs erreurs récurrentes peuvent faire dérailler l'automatisation de l'authentification Kubernetes. Voici les plus fréquentes et des moyens pratiques de les prévenir. **Piège : coder en dur les jetons de compte de service dans les variables CI/CD.** Pourquoi cela arrive : les équipes veulent un moyen rapide de s'authentifier depuis l'extérieur du cluster et copient le jeton depuis `kubectl describe secret` dans une variable CI. Au fil du temps, le jeton expire ou fuit. Comment éviter : Utilisez des jetons à courte durée de vie via l'API TokenRequest ou un outil comme `kubectl create token`. Pour une automatisation de longue durée, utilisez une intégration OIDC ou un compte de service avec des jetons projetés qui tournent automatiquement. Dans votre pipeline, récupérez le jeton au moment de l'exécution : ```bash TOKEN=$(kubectl create token my-sa -n production --duration=1h) ``` **Piège : accorder cluster-admin aux comptes de service CI/CD.** Pourquoi cela arrive : il est pratique de donner au pipeline un accès complet pour déployer n'importe quoi n'importe où. Mais un pipeline compromis devient une compromission à l'échelle du cluster. Comment éviter : Appliquez le moindre privilège. Créez des comptes de service séparés pour chaque étape (par exemple, `deploy-dev`, `deploy-prod`) et n'accordez que les namespaces et les ressources dont ils ont besoin. Par exemple, le déployeur de production a besoin de `create`, `update`, `patch` sur les déploiements, les services et les configmaps dans le namespace de production uniquement. Revoyez les autorisations trimestriellement avec un script qui liste toutes les liaisons de rôle pour les comptes de service de CI. **Piège : ne pas valider le YAML avant d'appliquer.** Pourquoi cela arrive : les développeurs copient du YAML depuis la documentation et le modifient, introduisant des erreurs de syntaxe qui échouent à l'application, provoquant des échecs de pipeline. Comment éviter : Ajoutez une étape de lint dans la CI en utilisant `kubeconform` ou `kubeval` : ```bash kubeconform -strict -summary k8s/auth/ ``` Utilisez également `kubectl apply --dry-run=client` pour détecter les erreurs de schéma avant de toucher au cluster. **Piège : ignorer l'expiration des jetons dans les pods de longue durée.** Pourquoi cela arrive : avant Kubernetes 1.21, les jetons de compte de service étaient des JWT non expirants. Après le changement, les pods qui tournent longtemps peuvent perdre l'accès lorsque le jeton expire. Comment éviter : Pour les charges de travail de longue durée, assurez-vous que le pod utilise un jeton de compte de service projeté avec une expiration et une audience spécifiées. Le kubelet rafraîchira le jeton automatiquement. Dans la spécification de votre pod : ```yaml volumes: - name: sa-token projected: sources: - serviceAccountToken: path: token expirationSeconds: 3600 audience: my-api ``` **Piège : manque de journalisation d'audit pour les changements d'authentification.** Pourquoi cela arrive : les équipes appliquent des changements sans enregistrer qui a fait quoi, rendant le dépannage et les enquêtes de sécurité difficiles. Comment éviter : Activez la journalisation d'audit Kubernetes et envoyez les journaux à un système central. Si vous utilisez un outil GitOps, l'historique Git sert de piste d'audit. Pour les changements manuels, appliquez une politique selon laquelle tous les changements passent par le pipeline, et désactivez l'accès direct `kubectl` à la production pour les humains. ## Liste de contrôle opérationnelle Utilisez cette liste de contrôle pour vous assurer que votre automatisation CI/CD de l'authentification Kubernetes reste sûre et efficace. Attribuez un responsable unique pour chaque tâche récurrente et définissez une fréquence de revue. | Tâche | Responsable | Fréquence | Commande de vérification | |-------|-------------|-----------|--------------------------| | Revoir les comptes de service et l'utilisation des jetons | Priya Shah, ingénieure plateforme | Mensuelle | `kubectl get serviceaccounts --all-namespaces -o yaml \| grep -B2 automountServiceAccountToken` | | Auditer les liaisons de rôle pour le moindre privilège | Marcus Chen, ingénieur sécurité | Trimestrielle | `kubectl get rolebindings --all-namespaces -o yaml \| kubectl neat` | | Faire tourner les jetons CI/CD | Responsable du pipeline DevOps (rotation) | 90 jours | `kubectl create token ci-deployer -n production --duration=2160h` | | Tester la récupération après un échec de changement d'authentification | Ingénieur fiabilité site de garde | Mensuelle (jour de jeu) | Exécuter une application simulée défectueuse en staging et vérifier le script de retour arrière | | Mettre à jour les manifestes RBAC du pipeline depuis Git | Tech lead, équipe plateforme | À chaque fusion vers main | `kubectl apply --dry-run=client -f k8s/auth/` | Chaque tâche doit être attribuée à une personne nommée, pas à une équipe, pour garantir la responsabilité. Par exemple, Priya Shah est responsable de la revue mensuelle des comptes de service ; si elle part, la tâche est transférée explicitement. La liste de contrôle opérationnelle elle-même doit être revue trimestriellement par le responsable de l'équipe plateforme pour s'assurer qu'elle correspond à la topologie actuelle du cluster et aux exigences de sécurité. Au-delà de la liste de contrôle, automatisez autant que possible. Utilisez des déclencheurs CI/CD pour exécuter des vérifications d'autorisation après chaque déploiement : ```yaml # extrait de .gitlab-ci.yml auth-verify: stage: verify script: - kubectl auth can-i list pods --as=system:serviceaccount:$NAMESPACE:$SA -n $NAMESPACE - kubectl auth can-i update deployments --as=system:serviceaccount:$NAMESPACE:$SA -n $NAMESPACE only: - main ``` Et configurez des alertes pour les requêtes API non autorisées. Par exemple, en utilisant Prometheus et Alertmanager, créez une alerte sur `apiserver_audit_requests_total{code="403"}` dépassant un seuil. ## Conclusion L'automatisation CI/CD de l'authentification Kubernetes n'est pas une tâche à configurer et à oublier ; c'est une pratique continue qui exige de l'observation, des changements contrôlés et une récupération vérifiée. En inventoriant votre environnement, en définissant des chemins de configuration sûrs, en vérifiant chaque changement avec des commandes concrètes et en vous préparant aux modes de défaillance, vous pouvez réduire considérablement le risque d'incidents liés à l'authentification. Commencez petit : choisissez un compte de service utilisé par votre application, définissez son rôle et sa liaison dans Git, et créez un pipeline qui l'applique et le vérifie avec `kubectl auth can-i`. Ensuite, étendez à d'autres namespaces et adoptez éventuellement GitOps pour une gestion déclarative complète. Rappelez-vous les principes fondamentaux : moindre privilège, pas de secrets dans les journaux, changements observables et un plan de retour arrière pour chaque application. Un flux de travail fiable rend les échecs visibles, protège les valeurs sensibles, limite les changements à la ressource prévue et définit la vérification de récupération avant qu'un incident ne force la décision. Comme prochaine étape, choisissez une vérification à faible risque dans la liste de contrôle opérationnelle, enregistrez l'état actuel, exécutez la vérification documentée et comparez le résultat avec le signal attendu. Passez en revue les dépendances telles que les comptes de service, les rôles et les liaisons de rôle, et gardez le processus itératif. Avec ces pratiques, votre automatisation de l'authentification Kubernetes sera robuste, sécurisée et maintenable.