# 08 — Gestion des secrets > Bonnes pratiques pour les secrets de l'infrastructure : où ils sont, comment les rotater, et comment ne pas les exposer. --- ## 🔐 Inventaire des secrets ### Secrets stockés sur le serveur | Type | Localisation | Criticité | Rotation recommandée | |---|---|---|---| | Mdp Postgres principal | `~/docker/postgres/.env` | 🔴 Critique | 6 mois | | Mdp Postgres Zitadel | `~/docker/zitadel/.env` | 🔴 Critique | 6 mois | | Zitadel MASTERKEY | `~/docker/zitadel/.env` | 🔴⛔ IMMUABLE | Jamais | | Mdp Gitea DB | `~/docker/gitea/.env` | 🟡 Important | 6 mois | | Mdp n8n DB | `~/docker/n8n/.env` | 🟡 Important | 6 mois | | n8n Encryption Key | `~/docker/n8n/.env` | 🔴 Critique | Jamais (perte = perte workflows chiffrés) | | Client Secret OAuth2 (par outil) | `~/docker/oauth2-proxy-*/env` | 🟡 Important | 6 mois | | Cookie Secret OAuth2 | `~/docker/oauth2-proxy-*/env` | 🟢 Mineur | 1 an (déconnecte les users) | | Code Server password (fallback) | `~/docker/code-server/.env` | 🟢 Mineur | 6 mois | | Furious API credentials | `~/furious-to-zitadel/.env` | 🟡 Important | 6 mois | | Zitadel Service Account key | `~/furious-to-zitadel/zitadelfuriousimportkey.json` | 🔴 Critique | 1 an (avec expiration prévue) | | Traefik basic auth | `~/docker/traefik/docker-compose.yml` (label) | 🟡 Important | 6 mois | ### Secrets stockés ailleurs | Secret | Localisation | |---|---| | Mdp utilisateurs Zitadel | Dans la base Postgres Zitadel (hashés) | | Tokens de session OAuth2-Proxy | Dans les cookies HTTP des navigateurs des users | | Certificats Let's Encrypt | `~/docker/traefik/letsencrypt/acme.json` (chmod 600) | --- ## 🔒 Bonnes pratiques ### 1. Toujours utiliser un gestionnaire de mots de passe Pour stocker **tous** les secrets de l'infra : - **Bitwarden** (cloud + self-hosted possible) ← recommandé - **KeePassXC** (offline) - **1Password Business** Créer une **collection partagée "Seize Infra"** accessible aux mainteneurs (Hedi, Philippe, futur collègue). ### 2. Permissions Linux strictes Tous les fichiers contenant des secrets doivent avoir `chmod 600` : ```bash # Vérifier toutes les permissions de .env find ~/docker -name ".env" -exec ls -la {} \; # Toutes doivent montrer "-rw-------" (600) # Vérifier la clé Zitadel ls -la ~/furious-to-zitadel/zitadelfuriousimportkey.json # Doit être 600 ``` Corriger si nécessaire : ```bash chmod 600 ~/docker//.env ``` ### 3. Ne JAMAIS committer de secret sur Git Configurer `.gitignore` dans tous les dépôts : ```gitignore # Secrets .env *.env *.key *.pem *.p12 zitadelfuriousimportkey.json users-credentials.csv distribution-teams.csv roles-mapping.json letsencrypt/acme.json # Logs (peuvent contenir des secrets) *.log import.log ``` ### 4. Ne JAMAIS coller de secret dans une conversation IA Si tu colles un token, mdp, ou clé dans Claude / ChatGPT / autre, considère-le **compromis** : - Il peut être logué côté provider - Il peut être utilisé pour entraîner des modèles - L'historique est conservé pendant des mois → **Toujours masquer** les secrets (ex: `XXX_REDACTED_XXX`) avant de coller du contenu. ⚠️ Voir [HANDOVER.md](../HANDOVER.md) pour la liste des secrets qui ont été exposés pendant le développement et qui doivent être rotatés. ### 5. Audit des accès aux secrets Périodiquement, vérifier : - Qui a accès au gestionnaire de mots de passe ? - Y a-t-il des anciens employés à révoquer ? - Les permissions Linux sont-elles toujours OK ? --- ## 🔄 Procédures de rotation ### Rotation Client Secret OAuth2 (par outil) ⏱️ ~5 min par outil. ```bash # 1. Aller dans Zitadel Console # → Projects → Infra Seize → Applications → # → Actions → Generate Client Secret → copier la nouvelle valeur # 2. Mettre à jour le .env d'OAuth2-Proxy nano ~/docker/oauth2-proxy-/.env # Remplacer OAUTH2_PROXY_CLIENT_SECRET=... # 3. Sauvegarder dans le gestionnaire de mdp # 4. Restart OAuth2-Proxy cd ~/docker/oauth2-proxy- docker compose down docker compose up -d # 5. Tester le SSO en incognito ``` ### Rotation Postgres password (Gitea ou n8n) ⏱️ ~10 min. **Hors heures de bureau** (le service s'arrête brièvement). ```bash # 1. Générer nouveau mdp NEW_PWD=$(openssl rand -base64 32 | tr -d '+/=' | head -c 32) echo "Nouveau mdp : $NEW_PWD" # Sauvegarder dans le gestionnaire # 2. Changer le mdp dans Postgres docker exec -it postgres psql -U postgres -c "ALTER USER gitea WITH PASSWORD '$NEW_PWD';" # 3. Mettre à jour le .env du service nano ~/docker/gitea/.env # Remplacer GITEA_DB_PASSWORD=... # 4. Restart cd ~/docker/gitea docker compose down docker compose up -d # 5. Tester curl -sI https://git.seizeconsulting.com ``` ### Rotation Zitadel Service Account key ⏱️ ~10 min. ```bash # 1. Console Zitadel → Users → furious-import-service → Keys # → Créer une nouvelle clé (Type JSON) # → Télécharger immédiatement # → Supprimer l'ancienne clé (pour l'invalider) # 2. Transférer sur le serveur scp .json admin@:~/furious-to-zitadel/zitadelfuriousimportkey.json # 3. Sécuriser ssh admin@ chmod 600 ~/furious-to-zitadel/zitadelfuriousimportkey.json # 4. Tester les scripts cd ~/furious-to-zitadel source venv/bin/activate python3 assign-roles.py --dry-run # ou un autre script sans effet ``` ### Rotation Furious API credentials ```bash # 1. Sur Furious : Configuration → Utilisateurs API # → Supprimer l'ancien compte # → Créer un nouveau avec les mêmes permissions (User > Search uniquement) # → Sauvegarder identifiants dans le gestionnaire de mdp # 2. Mettre à jour le .env nano ~/furious-to-zitadel/.env # Remplacer FURIOUS_USERNAME et FURIOUS_PASSWORD # 3. Tester cd ~/furious-to-zitadel source venv/bin/activate ./test-auth.sh ``` ### ⛔ ZITADEL_MASTERKEY — IMMUABLE ⚠️ **NE JAMAIS CHANGER** le `ZITADEL_MASTERKEY` après le premier démarrage de Zitadel. Cette clé est utilisée pour chiffrer/déchiffrer les données sensibles en base. La changer = perdre l'accès à toutes les données. Si elle a été exposée → option drastique uniquement : 1. Backup complet des données critiques (export users via API) 2. Détruire l'instance Zitadel 3. Re-déployer from scratch avec une nouvelle MASTERKEY 4. Restore les users via les scripts d'import --- ## 📧 Configuration SMTP M365 (à faire) ⚠️ **Pas encore fait** au moment de la passation. ### Prérequis - Admin M365 (pas Hedi → solliciter quelqu'un d'autre) - Compte M365 dédié : `noreply@seizeconsulting.com` ### Étape 1 — Créer le compte M365 Demander à l'admin M365 : 1. Créer le compte `noreply@seizeconsulting.com` 2. Activer SMTP AUTH (peut nécessiter ticket Microsoft) 3. Désactiver MFA sur ce compte (incompatible avec SMTP) 4. Générer un **App Password** pour ce compte ### Étape 2 — Configurer dans Zitadel Console Zitadel → Default Settings → Notifications → SMTP Provider : | Paramètre | Valeur | |---|---| | Host | `smtp.office365.com` | | Port | `587` | | User | `noreply@seizeconsulting.com` | | Password | `` | | From | `noreply@seizeconsulting.com` | | From Name | `Seize Consulting` | | Reply-to | (vide ou `it@seizeconsulting.com`) | | TLS | ✅ Required | ### Étape 3 — Tester Console Zitadel → Default Settings → SMTP → **Test Email**. → Si OK, on peut désormais utiliser : - Welcome emails pour nouveaux users - Reset password - MFA Email codes - Notifications de sécurité --- ## 🔍 Audit des secrets exposés Pendant le développement (cf. [HANDOVER.md](../HANDOVER.md)), plusieurs secrets ont été exposés dans des conversations IA : | Secret | Statut | Action requise | |---|---|---| | Compte API Furious `mick.emmaus.90849` | 🔴 Exposé | **Rotater dans Furious** | | ID API Furious `6a0b0396817841ef2d3c87c8` | 🔴 Exposé | **Rotater dans Furious** | | Token JWT user HKA (1 instance) | 🟡 Expiré | OK (1h de vie) | | Noms + emails + job_titles ~10 collaborateurs | 🟡 Exposé | Pas de rotation possible, vigilance | ### Procédure post-incident 1. Rotater immédiatement le secret (procédures ci-dessus) 2. Vérifier les **logs d'accès** Zitadel/Furious pour détecter usage suspect 3. Documenter dans un fichier sécurité (qui, quand, quoi) 4. Si données personnelles exposées → notification CNIL si applicable --- ## 🛡️ Hardening complémentaire ### Activer fail2ban (recommandé) Pour bloquer automatiquement les IPs malveillantes qui scannent SSH ou OAuth2 : ```bash sudo apt install -y fail2ban # Config par défaut OK pour SSH sudo systemctl enable --now fail2ban # Vérifier sudo fail2ban-client status sshd ``` ### Activer Crowdsec (alternative moderne) ```bash curl -s https://install.crowdsec.net | sudo sh # Puis configurer les bouncers (cf-firewall-bouncer, etc.) ``` ### Monitoring des tentatives de login échouées Zitadel À mettre en place via : - Workflow n8n qui scrape les logs Zitadel toutes les heures - Alert si > 50 échecs en 1h (potentiellement attaque par brute force) --- ## 📚 Voir aussi - [HANDOVER.md](../HANDOVER.md) — Liste des secrets exposés à rotater en priorité - [03-zitadel-setup.md](./03-zitadel-setup.md) — Configuration du service account - [04-oauth2-proxy-pattern.md](./04-oauth2-proxy-pattern.md) — Rotation des secrets OAuth2 - [OPERATIONS.md](../OPERATIONS.md) — Procédures complètes de rotation