# 🔐 Guide Sécurisation Secrets - FailDaily
**Date** : 28 novembre 2025  
**Statut** : Production OVH + Local  
**Audience** : Équipe technique (1-2 personnes)

---

## 📌 Philosophie

> **"Garde tes secrets hors git, sur le disque avec droits stricts, et ne les copie pas dans les images Docker"**

Pour un projet à 1-2 personnes sur serveur unique OVH, **pas besoin de HashiCorp Vault** tout de suite.  
**Solution actuelle suffisante** : `.env` bien protégés + rotation manuelle + backup chiffré.

---

## 📋 INVENTAIRE DES SECRETS

### Secrets Actuels FailDaily

```bash
# Backend API (.env.ovh)
JWT_SECRET=SjGId6c9pMyK4!+*VTPoYvs2qz0uJ5L=@FU-OX7CwgAWHfhb%Rm#8rDxliNkt13n
DB_PASSWORD=<password_mysql>
LOGS_DB_PASSWORD=<password_logs_db>

# Email SMTP
SMTP_USER=contact@taaazzz-prog.fr
SMTP_PASS=@51008473@ZoE@

# OpenAI Moderation
OPENAI_API_KEY=<clé_api>

# Firebase Push Notifications (si utilisé)
backend-api/faildaily-8efdd-firebase-adminsdk-fbsvc-09630fc557.json
```

### Localisation Fichiers

```
Local:
- docker/.env
- docker/.env.local
- backend-api/.env

OVH Production:
- ~/FailDaily/docker/.env.ovh
- ~/FailDaily/backend-api/.env
- ~/FailDaily/backend-api/faildaily-*-firebase-adminsdk-*.json
```

---

## ✅ PLAN D'ACTION IMMÉDIAT

### 🔴 PHASE 1 : Sécuriser (30 minutes)

#### Étape 1.1 : Permissions Fichiers (5 min)

```bash
# Se connecter à OVH
ssh ubuntu@141.94.42.172

# Sécuriser fichiers .env (lecture/écriture propriétaire uniquement)
chmod 600 ~/FailDaily/docker/.env.ovh
chmod 600 ~/FailDaily/docker/.env.local
chmod 600 ~/FailDaily/backend-api/.env

# Sécuriser service account Firebase
chmod 600 ~/FailDaily/backend-api/faildaily-*-firebase-adminsdk-*.json

# Vérifier permissions
ls -la ~/FailDaily/docker/.env* | grep -v "rw-------" && echo "❌ Permissions incorrectes" || echo "✅ OK"
ls -la ~/FailDaily/backend-api/.env | grep -v "rw-------" && echo "❌ Permissions incorrectes" || echo "✅ OK"
```

**Résultat attendu** :
```
-rw------- 1 taaazzz taaazzz 1234 Nov 28 .env.ovh
-rw------- 1 taaazzz taaazzz  456 Nov 28 .env
```

---

#### Étape 1.2 : Rotation JWT_SECRET (10 min)

```bash
# Générer nouveau secret (64+ caractères)
node -e "console.log(require('crypto').randomBytes(64).toString('base64'))"

# Résultat exemple:
# xK9mP2vL8jN4qR7tY5wE3aS6dF1gH0iO+zX/cV=bM~nU-pQ

# Éditer .env.ovh
nano ~/FailDaily/docker/.env.ovh

# Remplacer:
# JWT_SECRET=ancien_secret
# Par:
# JWT_SECRET=xK9mP2vL8jN4qR7tY5wE3aS6dF1gH0iO+zX/cV=bM~nU-pQ

# Redémarrer backend
cd ~/FailDaily/docker
docker-compose -f docker-compose.ovh.yml restart backend

# Vérifier logs
docker-compose -f docker-compose.ovh.yml logs backend | tail -20
```

**⚠️ ATTENTION** : Tous les utilisateurs connectés seront déconnectés (devront se reconnecter).

---

#### Étape 1.3 : Rotation SMTP_PASS (5 min)

```bash
# 1. Changer mot de passe sur OVH Manager
# https://www.ovh.com/manager/web/#/email-domain/taaazzz-prog.fr/email/contact

# Étapes:
# - Se connecter au manager OVH
# - Emails → contact@taaazzz-prog.fr
# - "Modifier le mot de passe"
# - Générer nouveau mot de passe fort (16+ caractères)
# - Copier le nouveau mot de passe

# 2. Mettre à jour .env.ovh
nano ~/FailDaily/docker/.env.ovh

# Remplacer:
# SMTP_PASS=@51008473@ZoE@
# Par:
# SMTP_PASS=nouveau_password_ovh

# 3. Redémarrer backend
docker-compose -f docker-compose.ovh.yml restart backend

# 4. Tester envoi email
cd ~/FailDaily/backend-api
node test-smtp.js
```

