Les variables d’environnement Lambda sont de la configuration, pas un coffre à secrets : elles sont chiffrées au repos, mais quiconque détient lambda:GetFunctionConfiguration peut les lire en clair, elles apparaissent dans la console, et elles se font copier dans l’état IaC et l’outillage de déploiement. Le patron qui fonctionne : garder la configuration ordinaire dans les variables d’environnement, garder les secrets dans Parameter Store ou Secrets Manager, et ne mettre que le nom du secret dans l’environnement — puis récupérer et mettre en cache la valeur à l’init pour ne pas payer un appel d’API par invocation.
Ce qui se passe
Les variables d’environnement vivent dans la configuration de la fonction, plafonnées à 4 Ko au total pour toutes les clés. Lambda les chiffre au repos avec une clé KMS, ce qui protège le stockage — pas le chemin d’accès. L’action IAM qui lit la configuration d’une fonction est extrêmement courante dans les rôles de lecture seule et de développeur, donc un mot de passe de base de données dans une variable d’environnement est effectivement lisible par la moitié de l’organisation, et par chaque outil qui appelle GetFunction. Il atterrit aussi dans l’état Terraform ou CloudFormation, les journaux de déploiement et les reconstructions locales de .env. C’est ça, le vrai argument contre les secrets dans les variables d’environnement : la distribution, pas le chiffrement.
Les deux vrais coffres se séparent proprement sur les fonctionnalités. SSM Parameter Store, palier standard, est gratuit, contient des chaînes ordinaires et des valeurs SecureString chiffrées avec KMS, et suffit amplement pour les clés d’API, les indicateurs de fonctionnalités et les chaînes de connexion. Secrets Manager facture par secret par mois plus par appel d’API, et vous achète la rotation gérée (native pour les identifiants RDS), l’accès inter-comptes et la réplication automatique. La table de décision complète est dans Secrets Manager ou Parameter Store; la version courte pour Lambda : rotation ou inter-comptes signifie Secrets Manager, tout le reste signifie habituellement Parameter Store.
La question de performance est là où Lambda diffère des serveurs. Un serveur récupère un secret une fois au démarrage et le garde des jours. Un environnement d’exécution Lambda démarre souvent, et une conception naïve « récupérer le secret dans le handler » transforme chaque invocation en appel d’API SSM ou Secrets Manager — latence, risque de limitation (le débit du palier standard de Parameter Store est limité), et pour Secrets Manager, un coût par appel à volume. Le correctif, c’est la cache : récupérer dans la phase d’init pour que la valeur vive la durée de l’environnement, ou utiliser l’extension AWS Parameters and Secrets pour Lambda, qui fait rouler un mandataire de cache local sur localhost:2773 dans l’environnement d’exécution avec un TTL configurable.
Quoi vérifier en premier
- Ce qui se trouve actuellement dans les variables d’environnement. Un audit prend des minutes et trouve régulièrement des mots de passe de base de données qui sont là depuis des années.
- Si quelque chose tourne en rotation. Si la réponse est « on redéploierait », la rotation n’arrivera jamais vraiment — c’est le plus fort signal en faveur de Secrets Manager.
- Où la récupération se fait dans le code. Les récupérations dans le handler multiplient les appels d’API par le nombre d’invocations; celles dans l’init les multiplient par le nombre de démarrages à froid.
- La politique IAM de la fonction. Elle devrait permettre de lire les paramètres ou secrets précis dont elle a besoin, par ARN ou préfixe de chemin — pas
ssm:GetParametersur*.
Comment vérifier
Auditez ce que la fonction expose aujourd’hui :
aws lambda get-function-configuration --function-name my-function \
--query 'Environment.Variables'
Si quelque chose dans cette sortie vous fait grimacer, c’est ça le constat. Vérifiez ce que la fonction a le droit de lire :
aws iam list-attached-role-policies --role-name my-function-role
aws iam get-role-policy --role-name my-function-role --policy-name secrets-access
Rangez un secret proprement et relisez-le :
aws ssm put-parameter --name /prod/api/stripe-key \
--type SecureString --value 'sk_live_example'
aws ssm get-parameter --name /prod/api/stripe-key --with-decryption \
--query 'Parameter.Value'
Dans la console, les variables de la fonction se trouvent sous Lambda > Functions > (fonction) > Configuration > Environment variables — bien en vue, ce qui est justement le problème. La documentation des services vit à https://docs.aws.amazon.com/systems-manager/ et https://docs.aws.amazon.com/secretsmanager/.
L’approche
- Triez chaque valeur entre configuration et secret. Niveau de journalisation, nom de table, URL en aval : variable d’environnement. Tout ce qui compterait dans une fuite — mots de passe, clés d’API, clés de signature : un coffre. Dans le doute, traitez-la comme un secret.
- Par défaut Parameter Store; passez à Secrets Manager sur un déclencheur. Les déclencheurs : rotation gérée (identifiants RDS surtout), partage inter-comptes, ou réplication multi-régions du secret lui-même. Sans déclencheur, le palier standard de Parameter Store fait le travail gratuitement.
- Mettez la référence dans l’environnement, pas la valeur.
STRIPE_KEY_PARAM=/prod/api/stripe-keydans les variables; la fonction la résout à l’exécution. Les environnements ne diffèrent que par le préfixe de chemin. - Récupérez une fois par environnement, pas une fois par invocation. Soit dans le code d’init (hors du handler), soit en attachant la couche d’extension AWS Parameters and Secrets et en appelant
http://localhost:2773/systemsmanager/parameters/get?name=...avec l’en-têteX-Aws-Parameters-Secrets-Token: $AWS_SESSION_TOKEN. L’extension gère le rafraîchissement par TTL, ce que la simple cache d’init ne fait pas. - Restreignez l’IAM au chemin. Accordez
ssm:GetParametersurarn:aws:ssm:*:*:parameter/prod/api/*(pluskms:Decryptsur la clé pertinente), pour qu’une fonction compromise ne puisse pas lire les paramètres de tout le compte. - Planifiez la réalité de la rotation. Avec la cache en phase d’init, un secret tourné n’est ramassé que par les nouveaux environnements d’exécution — les vieux environnements chauds gardent la valeur périmée des heures. Utilisez le TTL de l’extension, ou attrapez les échecs d’authentification et re-récupérez une fois avant d’échouer.
Quand ce n’est pas la bonne approche
Pour un projet personnel ou un outil interne avec un seul développeur, un paramètre SecureString lu à l’init est toute l’histoire — ajouter Secrets Manager, des Lambda de rotation et des couches d’extension, c’est de la cérémonie sans modèle de menace. À l’inverse, si votre régime de conformité exige une rotation démontrée et un audit de chaque accès aux identifiants, le palier gratuit de Parameter Store est la mauvaise économie — le coût par secret de Secrets Manager est le constat d’audit le moins cher que vous fermerez jamais.
Erreurs fréquentes
- Croire que le chiffrement KMS des variables d’environnement les rend sûres — l’exposition, c’est l’accès en lecture IAM et l’étalement de l’outillage, contre quoi le chiffrement au repos ne fait rien.
- Récupérer les secrets dans le handler et découvrir la limitation de Parameter Store à la première pointe de trafic.
- Mettre en cache à l’init sans plan de rafraîchissement, puis voir une rotation « briser la production » parce que les environnements chauds gardaient le vieux mot de passe.
- Une seule déclaration IAM avec
Resource: "*"pour SSM, faisant de chaque fonction un passe-partout.
Garder le contrôle
- Roulez un audit trimestriel des
Environment.Variablesde toutes les fonctions — un petit script par-dessusaws lambda list-functionsattrape les régressions. - Imposez des conventions de nommage (
/env/service/usage) pour que la restriction IAM par chemin reste propre. - Alarmez sur le volume d’appels
GetParameterde SSM et Secrets Manager par fonction; un bond signifie que quelqu’un a déplacé une récupération dans le chemin du handler. - Testez la rotation en pré-production de bout en bout, incluant le comportement des environnements chauds, avant de lui faire confiance en production.
Le patron est plate et c’est sa vertu : des références dans l’environnement, des valeurs dans un coffre, une récupération par environnement, l’IAM restreint à un chemin. Si personne dans votre équipe ne possède vraiment l’environnement AWS de bout en bout, c’est la racine de la plupart de ces problèmes — Stack Harbor opère des comptes AWS au quotidien sous Opérations AWS, et vous pouvez réserver une revue AWS.