358 lines
10 KiB
Markdown
358 lines
10 KiB
Markdown
|
|
# Configuration Backend Veza - Guide de Sécurité
|
||
|
|
|
||
|
|
**Version**: 1.0
|
||
|
|
**Date**: 2025-01-XX
|
||
|
|
**Priorité**: P0 - Sécurité
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 📋 Vue d'ensemble
|
||
|
|
|
||
|
|
Ce document décrit la configuration du backend Go de Veza, avec un focus particulier sur la **sécurisation** selon l'environnement (development, test, production).
|
||
|
|
|
||
|
|
### Changements de sécurité (P0-SECURITY)
|
||
|
|
|
||
|
|
- ✅ **CORS sécurisé**: Plus de wildcard `"*"` par défaut en production
|
||
|
|
- ✅ **Validation stricte**: Production refuse de démarrer si configuration critique manquante
|
||
|
|
- ✅ **Profils d'environnement**: Comportements différents selon `APP_ENV`
|
||
|
|
- ✅ **Defaults sécurisés**: Valeurs par défaut adaptées à chaque environnement
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 🔧 Variables d'environnement
|
||
|
|
|
||
|
|
### Variables requises (tous environnements)
|
||
|
|
|
||
|
|
| Variable | Description | Exemple | Validation |
|
||
|
|
|----------|-------------|---------|------------|
|
||
|
|
| `JWT_SECRET` | Secret pour signer les tokens JWT | `your-super-secret-jwt-key-min-32-chars` | **REQUIS**, min 32 caractères |
|
||
|
|
| `DATABASE_URL` | URL de connexion PostgreSQL | `postgresql://user:pass@localhost:5432/veza_db` | **REQUIS**, format valide |
|
||
|
|
|
||
|
|
### Variables optionnelles avec defaults
|
||
|
|
|
||
|
|
| Variable | Description | Default | Notes |
|
||
|
|
|----------|-------------|---------|-------|
|
||
|
|
| `APP_PORT` | Port HTTP du serveur | `8080` | 1-65535 |
|
||
|
|
| `REDIS_URL` | URL de connexion Redis | `redis://localhost:6379` | Format `redis://` ou `rediss://` |
|
||
|
|
| `LOG_LEVEL` | Niveau de log | `INFO` | `DEBUG`, `INFO`, `WARN`, `ERROR` |
|
||
|
|
| `UPLOAD_DIR` | Répertoire d'upload | `uploads` | Chemin relatif ou absolu |
|
||
|
|
| `STREAM_SERVER_URL` | URL du serveur de streaming | `http://localhost:8082` | URL complète |
|
||
|
|
|
||
|
|
### Variables spécifiques CORS (P0-SECURITY)
|
||
|
|
|
||
|
|
| Variable | Description | Default (dev) | Default (prod) | Validation |
|
||
|
|
|----------|-------------|---------------|----------------|------------|
|
||
|
|
| `CORS_ALLOWED_ORIGINS` | Origines CORS autorisées (séparées par virgules) | `http://localhost:3000,http://127.0.0.1:3000,...` | **REQUIS** | **Non vide en prod**, **pas de `"*"` en prod** |
|
||
|
|
|
||
|
|
**Format**: Liste séparée par virgules
|
||
|
|
```bash
|
||
|
|
CORS_ALLOWED_ORIGINS=https://app.veza.com,https://www.veza.com,https://staging.veza.com
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 🌍 Environnements
|
||
|
|
|
||
|
|
### Détection automatique
|
||
|
|
|
||
|
|
L'environnement est détecté automatiquement selon cette priorité :
|
||
|
|
|
||
|
|
1. `APP_ENV` (priorité maximale)
|
||
|
|
2. `NODE_ENV` (compatibilité)
|
||
|
|
3. `GO_ENV` (compatibilité Go)
|
||
|
|
4. Hostname (si contient "prod" → production)
|
||
|
|
5. **Fallback**: `development`
|
||
|
|
|
||
|
|
### Environnements supportés
|
||
|
|
|
||
|
|
- `development`: Développement local
|
||
|
|
- `test`: Tests automatisés
|
||
|
|
- `staging`: Environnement de pré-production
|
||
|
|
- `production`: Production
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 🔒 Comportements par environnement
|
||
|
|
|
||
|
|
### Development (`APP_ENV=development`)
|
||
|
|
|
||
|
|
**Caractéristiques**:
|
||
|
|
- ✅ CORS permissif par défaut (localhost uniquement)
|
||
|
|
- ✅ Logs verbeux (DEBUG autorisé)
|
||
|
|
- ✅ Valeurs par défaut acceptées
|
||
|
|
- ⚠️ Warning si CORS contient `"*"` (mais démarrage autorisé)
|
||
|
|
|
||
|
|
**Defaults CORS** (si `CORS_ALLOWED_ORIGINS` non défini):
|
||
|
|
```
|
||
|
|
http://localhost:3000
|
||
|
|
http://127.0.0.1:3000
|
||
|
|
http://localhost:5173
|
||
|
|
http://127.0.0.1:5173
|
||
|
|
```
|
||
|
|
|
||
|
|
**Exemple de configuration minimale**:
|
||
|
|
```bash
|
||
|
|
APP_ENV=development
|
||
|
|
JWT_SECRET=dev-secret-key-minimum-32-characters-long
|
||
|
|
DATABASE_URL=postgresql://veza:password@localhost:5432/veza_db
|
||
|
|
# CORS_ALLOWED_ORIGINS optionnel - defaults locaux utilisés
|
||
|
|
```
|
||
|
|
|
||
|
|
### Test (`APP_ENV=test`)
|
||
|
|
|
||
|
|
**Caractéristiques**:
|
||
|
|
- ✅ CORS vide par défaut (peut être configuré explicitement)
|
||
|
|
- ✅ Validation adaptée aux tests
|
||
|
|
- ✅ Pas de side-effects externes (SMTP, etc.)
|
||
|
|
|
||
|
|
**Exemple de configuration**:
|
||
|
|
```bash
|
||
|
|
APP_ENV=test
|
||
|
|
JWT_SECRET=test-secret-key-minimum-32-characters-long
|
||
|
|
DATABASE_URL=postgresql://veza:password@localhost:5432/veza_test
|
||
|
|
# CORS_ALLOWED_ORIGINS optionnel - liste vide par défaut
|
||
|
|
```
|
||
|
|
|
||
|
|
### Production (`APP_ENV=production`)
|
||
|
|
|
||
|
|
**Caractéristiques**:
|
||
|
|
- 🔴 **CORS_ALLOWED_ORIGINS REQUIS** et non vide
|
||
|
|
- 🔴 **Wildcard `"*"` INTERDIT** en production
|
||
|
|
- 🔴 **LOG_LEVEL=DEBUG INTERDIT** en production
|
||
|
|
- 🔴 **Erreur fatale** si configuration critique manquante
|
||
|
|
|
||
|
|
**Validation stricte**:
|
||
|
|
- Si `CORS_ALLOWED_ORIGINS` est vide → **Erreur fatale, serveur ne démarre pas**
|
||
|
|
- Si `CORS_ALLOWED_ORIGINS` contient `"*"` → **Erreur fatale, serveur ne démarre pas**
|
||
|
|
- Si `LOG_LEVEL=DEBUG` → **Erreur fatale, serveur ne démarre pas**
|
||
|
|
|
||
|
|
**Exemple de configuration requise**:
|
||
|
|
```bash
|
||
|
|
APP_ENV=production
|
||
|
|
JWT_SECRET=production-super-secret-key-minimum-32-characters-long
|
||
|
|
DATABASE_URL=postgresql://veza:secure-password@db.veza.com:5432/veza_prod
|
||
|
|
CORS_ALLOWED_ORIGINS=https://app.veza.com,https://www.veza.com
|
||
|
|
LOG_LEVEL=INFO
|
||
|
|
REDIS_URL=rediss://redis.veza.com:6379
|
||
|
|
```
|
||
|
|
|
||
|
|
**❌ Configuration INVALIDE en production**:
|
||
|
|
```bash
|
||
|
|
# ❌ CORS_ALLOWED_ORIGINS manquant
|
||
|
|
APP_ENV=production
|
||
|
|
JWT_SECRET=...
|
||
|
|
DATABASE_URL=...
|
||
|
|
# → Erreur: "CORS_ALLOWED_ORIGINS is required in production"
|
||
|
|
|
||
|
|
# ❌ Wildcard dans CORS
|
||
|
|
CORS_ALLOWED_ORIGINS=*
|
||
|
|
# → Erreur: "CORS wildcard '*' is not allowed in production"
|
||
|
|
|
||
|
|
# ❌ DEBUG en production
|
||
|
|
LOG_LEVEL=DEBUG
|
||
|
|
# → Erreur: "LOG_LEVEL=DEBUG is not allowed in production"
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 🚀 Démarrage du serveur
|
||
|
|
|
||
|
|
### Development
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Option 1: Via fichier .env
|
||
|
|
echo "APP_ENV=development" > .env
|
||
|
|
echo "JWT_SECRET=dev-secret-key-minimum-32-characters-long" >> .env
|
||
|
|
echo "DATABASE_URL=postgresql://veza:password@localhost:5432/veza_db" >> .env
|
||
|
|
go run cmd/api/main.go
|
||
|
|
|
||
|
|
# Option 2: Variables d'environnement
|
||
|
|
export APP_ENV=development
|
||
|
|
export JWT_SECRET=dev-secret-key-minimum-32-characters-long
|
||
|
|
export DATABASE_URL=postgresql://veza:password@localhost:5432/veza_db
|
||
|
|
go run cmd/api/main.go
|
||
|
|
```
|
||
|
|
|
||
|
|
### Production
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Configuration requise
|
||
|
|
export APP_ENV=production
|
||
|
|
export JWT_SECRET=production-super-secret-key-minimum-32-characters-long
|
||
|
|
export DATABASE_URL=postgresql://veza:secure-password@db.veza.com:5432/veza_prod
|
||
|
|
export CORS_ALLOWED_ORIGINS=https://app.veza.com,https://www.veza.com
|
||
|
|
export LOG_LEVEL=INFO
|
||
|
|
export REDIS_URL=rediss://redis.veza.com:6379
|
||
|
|
|
||
|
|
# Démarrage
|
||
|
|
./veza-backend-api
|
||
|
|
```
|
||
|
|
|
||
|
|
**Si une variable critique manque en production**, le serveur **refusera de démarrer** avec un message d'erreur explicite.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 🔍 Validation de la configuration
|
||
|
|
|
||
|
|
### Validation automatique
|
||
|
|
|
||
|
|
La configuration est validée automatiquement au démarrage via `ValidateForEnvironment()` :
|
||
|
|
|
||
|
|
1. **Validation de base** (tous environnements):
|
||
|
|
- Port valide (1-65535)
|
||
|
|
- JWT secret ≥ 32 caractères
|
||
|
|
- DatabaseURL et RedisURL format valide
|
||
|
|
- LogLevel dans la liste autorisée
|
||
|
|
|
||
|
|
2. **Validation spécifique production**:
|
||
|
|
- `CORS_ALLOWED_ORIGINS` non vide
|
||
|
|
- Pas de wildcard `"*"` dans CORS
|
||
|
|
- `LOG_LEVEL` ≠ `DEBUG`
|
||
|
|
|
||
|
|
### Messages d'erreur
|
||
|
|
|
||
|
|
**Production - CORS manquant**:
|
||
|
|
```
|
||
|
|
ERROR: Configuration validation failed
|
||
|
|
Error: CORS_ALLOWED_ORIGINS is required in production environment and must not be empty
|
||
|
|
```
|
||
|
|
|
||
|
|
**Production - Wildcard détecté**:
|
||
|
|
```
|
||
|
|
ERROR: Configuration validation failed
|
||
|
|
Error: CORS wildcard '*' is not allowed in production environment. Please specify explicit origins in CORS_ALLOWED_ORIGINS
|
||
|
|
```
|
||
|
|
|
||
|
|
**Production - DEBUG interdit**:
|
||
|
|
```
|
||
|
|
ERROR: Configuration validation failed
|
||
|
|
Error: LOG_LEVEL=DEBUG is not allowed in production environment for security reasons
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 📝 Fichiers de configuration
|
||
|
|
|
||
|
|
### Ordre de chargement
|
||
|
|
|
||
|
|
1. Variables d'environnement système (priorité maximale)
|
||
|
|
2. `.env.{APP_ENV}` (ex: `.env.development`, `.env.production`)
|
||
|
|
3. `.env` (fallback)
|
||
|
|
4. Valeurs par défaut (selon environnement)
|
||
|
|
|
||
|
|
### Exemple de fichiers
|
||
|
|
|
||
|
|
**`.env.development`**:
|
||
|
|
```bash
|
||
|
|
APP_ENV=development
|
||
|
|
JWT_SECRET=dev-secret-key-minimum-32-characters-long
|
||
|
|
DATABASE_URL=postgresql://veza:password@localhost:5432/veza_db
|
||
|
|
REDIS_URL=redis://localhost:6379
|
||
|
|
LOG_LEVEL=DEBUG
|
||
|
|
# CORS_ALLOWED_ORIGINS optionnel - defaults locaux utilisés
|
||
|
|
```
|
||
|
|
|
||
|
|
**`.env.production`**:
|
||
|
|
```bash
|
||
|
|
APP_ENV=production
|
||
|
|
JWT_SECRET=production-super-secret-key-minimum-32-characters-long
|
||
|
|
DATABASE_URL=postgresql://veza:secure-password@db.veza.com:5432/veza_prod
|
||
|
|
CORS_ALLOWED_ORIGINS=https://app.veza.com,https://www.veza.com
|
||
|
|
LOG_LEVEL=INFO
|
||
|
|
REDIS_URL=rediss://redis.veza.com:6379
|
||
|
|
```
|
||
|
|
|
||
|
|
**⚠️ IMPORTANT**: Ne jamais commiter les fichiers `.env.production` avec des secrets réels dans le repository.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 🧪 Tests
|
||
|
|
|
||
|
|
### Exécuter les tests de configuration
|
||
|
|
|
||
|
|
```bash
|
||
|
|
cd veza-backend-api
|
||
|
|
go test ./internal/config/... -v
|
||
|
|
```
|
||
|
|
|
||
|
|
### Tests de sécurité (P0-SECURITY)
|
||
|
|
|
||
|
|
Les tests suivants valident la sécurisation :
|
||
|
|
|
||
|
|
- `TestLoadConfig_DevDefaults`: Vérifie les defaults dev
|
||
|
|
- `TestLoadConfig_ProdMissingCritical`: Vérifie que prod refuse si CORS manquant
|
||
|
|
- `TestLoadConfig_ProdWildcard`: Vérifie que prod refuse le wildcard
|
||
|
|
- `TestLoadConfig_ProdValid`: Vérifie qu'une config prod valide passe
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 🔐 Bonnes pratiques de sécurité
|
||
|
|
|
||
|
|
### ✅ À FAIRE
|
||
|
|
|
||
|
|
1. **Production**: Toujours définir `CORS_ALLOWED_ORIGINS` explicitement
|
||
|
|
2. **Production**: Utiliser `LOG_LEVEL=INFO` ou supérieur
|
||
|
|
3. **Secrets**: Stocker les secrets dans des variables d'environnement, jamais dans le code
|
||
|
|
4. **Validation**: Vérifier la configuration avant chaque déploiement
|
||
|
|
5. **Documentation**: Documenter les variables d'environnement requises
|
||
|
|
|
||
|
|
### ❌ À ÉVITER
|
||
|
|
|
||
|
|
1. **Production**: Ne jamais utiliser `CORS_ALLOWED_ORIGINS=*`
|
||
|
|
2. **Production**: Ne jamais utiliser `LOG_LEVEL=DEBUG`
|
||
|
|
3. **Secrets**: Ne jamais hardcoder des secrets dans le code
|
||
|
|
4. **Git**: Ne jamais commiter des fichiers `.env` avec des secrets
|
||
|
|
5. **Defaults**: Ne pas compter sur les valeurs par défaut en production
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 🐛 Dépannage
|
||
|
|
|
||
|
|
### Le serveur refuse de démarrer en production
|
||
|
|
|
||
|
|
**Erreur**: `CORS_ALLOWED_ORIGINS is required in production`
|
||
|
|
|
||
|
|
**Solution**: Définir `CORS_ALLOWED_ORIGINS` avec une liste explicite d'origines :
|
||
|
|
```bash
|
||
|
|
export CORS_ALLOWED_ORIGINS=https://app.veza.com,https://www.veza.com
|
||
|
|
```
|
||
|
|
|
||
|
|
### Erreur de validation CORS wildcard
|
||
|
|
|
||
|
|
**Erreur**: `CORS wildcard '*' is not allowed in production`
|
||
|
|
|
||
|
|
**Solution**: Remplacer `"*"` par une liste explicite d'origines autorisées.
|
||
|
|
|
||
|
|
### Erreur LOG_LEVEL=DEBUG en production
|
||
|
|
|
||
|
|
**Erreur**: `LOG_LEVEL=DEBUG is not allowed in production`
|
||
|
|
|
||
|
|
**Solution**: Utiliser `LOG_LEVEL=INFO` ou supérieur :
|
||
|
|
```bash
|
||
|
|
export LOG_LEVEL=INFO
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 📚 Références
|
||
|
|
|
||
|
|
- [Audit de sécurité](./AUDIT_CONFIG.md) - Rapport d'audit détaillé
|
||
|
|
- [Middleware CORS](../internal/middleware/cors.go) - Implémentation CORS
|
||
|
|
- [Validation de config](../internal/config/validator.go) - Validateur de configuration
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 📞 Support
|
||
|
|
|
||
|
|
Pour toute question sur la configuration, consulter :
|
||
|
|
- Le code source: `internal/config/config.go`
|
||
|
|
- Les tests: `internal/config/config_test.go`
|
||
|
|
- Ce document: `docs/BACKEND_CONFIG.md`
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
**Dernière mise à jour**: 2025-01-XX
|
||
|
|
**Auteur**: Équipe Veza
|
||
|
|
**Priorité**: P0 - Sécurité
|
||
|
|
|