---

#### Étape 1.4 : Backup Secrets (10 min)

**Option A : Password Manager (RECOMMANDÉ)**

```bash
# Installer Bitwarden Desktop
# https://bitwarden.com/download/

# Créer coffre "FailDaily Production"
# Ajouter entrées sécurisées:

Entrée 1 - JWT Secret
  Titre: FailDaily JWT_SECRET Production
  Nom d'utilisateur: -
  Mot de passe: [Coller JWT_SECRET]
  Notes: Généré le 28/11/2025, ne jamais committer

Entrée 2 - Database
  Titre: FailDaily MySQL Root Password
  Nom d'utilisateur: root
  Mot de passe: [DB_PASSWORD]
  URI: mysql://141.94.42.172:3306
  
Entrée 3 - Email SMTP
  Titre: FailDaily SMTP OVH
  Nom d'utilisateur: contact@taaazzz-prog.fr
  Mot de passe: [SMTP_PASS]
  URI: ssl0.ovh.net:465
  
Entrée 4 - OpenAI
  Titre: FailDaily OpenAI API Key
  Nom d'utilisateur: -
  Mot de passe: [OPENAI_API_KEY]
  Notes: Modération IA

# Activer 2FA sur Bitwarden
# Paramètres → Sécurité → Authentification à deux facteurs
```

**Option B : Fichier Chiffré GPG**

```bash
# Sur machine locale
cd "D:\WEB API\FailDaily"

# Créer fichier secrets
cat > secrets-production.txt <<EOF
# FailDaily Production Secrets - 28/11/2025
JWT_SECRET=xK9mP2vL8jN4qR7tY5wE3aS6dF1gH0iO+zX/cV=bM~nU-pQ
DB_PASSWORD=votre_password_mysql
LOGS_DB_PASSWORD=votre_password_logs
SMTP_USER=contact@taaazzz-prog.fr
SMTP_PASS=nouveau_password_ovh
OPENAI_API_KEY=sk-xxxxxxxxxxxxx
EOF

# Chiffrer avec GPG
gpg --symmetric --cipher-algo AES256 secrets-production.txt
# Entrer passphrase forte (20+ caractères, mémoriser ou stocker dans Bitwarden)

# Vérifier fichier chiffré créé
ls -lh secrets-production.txt.gpg

# Supprimer original de façon sécurisée
shred -u secrets-production.txt

# Backup fichier chiffré
# - Copier sur clé USB
# - Upload sur cloud personnel chiffré (OneDrive, Dropbox)
# - NE PAS committer dans git

# Déchiffrer plus tard si besoin:
# gpg -d secrets-production.txt.gpg > secrets.txt
```

---

### 🟠 PHASE 2 : Nettoyer (15 minutes)

#### Étape 2.1 : Supprimer Copies Inutiles

```bash
# Sur OVH
ssh ubuntu@141.94.42.172

# Rechercher tous .env
find ~ -name ".env*" -type f 2>/dev/null

# Vérifier qu'on a uniquement:
# ~/FailDaily/docker/.env.ovh
# ~/FailDaily/backend-api/.env

# Supprimer backups/duplicatas si présents
rm ~/FailDaily/docker/.env.backup 2>/dev/null || true
rm ~/FailDaily/docker/.env.bak 2>/dev/null || true
rm ~/FailDaily/backend-api/.env.old 2>/dev/null || true

# Supprimer scripts test avec secrets hardcodés
rm ~/FailDaily/backend-api/test-smtp-prod.js 2>/dev/null || true

# Chercher service accounts Firebase dupliqués
find ~ -name "*firebase-adminsdk*.json" 2>/dev/null

# Garder uniquement:
# ~/FailDaily/backend-api/faildaily-8efdd-firebase-adminsdk-fbsvc-09630fc557.json
```

#### Étape 2.2 : Vérifier Git (5 min)

