Ce que tu apprends
- Ce qu'est un fichier .env, pourquoi .gitignore n'est pas négociable et des clés séparées par environnement
- Quoi faire si vous avez déjà poussé un secret : le faire tourner, car supprimer le commit ne suffit pas
- Les deploy keys Convex et chiffrer les clés API utilisateur au repos au lieu de les stocker en clair
Vue d'ensemble
Vous jonglez maintenant avec des clés pour Clerk, Convex, bientôt Stripe et probablement un provider d'IA. Chacune est une clé vers quelque chose de précieux - vos services, votre argent, les données de vos clients. Les gérer bien n'est pas optionnel dès que de l'argent réel et de vrais utilisateurs sont en jeu. Cette leçon est la version rigoureuse de l'habitude des secrets que vous avez commencée au Cours 1 : où vivent les secrets, comment les tenir hors de Git pour toujours, la procédure d'urgence quand l'un s'échappe, comment les deploy keys donnent accès à votre hébergement sans exposer vos credentials maîtres, et pourquoi chaque clé que vos utilisateurs vous donnent doit être chiffrée, pas stockée en texte lisible.
Ce que vous allez apprendre
Vous allez apprendre ce qu'est un fichier env et pourquoi il existe, comment utiliser .gitignore pour qu'un secret ne puisse jamais être committé, pourquoi chaque environnement reçoit ses propres clés, les étapes exactes de récupération si vous avez déjà poussé un secret, comment fonctionnent les deploy keys Convex et où elles vont, et comment chiffrer au repos les clés API fournies par les utilisateurs, pour qu'une fuite de base de données ne mette pas les credentials de vos clients entre les mains des attaquants.
Prérequis
Les bases des secrets du Cours 1 (clés dans .env, .env dans .gitignore) et une app multi-services de la partie précédente de ce cours, car le risque grandit avec chaque intégration que vous ajoutez. La page de fondamentaux sur ce qu'est un fichier env couvre les bases absolues si vous voulez les avoir détaillées avant d'aller plus loin.
Le problème
Les secrets fuités sont l'une des catastrophes de débutant les plus fréquentes et coûteuses, et elles arrivent en silence. Vous collez une clé dans un fichier pour tester quelque chose, la committez sans réfléchir, poussez vers GitHub, et maintenant cette clé est pour toujours dans l'historique de votre repository - lisible par quiconque peut voir le repo, et en quelques minutes scrapée par des bots qui fouillent GitHub public exactement pour cela. Des gens avec une clé Stripe ou cloud fuitée se sont réveillés devant des milliers de dollars de débits frauduleux. Et stocker les clés API de vos utilisateurs en clair signifie qu'une seule violation de base de données expose tous les credentials clients d'un coup. Rien de tout cela ne demande de la malchance. Cela demande un commit distrait. Cette leçon rend la distraction structurellement difficile.
Ce qu'est un fichier .env et gitignore bien fait
Un fichier .env est un simple fichier texte qui tient vos secrets en paires KEY=value, séparé de votre code, pour que le code puisse les lire à l'exécution sans que les valeurs soient en dur dans des fichiers committés. Tout l'intérêt est la séparation : le code dit « lis la clé Stripe depuis l'environnement », et la vraie clé siège dans .env, qui ne quitte jamais votre machine. Ce qui rend cela sûr, c'est .gitignore - un fichier qui liste ce que Git ne doit jamais suivre. Votre .env et toutes ses variantes y ont leur place, toujours, dans chaque projet, sans exception. Faites-le bien une fois par projet, et un secret ne peut physiquement pas être committé.
# .env.local - vos vrais secrets. NE JAMAIS committer.
CLERK_SECRET_KEY=sk_live_xxxxxxxxxxxxxxxxxxxx
STRIPE_SECRET_KEY=sk_live_xxxxxxxxxxxxxxxxxxxx
CONVEX_DEPLOY_KEY=prod:your-deployment|xxxxxxxxxxxxxxxxxxxx
ENCRYPTION_KEY=base64-32-byte-random-value-here# .gitignore - les lignes non négociables pour chaque projet
node_modules
.env
.env.local
.env.*.local
.DS_Store
distUne habitude utile : committez un fichier .env.example (avec les clés mais des valeurs vides ou fictives), pour que quiconque met en place le projet sache quelles variables sont nécessaires sans jamais committer un vrai secret. Le fichier exemple est sûr à committer précisément parce qu'il ne contient aucune vraie valeur.
Des clés séparées par environnement
Development et production doivent utiliser des clés différentes. Vous l'avez vu avec Clerk (pk_test versus pk_live), et Stripe fait pareil (clés test versus live). La raison est le rayon d'impact : si une clé de development fuit, elle ne peut toucher que des données de test et le mode test, donc les dégâts sont limités. Une clé de production fuitée touche de vrais clients et de l'argent réel. Les garder strictement séparées signifie qu'une erreur pendant la construction ne peut jamais atteindre des données live, et vous pouvez donner vos clés de development à un coéquipier ou un agent sans risquer le business. N'utilisez jamais une clé de production en development « pour gagner du temps » - c'est exactement ainsi qu'un script de test débite accidentellement une vraie carte ou supprime un vrai utilisateur.
- Clés de development (mode test) : sûres à utiliser en construisant, ne touchent que des données de test.
- Clés de production (mode live) : argent réel, vrais utilisateurs - gardez-les et ne les utilisez que dans votre environnement déployé.
- Posez les secrets de production dans les dashboards de votre hôte (Vercel) et de votre backend (Convex), pas dans un fichier committé.
- Une clé dev fuitée est un désagrément ; une clé prod fuitée peut être une catastrophe. Gardez-les séparées.
Quoi faire si vous avez POUSSÉ un secret
C'est la section la plus importante de la leçon, car cela vous arrivera, ou arrivera à quelqu'un avec qui vous travaillez, tôt ou tard. L'instinct est de supprimer la ligne et de recommitter, ou de supprimer le commit. Cela ne suffit pas et c'est dangereux, car le secret vit toujours dans votre historique Git et, si le repo a jamais été public ou poussé quelque part, est peut-être déjà scrapé. La seule hypothèse sûre est qu'un secret poussé est compromis. Donc le vrai fix est de le faire tourner : allez au service, révoquez la clé fuitée et générez-en une nouvelle. Nettoyer l'historique Git est secondaire et optionnel une fois la clé morte. Traitez la rotation comme la première et la plus urgente étape, à chaque fois.
- Supposez le secret compromis dès l'instant où il a été poussé. Les bots scannent GitHub public en quelques minutes.
- FAITES TOURNER D'ABORD : allez au service (Stripe, Clerk, Convex, votre provider d'IA), révoquez l'ancienne clé, créez-en une nouvelle.
- Mettez à jour la nouvelle clé dans votre .env et dans les variables d'environnement de votre hôte/backend.
- Ensuite seulement, optionnellement, nettoyez l'historique (des outils comme git filter-repo ou BFG) - mais une clé morte ne peut de toute façon plus vous nuire.
- Vérifiez sur le service toute activité non autorisée (débits, nouveaux utilisateurs, appels API) pendant que la clé était exposée.
Disons-le clairement : supprimer le commit n'annule pas la fuite du secret. Faire tourner la clé, si. Si vous retenez une chose de cette leçon, retenez : faire tourner d'abord, nettoyer ensuite.
Deploy keys Convex
Quand votre hébergement (Vercel) build et déploie votre app, il a besoin de la permission de pousser vos fonctions backend et votre schema vers Convex. Il serait faux de donner à votre environnement de build votre login personnel. À la place, Convex émet une deploy key : une credential délimitée qui laisse un environnement automatisé déployer vers un deployment Convex précis et rien de plus. Vous la générez dans le dashboard Convex pour votre deployment de production puis la stockez comme variable d'environnement dans Vercel (jamais dans le code). Le principe se généralise : les environnements automatisés reçoivent des credentials étroites et délimitées, pas votre compte maître, pour qu'une deploy key fuitée ait un rayon d'impact limité et puisse être régénérée sans toucher à rien d'autre qui vous appartient.
# À poser dans Vercel comme variable d'environnement (PAS dans un fichier committé).
# Générée dans le dashboard Convex pour votre deployment de PRODUCTION.
CONVEX_DEPLOY_KEY=prod:your-deployment-name|xxxxxxxxxxxxxxxxxxxxxxxx
# Votre commande de build l'utilise ensuite pour déployer le backend pendant le build Vercel :
# bunx convex deploy --cmd "bun run build"Chiffrer au repos les clés fournies par les utilisateurs
Voici un scénario auquel ce cours mène directement : votre produit laisse les utilisateurs apporter leur propre clé API (leur clé OpenAI, leur clé Stripe, leur clé pour un service que vous intégrez). Vous la stockez pour pouvoir agir en leur nom. Si vous stockez cette clé en clair dans votre base de données, alors une seule violation donne à un attaquant les credentials de chaque client d'un coup - une catastrophe qui transforme un incident en des centaines. Le fix est de chiffrer les valeurs sensibles avant qu'elles n'entrent en base de données, et de ne les déchiffrer qu'au moment où vous les utilisez. Même si quelqu'un vole votre base de données, les blobs chiffrés sont inutiles sans la clé de chiffrement, qui vit séparément dans votre environnement, pas dans la base de données. C'est la différence entre « nous avons eu une violation » et « nous avons eu une violation et fuité les clés de chaque client ».
// Chiffrer avant de stocker, ne déchiffrer qu'à l'usage. La ENCRYPTION_KEY vit dans
// votre environnement, PAS dans la base de données, pour qu'une base volée seule soit inutile.
import { createCipheriv, createDecipheriv, randomBytes } from 'node:crypto'
const key = Buffer.from(process.env.ENCRYPTION_KEY!, 'base64') // 32 bytes
export function encryptSecret(plain: string) {
const iv = randomBytes(12)
const cipher = createCipheriv('aes-256-gcm', key, iv)
const enc = Buffer.concat([cipher.update(plain, 'utf8'), cipher.final()])
const tag = cipher.getAuthTag()
// Stocker iv + tag + ciphertext ensemble ; aucun d'eux n'est secret en soi.
return Buffer.concat([iv, tag, enc]).toString('base64')
}
export function decryptSecret(stored: string) {
const raw = Buffer.from(stored, 'base64')
const iv = raw.subarray(0, 12)
const tag = raw.subarray(12, 28)
const enc = raw.subarray(28)
const decipher = createDecipheriv('aes-256-gcm', key, iv)
decipher.setAuthTag(tag)
return Buffer.concat([decipher.update(enc), decipher.final()]).toString('utf8')
}Vous n'avez pas besoin d'être cryptographe pour utiliser un algorithme bien testé comme AES-256-GCM via la librairie crypto standard de votre plateforme, comme ci-dessus. La règle de pouce : n'inventez jamais votre propre chiffrement, utilisez toujours la librairie standard et gardez la clé de chiffrement dans votre environnement, totalement séparée des données qu'elle protège.
Erreurs fréquentes
Les douloureuses : committer un .env parce que .gitignore manquait ou était faux ; supprimer un secret fuité d'un fichier en croyant qu'il est en sécurité alors qu'il vit encore dans l'historique et est déjà scrapé ; réutiliser une clé de production en development et toucher accidentellement des données live ; mettre une deploy key ou une credential maître dans du code committé ; et stocker les clés API utilisateur en clair, si bien qu'une violation les fuite toutes. Chacune est évitée par la même discipline : secrets hors de Git, clés séparées par environnement, faire tourner en cas de fuite, chiffrer les données sensibles au repos.
ROI business
La discipline des secrets est une assurance bon marché contre une catégorie de catastrophes qui a ruiné des petits produits : une facture cloud qui déborde à cause d'une clé fuitée, un incident de fraude à cause d'une clé de paiement fuitée, ou une violation qui expose les credentials clients et déclenche une responsabilité juridique sous le RGPD et les lois de protection des données américaines. Le coût de bien faire est quelques minutes de setup par projet et une fonction de chiffrement standard que vous écrivez une fois. Le coût de mal faire se mesure en milliers de dollars, exposition juridique et confiance perdue que vous ne regagnerez peut-être jamais. Pour une fondatrice, c'est l'une des habitudes au plus haut rendement par effort de tout le stack.
Checklist
Vous êtes assez sûr pour ajouter les paiements quand tout ceci est vrai sur chaque projet que vous shippez.
- Chaque projet a un .gitignore correct et aucun .env n'a jamais été committé.
- Development et production utilisent des clés séparées, avec les secrets de prod posés dans vos dashboards d'hôte et de backend.
- Vous connaissez la règle : un secret poussé se fait tourner d'abord, l'historique se nettoie ensuite.
- Chaque clé API fournie par un utilisateur est chiffrée au repos, la clé de chiffrement tenue hors de la base de données.
Ressources
Gardez en favoris les pages de clés API et de rotation de vos services, pour pouvoir révoquer une clé fuitée en secondes quand le moment vient. GitHub propose aussi le secret scanning, qui peut vous alerter des clés fuitées - activez-le. La page de fondamentaux sur ce qu'est un fichier env couvre les bases. Avec votre stack sécurisé, les deux prochaines leçons ajoutent l'argent : Stripe Checkout et Subscriptions, puis les détails de facturation plus délicats.
Votre mission
Auditez l'un de vos vrais projets tout de suite. Confirmez que .gitignore exclut chaque variante de .env, fouillez l'historique du repo pour une clé committée par accident, et si vous en trouvez une, faites-la tourner immédiatement. Ajoutez ensuite un .env.example avec des valeurs vides, pour que le projet documente ses secrets requis en sécurité. Si votre app stocke une clé fournie par un utilisateur, enveloppez-la avec les fonctions encrypt/decrypt ci-dessus. Cet audit est le genre de chose que les fondateurs repoussent jusqu'à ce qu'il soit trop tard - faites-le aujourd'hui.
Prochaine leçon
Votre stack est sécurisé. Maintenant faites-le gagner de l'argent. La prochaine leçon ajoute Stripe : Hosted versus Embedded Checkout, produits et prix, subscriptions avec facturation mensuelle et annuelle et la stricte discipline test versus production qui vous laisse bâtir les paiements sans jamais risquer un vrai débit.

Commentaires
Chargement des commentaires.
Poster un commentaire