Secrets et défense en profondeur
Les credentials des intégrations : chiffrés au repos
Les mots de passe IMAP, tokens OAuth, clĂ©s d'ERP des tenants vivent en base â chiffrĂ©s Fernet (AES-CBC + HMAC, via cryptography) :
- chiffrĂ© au write path (Ă l'enregistrement de l'intĂ©gration), dĂ©chiffrĂ© juste avant usage (au moment du poll IMAP, de l'export SFTP) â jamais en clair au repos ni dans une rĂ©ponse d'API (le read path ne renvoie jamais les secrets) ;
- la clé maßtresse vit dans l'environnement (
ENCRYPTION_KEY, injectĂ©e depuis le Secrets Manager en prod), rĂ©solue au boot avec fail loud si absente â l'app refuse de dĂ©marrer plutĂŽt que de tourner sans chiffrement ; - pourquoi ce niveau applicatif alors que le disque est dĂ©jĂ chiffrĂ© ? Parce qu'un dump SQL, un backup, un accĂšs en lecture Ă la base ne suffisent plus Ă rĂ©colter les secrets des clients â la clĂ© est ailleurs.
L'hygiĂšne : gitleaks aux deux portes
Le secret le plus dangereux est celui qui entre dans git (l'historique n'oublie jamais). gitleaks tourne deux fois : en pre-commit (scan du diff â le secret n'entre pas) et en CI sur l'historique complet (GIT_DEPTH: 0 â ce qui serait passĂ© est dĂ©tectĂ©), avec une allowlist explicite (.env.example, fixtures, locks). Deux portes, car le pre-commit se contourne (--no-verify) â la CI, non.
Les headers : l'API durcie par défaut
Le SecurityHeadersMiddleware pose sur chaque rĂ©ponse : X-Content-Type-Options: nosniff, X-Frame-Options: DENY, Referrer-Policy: no-referrer, HSTS un an â et le plus Ă©lĂ©gant : Content-Security-Policy: default-src 'none'. Une API qui ne sert que du JSON n'a besoin de rien charger : la CSP maximale ne coĂ»te rien et neutralise toute une classe d'exploitation si un navigateur affiche une rĂ©ponse.
La doctrine : ADR-0015, le substrat fail-closed
L'ADR qui lie tout le module : la dĂ©fense multi-tenant repose sur un substrat qui Ă©choue fermĂ© â la RLS (module 3). Pas sur des validations runtime, pas sur la vigilance des devs. Les autres couches (sql_safety qui re-qualifie l'AST du SQL gĂ©nĂ©rĂ© par le LLM, la whitelist de tools, le Redactor Langfuse, les clĂ©s Redis scopĂ©es) sont des couches complĂ©mentaires : chacune peut faillir, l'isolation tient. Le principe de conception Ă retenir : identifier LE mĂ©canisme qui doit ĂȘtre infaillible, le rendre structurel (base, pas code), puis empiler le reste comme du confort.
Pourquoi chiffrer les credentials en base alors que le disque est déjà chiffré ?