```bash
# Sur machine locale
cd "D:\WEB API\FailDaily"

# Vérifier aucun .env tracké
git ls-files | grep -E "\.env|password|smtp" || echo "✅ Aucun secret tracké"

# Vérifier .gitignore
cat .gitignore | grep -E "\.env|password|firebase"

# Résultat attendu:
# .env
# .env.*
# **/*password*.md
# **/firebase-adminsdk-*.json

# Chercher secrets dans l'historique git (optionnel mais important)
git log --all --full-history --source --find-copies-harder -- "**/.env*" "**/*password*"

# Si résultats trouvés, voir section "Nettoyer historique git" ci-dessous
```

#### Étape 2.3 : Vérifier Images Docker (5 min)

```bash
# Sur OVH
ssh ubuntu@141.94.42.172

# Inspecter image backend
docker inspect docker-backend | grep -i "env"

# Vérifier qu'il n'y a PAS de secrets hardcodés dans l'image
# Secrets doivent venir de:
# 1. env_file: .env.ovh
# 2. environment: variables injectées au runtime
# 3. Volumes montés

# Vérifier docker-compose.ovh.yml
cat ~/FailDaily/docker/docker-compose.ovh.yml | grep -A 10 "backend:"

# Résultat attendu:
# backend:
#   env_file:
#     - .env.ovh  ✅ Bon (secrets hors image)
#   environment:
#     NODE_ENV: production  ✅ Bon (non-sensible)
```

---

### 🟢 PHASE 3 : Améliorer (Optionnel - 1-2 heures)

#### Amélioration 1 : Docker Secrets (si migration vers Swarm)

```yaml
# docker/docker-compose.ovh.yml (version Swarm)
version: '3.8'

services:
  backend:
    image: docker-backend
    secrets:
      - jwt_secret
      - db_password
      - smtp_password
    environment:
      JWT_SECRET_FILE: /run/secrets/jwt_secret
      DB_PASSWORD_FILE: /run/secrets/db_password
      SMTP_PASS_FILE: /run/secrets/smtp_password

secrets:
  jwt_secret:
    file: ./secrets/jwt_secret.txt
  db_password:
    file: ./secrets/db_password.txt
  smtp_password:
    file: ./secrets/smtp_password.txt
```

**Adapter code backend** :
```javascript
// backend-api/src/config/loadSecrets.js
const fs = require('fs');

function loadSecret(name, envVar) {
  const secretFile = process.env[`${name}_FILE`];
  if (secretFile && fs.existsSync(secretFile)) {
    return fs.readFileSync(secretFile, 'utf8').trim();
  }
  return process.env[envVar];
}

module.exports = {
  JWT_SECRET: loadSecret('JWT_SECRET', 'JWT_SECRET'),
  DB_PASSWORD: loadSecret('DB_PASSWORD', 'DB_PASSWORD'),
  SMTP_PASS: loadSecret('SMTP_PASS', 'SMTP_PASS')
};
```

**Déploiement Swarm** :
```bash
# Initialiser Swarm
docker swarm init

# Créer secrets
echo "votre_jwt_secret" | docker secret create jwt_secret -
echo "votre_db_password" | docker secret create db_password -
echo "votre_smtp_password" | docker secret create smtp_password -

# Déployer stack
docker stack deploy -c docker-compose.ovh.yml faildaily
```

---

#### Amélioration 2 : Monitoring Accès Secrets

```bash
# Sur OVH - Installer auditd
sudo apt update
sudo apt install auditd -y

# Monitorer accès .env.ovh
sudo auditctl -w /home/taaazzz/FailDaily/docker/.env.ovh -p ra -k secrets_access

# Monitorer service account Firebase
sudo auditctl -w /home/taaazzz/FailDaily/backend-api/faildaily-8efdd-firebase-adminsdk-fbsvc-09630fc557.json -p ra -k firebase_access

# Voir logs accès
sudo ausearch -k secrets_access | tail -20
sudo ausearch -k firebase_access | tail -20

# Configurer email alertes (optionnel)
# /etc/audit/auditd.conf
# action_mail_acct = root
# admin_space_left_action = email
```

---

#### Amélioration 3 : Script Rotation Automatique

