## Introduction

L'automatisation de l'approbation des demandes de signature de certificats (Certificate Signing Request, CSR) Kubernetes dans les pipelines CI/CD est un besoin courant pour les équipes qui gèrent leurs propres certificats TLS ou s'intègrent à une infrastructure à clés publiques (PKI) externe. Sans flux de travail contrôlé, les opérateurs approuvent les CSR manuellement (lent et sujet aux erreurs) ou les laissent en attente indéfiniment, ce qui interrompt les déploiements d'applications.

Cet article fournit des conseils pratiques aux développeurs, consultants DevOps et équipes techniques de startups qui souhaitent automatiser l'approbation des CSR en toute sécurité. Il couvre le cycle de vie d'une CSR dans Kubernetes, la configuration du contrôle d'accès basé sur les rôles (RBAC) pour l'automatisation, la construction d'une étape CI/CD qui approuve les CSR, la vérification du certificat émis, et la gestion des échecs et retours en arrière.

Tout au long, nous insistons sur la sécurité opérationnelle : observer avant de modifier, limiter le rayon d'impact, protéger les valeurs sensibles, vérifier les résultats et documenter les chemins de récupération.

## Inventaire des versions et de l'environnement

Avant d'automatiser l'approbation des CSR, établissez la version exacte de Kubernetes et les détails de l'environnement. Le comportement des ressources CertificateSigningRequest a changé au fil des versions, notamment concernant les noms de signataires et les autorisations d'approbation.

Prérequis essentiels :

- Un cluster Kubernetes (v1.19 ou ultérieure recommandée ; l'approbation spécifique au signataire a été introduite plus tôt mais a mûri plus tard)
- kubectl configuré avec les autorisations appropriées pour inspecter les CSR
- Si vous utilisez un signataire personnalisé, assurez-vous qu'il est installé et configuré (par exemple, cert-manager, le signataire intégré du kube-controller-manager ou une autorité de certification externe)
- Un compte de service pour l'automatisation CI/CD avec un RBAC minimal

Commencez par une observation en lecture seule :

```bash
kubectl version --short
kubectl get csr
```

La sortie attendue inclut la version du cluster et une liste des CSR avec leurs conditions. Par exemple :

```
NAME        AGE   SIGNERNAME                     REQUESTOR          CONDITION
my-app-csr  2m    kubernetes.io/kube-apiserver-client   system:serviceaccount:default:my-app   Pending
```

Notez le `signerName`. Les clusters modernes utilisent des noms de signataires comme `kubernetes.io/kube-apiserver-client`, `kubernetes.io/kubelet-serving` ou des noms personnalisés. L'automatisation doit faire correspondre le signataire à l'usage prévu ; approuver une CSR pour le mauvais signataire peut délivrer un certificat avec des autorisations non intentionnelles.

Vérifiez la santé des composants :

```bash
kubectl get pods -n kube-system | grep -E 'kube-controller-manager|kube-apiserver'
```

Si le gestionnaire de contrôleurs qui exécute l'approbateur CSR est défaillant, l'automatisation peut sembler s'exécuter mais ne pas aboutir.

Pour les tests locaux, utilisez un cluster à nœud unique (kind, minikube) et appliquez un manifeste CSR à la fois. Vérifiez avec :

```bash
kubectl get csr my-csr -o yaml
```

Avant de passer en production, confirmez que l'API des certificats du cluster est activée (elle l'est par défaut) et que le serveur d'API a `--cluster-signing-cert-file` et `--cluster-signing-key-file` définis si vous utilisez le signataire intégré.

## Chemin de configuration sûr

L'automatisation de l'approbation des CSR nécessite une configuration RBAC soignée. Le principe du moindre privilège est essentiel : un compte de service CI/CD doit pouvoir approuver uniquement les CSR avec des noms de signataires spécifiques et, idéalement, seulement pour son espace de noms ou un motif de nommage connu.

