# 🐳 Docker Secrets - Guide Complet FailDaily

## Pourquoi Docker Secrets ?

**Avant** (avec .env) :
- ❌ Rotation = modifier `.env.ovh` + redémarrer manuellement
- ❌ Secrets en clair sur disque
- ❌ Risque de commit accidentel
- ❌ Difficile d'auditer les accès

**Après** (avec Docker Secrets) :
- ✅ Rotation en 1 commande automatisée
- ✅ Secrets chiffrés en RAM uniquement
- ✅ Impossible de commit (pas de fichiers)
- ✅ Logs d'accès natifs Docker

---

## 🚀 Migration vers Docker Secrets

### Étape 1 : Initialiser Docker Swarm

```bash
# Sur serveur OVH
ssh ubuntu@141.94.42.172

# Initialiser Swarm (une seule fois)
docker swarm init

# Vérifier
docker node ls
```

### Étape 2 : Créer les secrets initiaux

```bash
# JWT Secret (générer nouveau)
node -e "console.log(require('crypto').randomBytes(64).toString('base64'))" | \
  docker secret create jwt_secret -

# Database user password (utilisé par faildaily_user + alias logs_db_password via target)
echo "votre_mot_de_passe_db" | docker secret create db_password -

# MySQL root password (pour le service MySQL embarqué dans Swarm)
# Choisir un mot de passe root fort, distinct du mot de passe utilisateur
echo "votre_mysql_root_password" | docker secret create db_root_password -

# SMTP password
echo "votre_smtp_password_ovh" | docker secret create smtp_pass -

# OpenAI API Key
echo "votre_openai_api_key" | docker secret create openai_api_key -
```

> **Note** : `logs_db_password` n'est plus un secret Duck distinct.  
> Le stack monte `db_password` deux fois : comme `db_password` ET comme `logs_db_password`  
> (même valeur, même instance MySQL). Voir la section `secrets:` du backend dans `docker-stack.ovh-cloud.yml`.

**Vérifier les secrets créés** :
```bash
docker secret ls
# Attendu : jwt_secret, db_password, db_root_password, smtp_pass, openai_api_key, health_secret_v2
```

### Étape 3 : Adapter le code backend

Le code backend doit utiliser le nouveau loader :

```javascript
// backend-api/server.js (MODIFIER)
// Ancienne version :
// require('dotenv').config();
// const jwtSecret = process.env.JWT_SECRET;

// Nouvelle version :
const { loadAllSecrets } = require('./src/config/loadSecrets');
const secrets = loadAllSecrets();

// Utiliser partout :
// secrets.JWT_SECRET
// secrets.DB_PASSWORD
// secrets.SMTP_PASS
// etc.
```

### Étape 4 : Déployer avec Swarm

```bash
# Build des images
cd ~/FailDaily
docker build -t faildaily-backend:latest -f backend-api/Dockerfile backend-api/
docker build -t faildaily-frontend:latest -f frontend/Dockerfile frontend/

# Déployer la stack
docker stack deploy -c docker/docker-compose.swarm.yml faildaily

# Vérifier le déploiement
docker stack ps faildaily
docker service ls
```

---

## 🔄 Rotation de Secrets

### Méthode automatique (recommandée)

```bash
# Rendre le script exécutable
chmod +x ~/FailDaily/scripts/rotate-secrets.sh

# Lancer la rotation
./scripts/rotate-secrets.sh

# Menu interactif :
# 1) JWT_SECRET
# 2) DB_PASSWORD
# 3) SMTP_PASS
# 4) OPENAI_API_KEY
# 5) TOUS les secrets
```

### Méthode manuelle

```bash
# Exemple : Rotation JWT_SECRET

# 1. Générer nouveau secret
NEW_JWT=$(node -e "console.log(require('crypto').randomBytes(64).toString('base64'))")

# 2. Créer nouveau secret avec version
echo "$NEW_JWT" | docker secret create jwt_secret_v20251128 -

# 3. Mettre à jour le service
docker service update \
  --secret-rm jwt_secret \
  --secret-add source=jwt_secret_v20251128,target=jwt_secret \
  faildaily_backend

# 4. Vérifier que le service redémarre
docker service ps faildaily_backend

# 5. Tester l'application
curl -I https://faildaily.com/api/health

# 6. Supprimer l'ancien secret (après 24h)
docker secret rm jwt_secret
```