```bash
# scripts/rotate-jwt-secret.sh
#!/bin/bash
set -e

ENV_FILE="/home/taaazzz/FailDaily/docker/.env.ovh"
BACKUP_DIR="/home/taaazzz/backups/secrets"
DATE=$(date +%Y%m%d_%H%M%S)

echo "🔄 Rotation JWT_SECRET - $DATE"

# Créer backup
mkdir -p $BACKUP_DIR
cp $ENV_FILE $BACKUP_DIR/.env.ovh.$DATE

# Générer nouveau secret
NEW_SECRET=$(node -e "console.log(require('crypto').randomBytes(64).toString('base64'))")

# Remplacer dans .env
OLD_SECRET=$(grep JWT_SECRET $ENV_FILE | cut -d= -f2)
sed -i "s|JWT_SECRET=$OLD_SECRET|JWT_SECRET=$NEW_SECRET|g" $ENV_FILE

# Redémarrer backend
cd /home/taaazzz/FailDaily/docker
docker-compose -f docker-compose.ovh.yml restart backend

# Vérifier service UP
sleep 5
curl -f http://localhost:3000/health || echo "❌ Backend ne répond pas"

echo "✅ JWT_SECRET rotated successfully"
echo "⚠️ Tous les utilisateurs devront se reconnecter"

# Notifier admin par email
echo "JWT_SECRET rotated on $DATE. Old secret backed up to $BACKUP_DIR/.env.ovh.$DATE" | \
  mail -s "FailDaily - JWT Secret Rotation" contact@taaazzz-prog.fr

# Cleanup vieux backups (garder 30 jours)
find $BACKUP_DIR -name ".env.ovh.*" -mtime +30 -delete
```

**Installation** :
```bash
# Upload script
scp scripts/rotate-jwt-secret.sh ubuntu@141.94.42.172:~/FailDaily/scripts/

# Rendre exécutable
ssh ubuntu@141.94.42.172 "chmod +x ~/FailDaily/scripts/rotate-jwt-secret.sh"

# Tester manuellement
ssh ubuntu@141.94.42.172 "~/FailDaily/scripts/rotate-jwt-secret.sh"

# Automatiser (cron tous les 6 mois)
ssh ubuntu@141.94.42.172 "crontab -e"
# Ajouter:
# 0 3 1 */6 * /home/taaazzz/FailDaily/scripts/rotate-jwt-secret.sh >> /var/log/jwt-rotation.log 2>&1
```

---

## 🚨 PROCÉDURES D'URGENCE

### Secret Compromis Détecté

```bash
# 1. ROTATION IMMÉDIATE
ssh ubuntu@141.94.42.172

# 2. Générer nouveaux secrets
node -e "console.log(require('crypto').randomBytes(64).toString('base64'))"

# 3. Mettre à jour .env.ovh
nano ~/FailDaily/docker/.env.ovh

# 4. Redémarrer services
cd ~/FailDaily/docker
docker-compose -f docker-compose.ovh.yml restart

# 5. Invalider tous tokens JWT (si JWT_SECRET compromis)
# Les utilisateurs devront se reconnecter

# 6. Auditer logs accès
sudo ausearch -k secrets_access -ts recent

# 7. Notifier utilisateurs (si nécessaire)
# Email: "Par mesure de sécurité, veuillez vous reconnecter"

# 8. Documenter incident
echo "$(date): JWT_SECRET compromis - Rotation effectuée - Cause: [détails]" >> ~/security-incidents.log
```

---

### Restaurer Secrets depuis Backup

```bash
# Option A : Depuis Bitwarden
# 1. Ouvrir Bitwarden Desktop
# 2. Copier secrets depuis coffre "FailDaily Production"
# 3. Éditer .env.ovh
nano ~/FailDaily/docker/.env.ovh

# Option B : Depuis fichier chiffré GPG
# Sur machine locale
gpg -d secrets-production.txt.gpg > secrets.txt
cat secrets.txt

# Copier secrets manuellement
# PUIS supprimer fichier déchiffré
shred -u secrets.txt

# Option C : Depuis backup .env
cd /home/taaazzz/backups/secrets
ls -lt .env.ovh.* | head -5  # Voir derniers backups
cp .env.ovh.20251128_030000 ~/FailDaily/docker/.env.ovh

# Redémarrer services
docker-compose -f docker-compose.ovh.yml restart
```

---

## 📊 CHECKLIST SÉCURITÉ SECRETS

### ✅ Protection de Base (FAIT)
- [x] `.gitignore` configuré (`.env`, `*password*`, `firebase-adminsdk-*`)
- [x] Aucun secret tracké dans git
- [ ] `chmod 600` sur tous fichiers secrets (À FAIRE)
- [ ] Backup secrets dans password manager (À FAIRE)
- [ ] Rotation JWT_SECRET (À FAIRE)
- [ ] Rotation SMTP_PASS (À FAIRE)

