Pourquoi utiliser Secrets Manager plutôt que de coder les secrets en dur ?
Un dépôt privé ne protège pas un mot de passe de base de données codé en dur — c'est une illusion de sécurité que l'on découvre souvent trop tard, après une rotation d'accès forcée ou une fuite via un log d'application. AWS Secrets Manager existe précisément pour découpler les secrets du code, et sa rotation automatique change fondamentalement la surface d'attaque.
Résumé (TL;DR) — Secrets Manager vs. secrets codés en dur
| Critère | Secret codé en dur | AWS Secrets Manager |
|---|---|---|
| Exposition en cas de fuite du dépôt | Immédiate et permanente | Aucune (le code ne contient pas le secret) |
| Rotation du mot de passe | Manuelle, risquée, souvent ignorée | Automatique, sans interruption de service |
| Audit d'accès | Impossible | CloudTrail enregistre chaque appel GetSecretValue |
| Gestion multi-environnements | Copie manuelle, divergence garantie | Secrets distincts par environnement, même code |
| Révocation d'urgence | Redéploiement requis | Rotation immédiate sans toucher au code |
Comment fonctionne AWS Secrets Manager
Secrets Manager stocke les secrets sous forme de paires clé-valeur chiffrées avec AWS KMS. L'application ne reçoit jamais le secret au moment du déploiement — elle l'interroge à l'exécution via l'API GetSecretValue. Ce découplage est le point central : le secret n'existe nulle part dans le pipeline CI/CD, les variables d'environnement du conteneur, ou le système de fichiers de l'instance.
La rotation automatique s'appuie sur une fonction Lambda dédiée. Secrets Manager invoque cette Lambda selon un calendrier configurable. La Lambda génère un nouveau mot de passe, le met à jour dans la base de données cible, puis met à jour la valeur du secret. Pendant la rotation, Secrets Manager maintient simultanément l'ancienne et la nouvelle version du secret (étiquettes AWSPENDING, AWSCURRENT, AWSPREVIOUS) pour éviter toute interruption de service.
Secrets Manager"] -->|Invoque| Lambda["Lambda Rotation"] Lambda -->|Nouveau mot de passe| RDS Lambda -->|Met à jour AWSCURRENT| SM
- Application → Secrets Manager : l'application appelle
GetSecretValueà l'exécution, jamais au build. - Secrets Manager → KMS : le secret chiffré est déchiffré via la clé KMS associée avant d'être retourné.
- Rotation Lambda : invoquée automatiquement selon le calendrier, elle met à jour le secret dans RDS et dans Secrets Manager de façon atomique.
- Versions parallèles : pendant la rotation,
AWSCURRENTreste valide jusqu'à ce que la Lambda confirme le succès de la mise à jour.
Pourquoi un dépôt privé ne suffit pas
L'argument 'mon repo est privé' repose sur l'hypothèse que le seul vecteur de fuite est la lecture directe du code source. En pratique, les secrets codés en dur fuient par des chemins bien différents :
- Logs d'application : une stack trace qui inclut la chaîne de connexion complète dans un message d'erreur.
- Historique Git : un secret supprimé dans le dernier commit reste accessible via
git logougit reflog. GitHub et GitLab conservent l'historique complet même après suppression du fichier. - Artefacts de build : images Docker, packages Lambda, archives ZIP — tous peuvent embarquer des fichiers de configuration contenant des secrets.
- Variables d'environnement exposées : les variables d'environnement sont visibles dans les consoles ECS, Lambda, et Elastic Beanstalk sans contrôle d'accès granulaire.
- Accès développeur étendu : chaque développeur ayant accès au dépôt connaît le secret de production — sans qu'aucun audit ne soit possible.
Un secret dans un dépôt privé, c'est comme une clé sous le paillasson : la porte est fermée, mais quiconque connaît la convention sait où chercher.
Mise en place de Secrets Manager — étapes concrètes
Étape 1 : Créer le secret
Commencez par stocker le secret existant dans Secrets Manager. Cette étape migre la valeur sans toucher au code applicatif — les deux coexistent temporairement pendant la transition.
aws secretsmanager create-secret \
--name prod/myapp/db-password \
--description 'Mot de passe RDS PostgreSQL pour myapp en production' \
--secret-string '{"username":"myapp_user","password":"MonMotDePasse123!"}' \
--region us-east-1
Étape 2 : Autoriser l'application à lire le secret
L'IAM est la couche de contrôle réelle. Sans politique explicite, aucun service ne peut lire le secret — même dans le même compte. Attachez cette politique au rôle IAM de votre application (rôle d'exécution Lambda, rôle de tâche ECS, profil d'instance EC2).
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "LireSecretDB",
"Effect": "Allow",
"Action": "secretsmanager:GetSecretValue",
"Resource": "arn:aws:secretsmanager:us-east-1:123456789012:secret:prod/myapp/db-password-*"
}
]
}
Notez le suffixe -* dans l'ARN : Secrets Manager ajoute automatiquement un suffixe aléatoire de 6 caractères à chaque secret. L'ARN exact est retourné par la commande create-secret — utilisez-le, ou utilisez le wildcard pour couvrir les rotations futures.
Étape 3 : Lire le secret depuis l'application
L'application interroge Secrets Manager à l'initialisation de la connexion. Voici l'appel CLI équivalent pour valider l'accès avant d'intégrer dans le code :
aws secretsmanager get-secret-value \
--secret-id prod/myapp/db-password \
--region us-east-1 \
--query SecretString \
--output text
En production, mettez en cache la valeur retournée pour la durée de vie de la connexion — appeler GetSecretValue à chaque requête SQL est inutile et génère des coûts supplémentaires. Secrets Manager facture par appel API.
Étape 4 : Activer la rotation automatique
Pour RDS, AWS fournit des fonctions Lambda de rotation prédéfinies. La commande suivante active la rotation tous les 30 jours en utilisant une Lambda de rotation gérée par AWS pour RDS PostgreSQL. Vérifiez la disponibilité des Lambdas de rotation dans votre région avant de configurer.
aws secretsmanager rotate-secret \
--secret-id prod/myapp/db-password \
--rotation-lambda-arn arn:aws:lambda:us-east-1:123456789012:function:SecretsManagerRDSPostgreSQLRotationSingleUser \
--rotation-rules AutomaticallyAfterDays=30 \
--region us-east-1
- createSecret : la Lambda crée une nouvelle version du secret avec l'étiquette
AWSPENDING. - setSecret : le nouveau mot de passe est appliqué dans la base de données RDS.
- testSecret : la Lambda vérifie que la connexion avec le nouveau mot de passe fonctionne.
- finishSecret :
AWSPENDINGdevientAWSCURRENT, l'ancienne version passe enAWSPREVIOUS. L'application n'est jamais interrompue.
Cas réel : la mauvaise hypothèse qui coûte cher
Symptôme observé : après une rotation manuelle du mot de passe RDS (forcée par la politique de sécurité trimestrielle), l'application retourne des erreurs de connexion en production à 3h du matin. L'équipe passe deux heures à chercher un problème réseau.
Mauvais diagnostic initial : le groupe de sécurité RDS a changé, ou le VPC a un problème de routage — parce que les logs montrent 'connection refused' sans détail supplémentaire.
Cause réelle : le mot de passe est codé en dur dans une variable d'environnement de la tâche ECS. La rotation manuelle a mis à jour RDS mais pas la définition de tâche ECS. Les nouvelles tâches démarrent avec l'ancien mot de passe.
Avec Secrets Manager et rotation automatique : la Lambda de rotation met à jour RDS et le secret de façon atomique. L'application lit AWSCURRENT à chaque nouvelle connexion. La rotation se produit sans intervention humaine, sans incident à 3h du matin.
La rotation manuelle n'échoue pas parce que les ingénieurs sont négligents — elle échoue parce qu'elle implique de synchroniser plusieurs systèmes à la main, sans transaction.
Interaction entre KMS et Secrets Manager — ce que la documentation ne dit pas clairement
Par défaut, Secrets Manager utilise la clé KMS gérée par AWS aws/secretsmanager. Si vous utilisez une clé KMS gérée par le client (CMK), le rôle IAM de l'application doit avoir à la fois secretsmanager:GetSecretValue ET kms:Decrypt sur cette CMK spécifique. L'erreur retournée en cas de permission KMS manquante est souvent interprétée comme une erreur Secrets Manager — ce qui mène à des heures de débogage IAM dans la mauvaise direction.
Vérifiez les permissions KMS si GetSecretValue retourne AccessDeniedException malgré une politique Secrets Manager correcte :
aws kms describe-key \
--key-id alias/ma-cle-secrets \
--region us-east-1
aws kms get-key-policy \
--key-id alias/ma-cle-secrets \
--policy-name default \
--region us-east-1 \
--output text
Vérification de l'audit avec CloudTrail
Chaque appel GetSecretValue est enregistré dans CloudTrail. C'est la différence fondamentale avec un secret codé en dur : vous savez qui a accédé à quoi, quand, depuis quelle IP, avec quel rôle IAM.
aws cloudtrail lookup-events \
--lookup-attributes AttributeKey=EventName,AttributeValue=GetSecretValue \
--start-time 2024-01-01T00:00:00Z \
--end-time 2024-01-02T00:00:00Z \
--region us-east-1 \
--query 'Events[*].{Heure:EventTime,Utilisateur:Username,Source:SourceIPAddress}' \
--output table
Conclusion — Pourquoi Secrets Manager est la bonne approche
Coder un secret en dur dans un dépôt privé résout un problème imaginaire tout en créant des problèmes réels : impossibilité d'auditer les accès, rotation manuelle risquée, exposition via les artefacts de build et l'historique Git. AWS Secrets Manager découple le secret du code, automatise la rotation sans interruption de service, et fournit un audit complet via CloudTrail.
La migration est progressive : créez le secret, mettez à jour le code pour appeler GetSecretValue, activez la rotation — dans cet ordre. Le coût opérationnel est marginal comparé au coût d'un incident de sécurité.
- Documentation officielle : AWS Secrets Manager User Guide
- Rotation automatique pour RDS : Rotating secrets
- Référence IAM : Service Authorization Reference — Secrets Manager
Glossaire
| Terme | Définition |
|---|---|
| Secret | Donnée sensible (mot de passe, clé API, certificat) stockée et chiffrée dans Secrets Manager. |
| Rotation automatique | Processus géré par Secrets Manager qui renouvelle périodiquement un secret via une fonction Lambda sans interruption de service. |
| AWSCURRENT | Étiquette de version désignant la valeur active du secret, retournée par défaut par GetSecretValue. |
| CMK (Customer Managed Key) | Clé KMS créée et contrôlée par le client, utilisable à la place de la clé par défaut pour chiffrer les secrets. |
| GetSecretValue | Action API Secrets Manager permettant de récupérer la valeur déchiffrée d'un secret à l'exécution. |
Commentaires
Enregistrer un commentaire