### Étape 1 : Créer un ServiceAccount dédié

```yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: csr-approver
  namespace: ci-cd
```

Appliquez-le :

```bash
kubectl apply -f sa.yaml
```

### Étape 2 : Définir un ClusterRole avec des autorisations d'approbation limitées

```yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: csr-approver
rules:
- apiGroups: ["certificates.k8s.io"]
  resources: ["certificatesigningrequests/approval"]
  verbs: ["update"]
- apiGroups: ["certificates.k8s.io"]
  resources: ["certificatesigningrequests"]
  verbs: ["get", "list", "watch"]
- apiGroups: ["certificates.k8s.io"]
  resources: ["certificatesigningrequests/status"]
  verbs: ["patch", "update"]
```

Cela permet de visualiser les CSR et de mettre à jour la sous-ressource d'approbation, ce qui est distinct de la modification de la CSR elle-même.

### Étape 3 : Lier le ClusterRole au ServiceAccount avec une restriction resourceName si possible

Si vous pouvez prévoir les noms de CSR (par exemple, générés à partir d'un nom de déploiement), utilisez resourceNames pour restreindre l'approbation à des CSR spécifiques :

```yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: csr-approver-binding
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: csr-approver
subjects:
- kind: ServiceAccount
  name: csr-approver
  namespace: ci-cd
```

Sans resourceNames, le compte peut approuver n'importe quelle CSR avec les verbes autorisés, ce qui est large mais parfois nécessaire si les noms sont dynamiques. Une alternative consiste à utiliser un webhook de validation pour appliquer des motifs de nommage.

Appliquez et vérifiez :

```bash
kubectl apply -f rbac.yaml
kubectl auth can-i approve certificatesigningrequests --as=system:serviceaccount:ci-cd:csr-approver
```

Sortie attendue : `yes` si les autorisations sont correctes.

Testez le plus petit changement : créez une CSR de test, puis approuvez-la avec les identifiants du compte de service. Utilisez `kubectl --as` pour usurper l'identité sans créer de fichier kubeconfig :

```bash
kubectl create csr test-csr --signer kubernetes.io/kube-apiserver-client --requestor test
kubectl certificate approve test-csr --as=system:serviceaccount:ci-cd:csr-approver
```

Si l'approbation réussit, la configuration est valide.

Gardez les données sensibles hors de la CI/CD : utilisez des jetons à courte durée de vie ou une identité de charge de travail au lieu de fichiers kubeconfig statiques avec des identifiants à longue durée.

## Vérification et diagnostic

Après avoir implémenté l'automatisation, vérifiez que les CSR sont approuvées correctement et que les certificats sont émis.

### Inspecter une CSR avant approbation

```bash
kubectl get csr my-csr -o yaml
```

Exemple de sortie condensée :

```yaml
spec:
  signerName: kubernetes.io/kube-apiserver-client
  usages:
  - client auth
  request: LS0tLS1CRUdJTiBDRV...
status:
  conditions: []
```

Vérifiez que les `usages` et le `signerName` correspondent aux attentes. Une CSR d'authentification client ne doit pas être approuvée pour l'authentification serveur.

### Approuver via kubectl

```bash
kubectl certificate approve my-csr
```

Sortie attendue :

```
certificatesigningrequest.certificates.k8s.io/my-csr approved
```

### Vérifier le statut

```bash
kubectl get csr my-csr
```

Si approuvée et signée, la CSR affichera `Approved,Issued` sous CONDITIONS.

### Récupérer le certificat émis

```bash
kubectl get csr my-csr -o jsonpath='{.status.certificate}' | base64 -d > client.crt
```

Vérifiez les détails du certificat :

```bash
openssl x509 -in client.crt -text -noout
```

Recherchez `Subject`, `Issuer`, `Validity` et `X509v3 Extended Key Usage` pour confirmer que le certificat correspond à la demande.

### Diagnostiquer les CSR bloquées

Si une CSR reste `Pending`, vérifiez les événements :

```bash
kubectl describe csr my-csr
```

Causes courantes :

- Aucun approbateur avec la permission d'approuver ce signataire
- L'approbateur ne fonctionne pas (si vous utilisez un contrôleur personnalisé)
- Mauvaise configuration du certificat/clé du signataire

Pour les pipelines CI/CD, enregistrez le nom et le statut de la CSR après la tentative d'approbation :

```bash
STATUS=$(kubectl get csr my-csr -o jsonpath='{.status.conditions[?(@.type=="Approved")].status}')
if [ "$STATUS" != "True" ]; then
  echo "CSR non approuvée : $STATUS"
  exit 1
fi
```

Cela empêche la poursuite du pipeline avec un certificat non signé.

## Modes de défaillance et récupération

L'approbation automatisée des CSR peut échouer de plusieurs manières. Comprendre chaque cas aide à concevoir la récupération.

### Défaillance 1 : La CSR est approuvée mais le certificat n'est pas émis

Symptôme : La CSR affiche `Approved` mais pas `Issued`.

Cause : Le contrôleur de signature (le signataire CSR du kube-controller-manager) ne fonctionne pas ou sa clé de signature est manquante.

Diagnostic :

```bash
kubectl get pods -n kube-system | grep kube-controller-manager
kubectl logs -n kube-system kube-controller-manager-<node> | grep -i csr
```

Récupération : Assurez-vous que le gestionnaire de contrôleurs a `--cluster-signing-cert-file` et `--cluster-signing-key-file` configurés et que les fichiers existent. Redémarrez le contrôleur si nécessaire.

### Défaillance 2 : L'approbateur automatisé ne peut pas approuver la CSR en raison du RBAC

Symptôme : Les journaux du pipeline montrent `error: You must be logged in to the server (Unauthorized)` ou `forbidden`.

Cause : Règles RBAC manquantes ou jeton du compte de service expiré.

Diagnostic :

```bash
kubectl auth can-i approve certificatesigningrequests --as=system:serviceaccount:ci-cd:csr-approver
```

Récupération : Examinez le ClusterRole et la liaison. Assurez-vous que le compte de service est dans le bon espace de noms.

### Défaillance 3 : Mauvais signataire approuvé

Symptôme : Le certificat émis ne peut pas être utilisé pour son objectif prévu (par exemple, un certificat client utilisé comme certificat serveur).

Cause : L'automatisation a approuvé une CSR avec un nom de signataire qui ne correspond pas aux besoins de l'application.

Récupération : Refusez ou supprimez la CSR et générez-en une nouvelle avec le bon signataire :

```bash
kubectl delete csr bad-csr
```

Prévention : validez les noms de signataires dans le script d'automatisation avant l'approbation.

### Défaillance 4 : Le pipeline approuve les CSR de manière trop large

Symptôme : Des CSR non autorisées sont approuvées automatiquement, délivrant potentiellement des identifiants à des attaquants.

Cause : RBAC trop permissif (pas de resourceNames, pas de filtrage par signataire).

Récupération : Révoquez immédiatement la liaison, supprimez le jeton du compte de service et auditez quelles CSR ont été approuvées. Renforcez le RBAC avec des noms de signataires et des noms de ressources spécifiques.

Retour en arrière pour les changements de configuration : gardez tous les fichiers YAML dans le contrôle de version. Si un changement provoque des échecs, revenez au commit précédent et réappliquez.

Exemple de retour en arrière :

```bash
git revert <commit-hash>
kubectl apply -f rbac.yaml
```

Vérifiez toujours le nouvel état avec `kubectl auth can-i` et une CSR de test.

## Liste de contrôle des opérations

Utilisez cette liste avant et après le déploiement de l'automatisation CSR en production.

Avant le déploiement :

- [ ] Version du cluster prise en charge (v1.19+ pour l'approbation spécifique au signataire)
- [ ] ServiceAccount créé dans un espace de noms dédié
- [ ] ClusterRole limité à `certificatesigningrequests/approval` et aux verbes de lecture nécessaires
- [ ] ClusterRoleBinding lie le ServiceAccount au ClusterRole
- [ ] Si possible, les resourceNames restreignent l'approbation à des noms de CSR connus
- [ ] Test avec `kubectl auth can-i` en tant que compte de service
- [ ] Test avec une CSR d'exemple de bout en bout dans un environnement de staging
- [ ] Le script de pipeline enregistre le nom et le statut de la CSR
- [ ] Plan de retour en arrière documenté (revert du commit, réappliquer le RBAC)

Pendant l'exploitation :

- [ ] Surveiller les CSR approuvées de manière inattendue (journaux d'audit)
- [ ] Faire tourner périodiquement les jetons du compte de service (si jetons statiques) ou utiliser une identité de charge de travail
- [ ] Garder les certificats de signature valides et les renouveler avant expiration
- [ ] Examiner régulièrement les autorisations RBAC pour le moindre privilège

Après la récupération d'un échec :

- [ ] Identifier la cause racine et documenter
- [ ] Appliquer une action corrective à l'automatisation
- [ ] Relancer une CSR de test pour confirmer la correction
- [ ] Mettre à jour le manuel opérationnel

Attribuez un propriétaire : par exemple, le responsable de plateforme (par exemple, Priya Shah) possède la configuration de l'automatisation CSR et la révise mensuellement ou après tout changement d'infrastructure.

## Pièges courants

### Piège 1 : Approuver les CSR manuellement par habitude

Pourquoi cela arrive : L'automatisation n'est pas mise en place ou pas fiable, donc les équipes reviennent à l'approbation manuelle.

Comment éviter : Implémentez l'approbation CI/CD avec journalisation et alertes. Si l'approbation manuelle reste, restreignez-la aux comptes de secours.

### Piège 2 : Utiliser cluster-admin pour le compte de service CI/CD

Pourquoi cela arrive : Configuration rapide et sale, ou manque de compréhension du RBAC.

Comment éviter : Utilisez le ClusterRole limité comme indiqué ci-dessus. Testez avec `kubectl auth can-i --list` pour voir toutes les autorisations.

### Piège 3 : Ignorer les noms de signataires

Pourquoi cela arrive : Les anciens clusters utilisaient par défaut un seul signataire, donc les équipes supposent qu'il n'y a pas de distinction.

Comment éviter : Inspectez toujours `spec.signerName` et faites correspondre la logique d'approbation au signataire attendu.

### Piège 4 : Ne pas vérifier le certificat émis

Pourquoi cela arrive : Le pipeline s'arrête après l'approbation, en supposant que l'émission a réussi.

Comment éviter : Vérifiez la condition `Issued` et décodez le certificat pour valider les usages et l'expiration.

### Piège 5 : Stocker un kubeconfig à longue durée dans la CI/CD

Pourquoi cela arrive : Simplicité.

Comment éviter : Utilisez des jetons à courte durée, OIDC ou une identité de charge de travail cloud. Faites tourner les secrets automatiquement.

## Conclusion

L'automatisation de l'approbation des CSR Kubernetes dans la CI/CD est réalisable avec un RBAC soigné, des étapes de vérification claires et une gestion robuste des échecs. La clé est de limiter étroitement les autorisations, de valider les noms de signataires et les usages, et de s'assurer que le contrôleur de signature est sain.

Commencez par une implémentation à faible risque : créez une CSR de test, approuvez-la via un compte de service restreint et vérifiez le certificat. Intégrez ensuite l'étape d'approbation dans votre pipeline avec une journalisation et une gestion des erreurs appropriées.

En suivant les pratiques de cet article, vous pouvez réduire la corvée manuelle, prévenir les certificats mal émis et maintenir un processus d'émission de certificats sûr et fiable dans vos clusters Kubernetes.