Retour au cours

infra / kubernetes

Secrets

Leçon 71 exercice

Explication

Ce que vous allez apprendre

  • Distinguer l'usage prévu d'un Secret (données sensibles) de celui d'un ConfigMap malgré une API très similaire
  • Expliquer pourquoi l'encodage base64 d'un Secret n'est PAS du chiffrement, et ce que cela implique en termes de risque
  • Identifier où se situe la vraie protection d'un Secret : RBAC et chiffrement au repos dans etcd, pas le Secret lui-même
  • Utiliser les types spécialisés de Secrets (docker-registry, tls) plutôt que d'encoder du base64 à la main
  • Justifier pourquoi une solution externe de gestion de secrets (Vault, External Secrets) est parfois préférable au Secret natif

Dans quel contexte ?

Un audit de sécurité découvre qu'un développeur a donné, par erreur de configuration RBAC, un accès en lecture sur tous les Secrets du namespace production à un compte de service utilisé par un outil de monitoring tiers. N'importe qui compromettant ce compte de service pourrait lire en clair tous les mots de passe de base de données stockés en Secrets, car le base64 ne protège absolument rien face à un accès légitime à l'API. Cet incident illustre pourquoi la vraie protection d'un Secret Kubernetes réside dans le contrôle d'accès RBAC, jamais dans l'encodage lui-même.

Un objet qui ressemble beaucoup au précédent

D'abord, sur le papier, un Secret se manipule presque exactement comme un ConfigMap vu à la leçon précédente : mêmes verbes kubectl, même logique d'injection en variable ou en fichier monté.

Prérequis

Cette leçon suppose acquis le fonctionnement des ConfigMaps (leçon précédente) : l'API des Secrets est presque identique, seule l'intention et le traitement interne diffèrent.

Ce qui change vraiment : l'intention

Son intention est radicalement différente : il est réservé aux données sensibles, comme les mots de passe, les jetons ou les certificats. Kubernetes le traite d'ailleurs différemment en interne, par exemple il n'est jamais affiché en clair dans kubectl describe.

Le malentendu le plus dangereux à corriger tout de suite

Il faut être extrêmement clair sur un point : un Secret encode ses valeurs en base64, ce qui n'est PAS du chiffrement. Le base64 est réversible instantanément par n'importe qui, une simple commande suffit à le décoder.

Piège fréquent

Le base64 utilisé par les Secrets n'est PAS du chiffrement : c'est un simple encodage réversible instantanément (echo "<valeur>" | base64 -d). Ne considérez jamais qu'un Secret est "protégé" par ce seul mécanisme — la protection réelle vient du RBAC et, en production, du chiffrement au repos dans etcd.

Ce que ça signifie concrètement

Si une personne malveillante obtient l'accès en lecture à un Secret via l'API Kubernetes, elle lit le mot de passe en clair aussi facilement que si rien n'avait été encodé.

Où se trouve la vraie protection

La vraie protection ne vient donc pas du Secret lui-même, mais du contrôle d'accès autour de lui, le RBAC vu plus loin dans ce cours, et en production sérieuse, du chiffrement des données au repos dans etcd.

Pourquoi il existe plusieurs types de Secrets

Kubernetes propose des types spécialisés, comme docker-registry pour s'authentifier auprès d'un registre d'images privé, ou tls pour un certificat et sa clé. Ces cas d'usage sont si courants que la CLI les gère avec des raccourcis dédiés, évitant d'écrire du base64 à la main.

Type de SecretUsage
Opaque (générique)Mots de passe, jetons, clés API arbitraires
kubernetes.io/dockerconfigjsonAuthentification auprès d'un registre d'images privé
kubernetes.io/tlsCertificat et clé privée TLS

Aller plus loin que le Secret natif

Pour des besoins de production sérieux, on va généralement plus loin que le Secret Kubernetes natif, avec un gestionnaire externe comme Vault, qui apporte rotation automatique, audit et chiffrement fort.

Maintenant que les données sensibles sont protégées, la leçon suivante s'attaque à un besoin différent : faire persister les données au-delà de la vie d'un Pod, avec les volumes persistants.

Commandes & code

Secrets

Comme les ConfigMaps, mais destinés aux données sensibles (mots de passe, tokens, clés TLS).

yaml
# secret.yaml - valeurs encodées en base64 (PAS chiffrées par défaut !)
apiVersion: v1
kind: Secret
metadata:
  name: db-credentials
type: Opaque
data:
  username: YWRtaW4=          # echo -n 'admin' | base64
  password: czNjcjN0cGFzcw==   # echo -n 's3cr3tpass' | base64
bash
# Créer un secret directement depuis la CLI (évite d'écrire du base64 à la main)
kubectl create secret generic db-credentials \
  --from-literal=username=admin \
  --from-literal=password=s3cr3tpass

# Secret TLS pour un Ingress
kubectl create secret tls api-tls --cert=tls.crt --key=tls.key

# Secret pour tirer une image depuis un registre privé
kubectl create secret docker-registry regcred \
  --docker-server=registry.example.com \
  --docker-username=ci-bot \
  --docker-password="$REGISTRY_TOKEN"
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: api-deployment
spec:
  replicas: 2
  selector:
    matchLabels:
      app: api
  template:
    metadata:
      labels:
        app: api
    spec:
      imagePullSecrets:
        - name: regcred                # utilise le secret pour tirer une image privée
      containers:
        - name: api
          image: registry.example.com/myorg/api:1.4.2
          env:
            - name: DB_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: db-credentials
                  key: password
bash
# base64 n'est PAS du chiffrement : quiconque a accès au Secret peut le décoder
kubectl get secret db-credentials -o jsonpath='{.data.password}' | base64 -d

# En production : activer le chiffrement au repos dans etcd (EncryptionConfiguration)
# et/ou utiliser un gestionnaire externe (Vault, Sealed Secrets, External Secrets Operator)

Résumé

  • Un Secret encode en base64, il ne CHIFFRE rien par défaut : contrôler l'accès RBAC est indispensable.
  • secretKeyRef injecte une clé précise, envFrom.secretRef injecte tout le Secret.
  • imagePullSecrets permet de tirer des images depuis un registre privé.
  • En production réelle : chiffrement etcd au repos + Vault/Sealed Secrets pour la gestion du cycle de vie.

Exercices pratiques

1 disponible
1

Mission : corriger une fuite potentielle de mots de passe

Objectif : Comprendre pourquoi le base64 ne protège rien, et savoir créer un Secret correctement sans jamais écrire de base64 à la main.

Contexte

Un audit de sécurité vient de découvrir qu'un compte de service utilisé par un outil de monitoring tiers a un accès en lecture sur tous les Secrets du namespace production. Le responsable sécurité, un peu paniqué, demande : "Est-ce grave si ces Secrets sont juste encodés en base64 et pas vraiment lisibles sans effort ?" Tu dois clarifier la situation et corriger la création du Secret concerné.

Résoudre l’exercice →