---

## 📋 Avantages vs Inconvénients

### ✅ Avantages

1. **Rotation facile** : 1 commande au lieu de modifier plusieurs fichiers
2. **Sécurité** : Secrets en RAM, jamais sur disque
3. **Audit** : Logs Docker natifs des accès secrets
4. **Versioning** : Garder anciennes versions pour rollback
5. **Zero-downtime** : Rolling update automatique

### ⚠️ Inconvénients

1. **Docker Swarm obligatoire** : Pas compatible docker-compose simple
2. **Courbe d'apprentissage** : Plus complexe que `.env`
3. **Serveur unique** : Swarm un peu overkill pour 1 serveur

---

## 🔍 Commandes utiles

### Lister les secrets
```bash
docker secret ls
```

### Inspecter un secret (juste metadata, pas valeur)
```bash
docker secret inspect jwt_secret
```

### Voir quels services utilisent un secret
```bash
docker service ps faildaily_backend --format "{{.ID}}: {{.DesiredState}}"
```

### Logs du service backend
```bash
docker service logs -f faildaily_backend
```

### Rollback si problème
```bash
docker service rollback faildaily_backend
```

---

## 🎯 Calendrier de rotation recommandé

| Secret | Fréquence | Commande |
|--------|-----------|----------|
| JWT_SECRET | 6 mois | `./rotate-secrets.sh` → choix 1 |
| DB_PASSWORD | 1 an | `./rotate-secrets.sh` → choix 2 |
| SMTP_PASS | 6 mois | `./rotate-secrets.sh` → choix 3 |
| OPENAI_API_KEY | 1 an | `./rotate-secrets.sh` → choix 4 |

**Automatisation avec cron** :
```bash
# Ajouter au crontab
crontab -e

# Rotation JWT tous les 6 mois (1er janvier et 1er juillet à 3h)
0 3 1 1,7 * /home/taaazzz/FailDaily/scripts/rotate-secrets.sh <<< "1"
```

---

## 🚨 Procédure d'urgence

### Secret compromis détecté

```bash
# 1. Rotation immédiate
./scripts/rotate-secrets.sh

# 2. Vérifier logs d'accès
docker service logs faildaily_backend | grep -i "secret"

# 3. Invalider tous les tokens JWT (si JWT compromis)
# Les utilisateurs devront se reconnecter

# 4. Documenter l'incident
echo "$(date): Secret compromis - Rotation effectuée" >> ~/security-incidents.log
```

---

## 📊 Comparaison systèmes

| Critère | .env files | Docker Secrets | HashiCorp Vault |
|---------|-----------|----------------|-----------------|
| Complexité | ⭐ Simple | ⭐⭐ Moyenne | ⭐⭐⭐⭐ Complexe |
| Rotation | Manuel | Semi-auto | Automatique |
| Sécurité | ⚠️ Disque | ✅ RAM | ✅ Chiffré |
| Audit | ❌ Aucun | ✅ Logs Docker | ✅ Logs complets |
| Équipe 1-2 | ✅ OK | ✅ Idéal | ❌ Overkill |
| Multi-serveurs | ❌ | ✅ Swarm | ✅ Natif |

**Recommandation FailDaily** : **Docker Secrets** = meilleur compromis complexité/sécurité

---

## 🔧 Maintenance

### Backup des secrets (Bitwarden)

```bash
# Après chaque rotation, sauvegarder dans Bitwarden
# Coffre: "FailDaily Production Secrets"

# Entrée exemple :
# Titre: JWT_SECRET (version 2025-11-28)
# Mot de passe: [valeur générée]
# Notes: Rotaté le 2025-11-28, utilisé par backend
```

### Nettoyage anciens secrets

```bash
# Lister secrets avec versions
docker secret ls | grep "_v2024"

# Supprimer secrets > 30 jours
# (À faire manuellement après validation)
docker secret rm jwt_secret_v20241128
```

---

*Guide maintenu par : Équipe FailDaily*  
*Dernière mise à jour : 28 novembre 2025*