### ✅ Nettoyage
- [ ] Supprimer copies inutiles `.env.backup`, `.env.old`
- [ ] Supprimer scripts test avec secrets hardcodés
- [ ] Vérifier historique git (aucun secret dans commits passés)
- [ ] Vérifier images Docker (secrets non baked)

### ✅ Amélioration (Optionnel)
- [ ] Migration Docker Secrets (si passage Swarm)
- [ ] Monitoring accès secrets (auditd)
- [ ] Script rotation automatique (cron 6 mois)
- [ ] Alertes email en cas d'accès suspect

---

## 🔄 ROTATION PLANIFIÉE

### Calendrier Rotation Secrets

| Secret | Fréquence | Prochaine Rotation | Impact Utilisateurs |
|--------|-----------|-------------------|---------------------|
| JWT_SECRET | 6 mois | 28 mai 2026 | ⚠️ Déconnexion forcée |
| DB_PASSWORD | 1 an | 28 novembre 2026 | ❌ Aucun (transparent) |
| SMTP_PASS | 6 mois | 28 mai 2026 | ❌ Aucun |
| OPENAI_API_KEY | 1 an | 28 novembre 2026 | ❌ Aucun |
| Firebase Service Account | 1 an | 28 novembre 2026 | ❌ Aucun |

**Rappels automatiques** :
```bash
# Ajouter au calendrier
# FailDaily - Rotation JWT_SECRET : 28 mai 2026
# FailDaily - Rotation SMTP_PASS : 28 mai 2026
# FailDaily - Rotation DB_PASSWORD : 28 novembre 2026
```

---

## 🎯 QUAND PASSER À VAULT ?

### Critères Migration

**Reste avec `.env` SI** :
- ✅ Équipe 1-2 personnes
- ✅ 1 serveur unique
- ✅ Moins de 10 secrets
- ✅ Rotation manuelle acceptable (2x/an)
- ✅ Pas de compliance (SOC2, ISO27001)

**Migrer vers Vault QUAND** :
- ❌ Équipe 5+ développeurs
- ❌ Multi-environnements (dev/staging/prod sur serveurs séparés)
- ❌ 20+ secrets à gérer
- ❌ Besoin rotation automatique (quotidienne/hebdomadaire)
- ❌ Compliance requise (audits, certifications)
- ❌ Secrets dynamiques (credentials temporaires)
- ❌ Multi-régions (Europe, US, Asie)

### Alternatives Vault (Ordre de Complexité)

1. **Docker Secrets** (Swarm) - ⭐ Recommandé avant Vault
   - Intégré Docker
   - Gratuit
   - Complexité moyenne
   
2. **AWS Secrets Manager** / **GCP Secret Manager**
   - Cloud natif
   - $0.40/secret/mois
   - Rotation automatique
   - Nécessite migration cloud

3. **HashiCorp Vault**
   - Maximum sécurité
   - Audit complet
   - Complexe à maintenir
   - Serveur dédié requis

---

## 📞 CONTACTS & RESSOURCES

### Documentation
- Bitwarden : https://bitwarden.com/help/
- Docker Secrets : https://docs.docker.com/engine/swarm/secrets/
- GPG Chiffrement : https://gnupg.org/documentation/
- Auditd : https://linux.die.net/man/8/auditd

### Support FailDaily
- Email : contact@taaazzz-prog.fr
- Incidents sécurité : URGENT - Rotation immédiate
- Questions : Ce guide ou documentation Docker

---

## 📝 CHANGELOG

| Date | Action | Détails |
|------|--------|---------|
| 28/11/2025 | 📄 Guide créé | Version initiale - Pre-beta |
| - | - | Rotation JWT_SECRET prévue 28/05/2026 |
| - | - | Rotation DB_PASSWORD prévue 28/11/2026 |

---

## ⚠️ NOTES IMPORTANTES

1. **Ne JAMAIS committer** :
   - Fichiers `.env`
   - Fichiers `*password*`
   - Service accounts Firebase
   - Fichiers de backup non chiffrés

2. **Toujours utiliser** :
   - `chmod 600` sur fichiers secrets
   - Password manager (Bitwarden) pour backup
   - Chiffrement GPG si backup fichiers
   - Variables d'environnement (pas hardcodé dans code)

3. **En cas de doute** :
   - Rotation immédiate du secret
   - Audit logs accès
   - Documentation incident
   - Notification équipe

---

*Guide maintenu par : Équipe FailDaily*  
*Dernière mise à jour : 28 novembre 2025*  
*Prochaine revue : 28 février 2026*
