veza/docs/ENV_VARIABLES.md
senke d03232c85c
Some checks failed
Veza CI / Backend (Go) (push) Failing after 0s
Veza CI / Frontend (Web) (push) Failing after 0s
Veza CI / Rust (Stream Server) (push) Failing after 0s
Security Scan / Secret Scanning (gitleaks) (push) Failing after 0s
Veza CI / Notify on failure (push) Failing after 0s
feat(storage): add track storage_backend column + config prep (v1.0.8 P0)
Phase 0 of the MinIO upload migration (FUNCTIONAL_AUDIT §4 item 2).
Schema + config only — Phase 1 will wire TrackService.UploadTrack()
to actually route writes to S3 when the flag is flipped.

Schema (migration 985):
- tracks.storage_backend VARCHAR(16) NOT NULL DEFAULT 'local'
  CHECK in ('local', 's3')
- tracks.storage_key VARCHAR(512) NULL (S3 object key when backend=s3)
- Partial index on storage_backend = 's3' (migration progress queries)
- Rollback drops both columns + index; safe only while all rows are
  still 'local' (guard query in the rollback comment)

Go model (internal/models/track.go):
- StorageBackend string (default 'local', not null)
- StorageKey *string (nullable)
- Both tagged json:"-" — internal plumbing, never exposed publicly

Config (internal/config/config.go):
- New field Config.TrackStorageBackend
- Read from TRACK_STORAGE_BACKEND env var (default 'local')
- Production validation rule #11 (ValidateForEnvironment):
  - Must be 'local' or 's3' (reject typos like 'S3' or 'minio')
  - If 's3', requires AWS_S3_ENABLED=true (fail fast, do not boot with
    TrackStorageBackend=s3 while S3StorageService is nil)
- Dev/staging warns and falls back to 'local' instead of fail — keeps
  iteration fast while still flagging misconfig.

Docs:
- docs/ENV_VARIABLES.md §13 restructured as "HLS + track storage backend"
  with a migration playbook (local → s3 → migrate-storage CLI)
- docs/ENV_VARIABLES.md §28 validation rules: +2 entries for new rules
- docs/ENV_VARIABLES.md §29 drift findings: TRACK_STORAGE_BACKEND added
  to "missing from template" list before it was fixed
- veza-backend-api/.env.template: TRACK_STORAGE_BACKEND=local with
  comment pointing at Phase 1/2/3 plans

No behavior change yet — TrackService.UploadTrack() still hardcodes the
local path via copyFileAsync(). Phase 1 wires it.

Refs:
- AUDIT_REPORT.md §9 item (deferrals v1.0.8)
- FUNCTIONAL_AUDIT.md §4 item 2 "Stockage local disque only"
- /home/senke/.claude/plans/audit-fonctionnel-wild-hickey.md Item 3

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 19:54:28 +02:00

29 KiB
Raw Blame History

Variables d'environnement Veza

Référence canonique de toutes les variables lues par la plateforme Veza.
Sync effectué le 2026-04-23 — survey direct du code (os.Getenv en Go, std::env::var en Rust, import.meta.env côté React).
SSOT Go : veza-backend-api/internal/config/config.go lignes 276465.
Templates : veza-backend-api/.env.template, veza-stream-server/.env.example, docker-compose.env.example.
Documents liés : ENV_CONFIG.md (setup dev veza.fr), ENVIRONMENT_REAL_SETUP.md (walkthrough).
Règle : quand tu ajoutes une variable dans le code, mets à jour ce fichier + .env.template dans le même commit. Référence audit : AUDIT_REPORT.md §9 item #15.


Démarrage rapide — 5 variables minimum

Pour booter un backend dev (make dev) :

Variable Exemple Pourquoi
DATABASE_URL postgres://veza:password@veza.fr:15432/veza?sslmode=disable Postgres — boot échoue sans.
REDIS_URL redis://veza.fr:16379 CSRF + rate-limit + cache. Pas de fallback silencieux en prod.
JWT_SECRET ≥32 caractères aléatoires HS256 fallback. Préférer JWT_PRIVATE_KEY_PATH + JWT_PUBLIC_KEY_PATH en prod.
CORS_ALLOWED_ORIGINS http://veza.fr:5173,http://veza.fr:3000 Pas de wildcard en prod.
FRONTEND_URL http://veza.fr:5173 OAuth redirects + liens emails.

Tout le reste a un défaut raisonnable ou est opt-in.


Table des matières

  1. Core / environnement
  2. Base de données
  3. Redis
  4. JWT / authentification
  5. OAuth providers
  6. CORS / cookies
  7. Rate limiting
  8. SMTP / email
  9. Hyperswitch / paiements
  10. Stripe Connect / payouts créateurs
  11. RabbitMQ / event bus
  12. Stockage S3 / MinIO
  13. HLS streaming
  14. Stream server (backend ↔ stream)
  15. Elasticsearch
  16. ClamAV / antivirus
  17. Sentry / tracking d'erreurs
  18. Logging
  19. Monitoring / metrics
  20. Frontend (Vite)
  21. Feature flags
  22. Politique de mot de passe
  23. Build / version info
  24. RTMP / Web Push / divers
  25. Stream server (Rust) — schéma propre
  26. Security headers (rappel)
  27. Variables dépréciées / legacy
  28. Règles de validation production
  29. Drift template ↔ code
  30. Checklist de démarrage

Légende : variable en gras = critique en production (validée au boot).


1. Core / environnement

Variable Défaut Lu à Rôle
APP_ENV development config.go:276 development / staging / production. Conditionne les validations et beaucoup de défauts.
APP_DOMAIN veza.fr config.go:299 Single source of truth pour les URLs dérivées en dev. APP_DOMAIN=example.com + /etc/hosts suffit.
APP_PORT 8080 config.go:309 Port HTTP.
LOG_LEVEL INFO config.go:296 DEBUG / INFO / WARN / ERROR. DEBUG refusé en prod (validation.go:876).
GO_ENV, NODE_ENV legacy Alias historiques de APP_ENV. Pas canoniques.

2. Base de données

Hard requirement : DATABASE_URL. Pool par défaut tuné pour un dev mono-pod ; bump pour multi-replica.

Variable Défaut Lu à Rôle
DATABASE_URL config.go:320 DSN Postgres. Boot échoue sans.
DATABASE_READ_URL (vide) config.go:342 DSN read-replica optionnel. Fallback sur DATABASE_URL.
DB_MAX_OPEN_CONNS 50 database/db_init.go Pool : connexions concurrentes.
DB_MAX_IDLE_CONNS 12 database/db_init.go Pool : idle.
DB_MAX_IDLE_TIME 5m database/db_init.go Timeout idle.
DB_MAX_LIFETIME 10m database/db_init.go Lifetime max avant recycle.
DB_READ_MAX_OPEN_CONNS 25 database/db_init.go Pool read-replica : max open.
DB_READ_MAX_IDLE_CONNS 6 database/db_init.go Pool read-replica : max idle.
DB_MAX_RETRIES 5 config.go:380 Retries sur échec connexion.
DB_RETRY_INTERVAL 5s config.go:381 Délai entre retries.

Drift : le template utilise DATABASE_MAX_OPEN_CONNS / DATABASE_MAX_IDLE_CONNS / DATABASE_CONN_MAX_LIFETIMEces noms ne sont pas lus par le code. Utiliser DB_MAX_*. Template corrigé en v1.1.0.

3. Redis

Variable Défaut Lu à Rôle
REDIS_URL redis://veza.fr:6379 config.go:338 URL complète. Doit être explicite en prod (validation.go:916) — pas de fallback qui casserait multi-pod.
REDIS_ENABLE true config.go:339 Désactiver Redis désactive CSRF, rate-limit, cache.

REDIS_ADDR, REDIS_PASSWORD, REDIS_DB apparaissent encore dans le template mais ne sont plus lus — utiliser REDIS_URL. Voir §27.

4. JWT / authentification

RS256 préféré (prod), HS256 fallback (dev). Clés générées par scripts/generate-jwt-keys.sh.

Variable Défaut Lu à Rôle
JWT_PRIVATE_KEY_PATH (vide) config.go:316 Chemin clé privée RSA (PEM). Préféré en prod.
JWT_PUBLIC_KEY_PATH (vide) config.go:317 Chemin clé publique RSA.
JWT_SECRET config.go:318 Fallback HS256. ≥32 chars. Requis si pas de RS256.
JWT_ISSUER veza-api config.go:335 Claim iss.
JWT_AUDIENCE veza-platform config.go:336 Claim aud.
CHAT_JWT_SECRET fallback sur JWT_SECRET config.go:337 Tokens chat WebSocket. Doit différer de JWT_SECRET en prod (validation.go:891).

JWT_ACCESS_TOKEN_DURATION et JWT_REFRESH_TOKEN_DURATION dans le template ne sont pas lues — durées hardcodées (access 5min, refresh 7j).

Génération RS256 :

scripts/generate-jwt-keys.sh
# ou manuellement :
openssl genrsa -out jwt-private.pem 2048
openssl rsa -in jwt-private.pem -pubout -out jwt-public.pem

5. OAuth providers

Opt-in par provider : définir CLIENT_ID + CLIENT_SECRET pour activer.

Variable Rôle
OAUTH_ENCRYPTION_KEY Clé AES-256 (≥32 bytes) pour chiffrer les refresh tokens OAuth au repos. Requis en prod (validation.go:896).
OAUTH_ALLOWED_REDIRECT_DOMAINS Whitelist des domaines redirect URI. Défauts dérivés de CORS_ALLOWED_ORIGINS.
OAUTH_GOOGLE_CLIENT_ID / _SECRET Google OAuth.
OAUTH_GITHUB_CLIENT_ID / _SECRET GitHub OAuth.
OAUTH_DISCORD_CLIENT_ID / _SECRET Discord OAuth.
OAUTH_SPOTIFY_CLIENT_ID / _SECRET Spotify OAuth.

Tout lu dans veza-backend-api/internal/config/services_init.go.

6. CORS / cookies

Variable Défaut Lu à Rôle
CORS_ALLOWED_ORIGINS env-aware config.go:302 Liste CSV. Pas de wildcards en prod (validation.go:869).
COOKIE_SECURE false (dev), true (prod) middleware/cors Cookies HTTPS-only.
COOKIE_SAME_SITE lax config.go:401 strict / lax / none.
COOKIE_DOMAIN (vide) config.go:402 Vide = domaine courant.
COOKIE_HTTP_ONLY true config.go:403 Empêche accès JS.
COOKIE_PATH / config.go:404 Path cookie.

7. Rate limiting

Variable Défaut Lu à Rôle
RATE_LIMIT_LIMIT env-aware config.go:305 Requêtes par fenêtre.
RATE_LIMIT_WINDOW 60 (secondes) config.go:306 Taille fenêtre.
RATE_LIMIT_IP_PER_HOUR 100 prod / 5000 dev middleware/rate_limit.go Plafond par IP (non-auth).
RATE_LIMIT_USER_PER_HOUR 1000 prod / 2000 dev middleware/rate_limit.go Plafond par user (auth).
AUTH_RATE_LIMIT_LOGIN_ATTEMPTS 5 prod / 100 test config.go:374 Seuil lockout login échoué.
AUTH_RATE_LIMIT_LOGIN_WINDOW 1 prod / 60 test (minutes) config.go:375 Fenêtre lockout.
ACCOUNT_LOCKOUT_EXEMPT_EMAILS (vide) config.go:376 CSV d'emails exemptés.
USER_RATE_LIMIT_BURST 100 middlewares_init.go:54 Burst tokens par user (BE-SVC-002).
USER_RATE_LIMIT_PER_MINUTE 1000 middlewares_init.go:54 RPM par user.
DISABLE_RATE_LIMIT_FOR_TESTS middleware Bypass E2E (test only).

8. SMTP / email

Variable Défaut Lu à Rôle
SMTP_HOST localhost mailer/sender.go:120 MailHog par défaut en dev.
SMTP_PORT 1025 mailer/sender.go:121 MailHog.
SMTP_USERNAME (vide) mailer/sender.go:122 Nom canonique (v1.0.6).
SMTP_PASSWORD (vide) mailer/sender.go:123
SMTP_FROM no-reply@veza.local mailer/sender.go:124 Adresse expéditeur.
SMTP_FROM_NAME Veza (dev) mailer/sender.go:125 Nom affiché.
EMAIL_TEMPLATE_DIR email handlers Dossier MJML/HTML templates.

SMTP_USER, FROM_EMAIL, FROM_NAME fonctionnent encore mais loggent un warning deprecation — voir §27.

9. Hyperswitch / paiements

Désactivé par défaut. Si activé, plusieurs clés deviennent obligatoires.

Variable Défaut Lu à Rôle
HYPERSWITCH_ENABLED false config.go:407 Master switch. Fail-closed en prod (validation.go:908) — boot prod refuse de démarrer si activé sans clés live.
HYPERSWITCH_LIVE_MODE false config.go:408 Clés live vs test.
HYPERSWITCH_URL http://localhost:18081 config.go:409 Endpoint router.
HYPERSWITCH_API_KEY (vide) config.go:410 Requis si HYPERSWITCH_ENABLED=true.
HYPERSWITCH_WEBHOOK_SECRET (vide) config.go:411 Requis en prod pour vérification signature.
CHECKOUT_SUCCESS_URL /purchases config.go:412 Redirect après paiement.
HYPERSWITCH_WEBHOOK_LOG_RETENTION_DAYS 90 config.go:433 Jours de rétention hyperswitch_webhook_log.

10. Stripe Connect / payouts créateurs

Variable Défaut Lu à Rôle
STRIPE_CONNECT_ENABLED false config.go:415 Active le flow payout créateur (v0.602).
STRIPE_SECRET_KEY (vide) config.go:416 Requis si activé.
STRIPE_CONNECT_WEBHOOK_SECRET (vide) config.go:417 Requis si activé.
PLATFORM_FEE_RATE 0.10 config.go:418 Commission plateforme (01).
TRANSFER_RETRY_ENABLED true config.go:421 Worker retry transfers échoués.
TRANSFER_RETRY_MAX 3 config.go:422
TRANSFER_RETRY_INTERVAL 5m config.go:423 Délai entre retries.
REVERSAL_WORKER_ENABLED true config.go:426 Worker async reverse-charge (v1.0.7 item B).
REVERSAL_MAX_RETRIES 5 config.go:427
REVERSAL_CHECK_INTERVAL 1m config.go:428 Poll.
REVERSAL_BACKOFF_BASE 1m config.go:429 Backoff exponentiel base.
REVERSAL_BACKOFF_MAX 1h config.go:430 Plafond backoff.
RECONCILE_WORKER_ENABLED true config.go:436 Réconciliation orders/refunds stuck (v1.0.7 item C).
RECONCILE_INTERVAL 1h config.go:437 Sweep.
RECONCILE_ORDER_STUCK_AFTER 30m config.go:438 Seuil staleness order.
RECONCILE_REFUND_STUCK_AFTER 30m config.go:439 Seuil staleness refund.
RECONCILE_REFUND_ORPHAN_AFTER 5m config.go:440 Seuil orphan refund.

11. RabbitMQ / event bus

Variable Défaut Lu à Rôle
RABBITMQ_ENABLE true config.go:397 Active les events async.
RABBITMQ_URL amqp://veza:password@veza.fr:15672/ config.go:326 URL connexion. Requis en prod si activé.
RABBITMQ_MAX_RETRIES 10 config.go:395 Retries connexion.
RABBITMQ_RETRY_INTERVAL 5s config.go:396 Délai retries.

12. Stockage S3 / MinIO

Opt-in. Le path upload principal n'utilise pas encore S3 (FUNCTIONAL_AUDIT §4 item 2 — stockage local disque only).

Variable Défaut Lu à Rôle
AWS_S3_ENABLED false config.go:364 Master switch.
AWS_S3_BUCKET (vide) config.go:359 Nom bucket.
AWS_REGION us-east-1 config.go:360 Région.
AWS_S3_ENDPOINT (vide) config.go:361 Endpoint custom (MinIO).
AWS_ACCESS_KEY_ID (vide) config.go:362 Optionnel si IAM role EC2.
AWS_SECRET_ACCESS_KEY (vide) config.go:363

13. HLS streaming + track storage backend

HLS

Variable Défaut Lu à Rôle
HLS_STREAMING false config.go:355 Active les endpoints HLS manifest/segments. Off = player fallback sur /tracks/:id/stream avec Range.
HLS_STORAGE_DIR /tmp/veza-hls config.go:356 Stockage segments HLS.
HLS_OUTPUT_DIR (contextuel) workers/job_worker.go Output segments transcodés.
STREAM_HLS_BASE_URL (vide) live_stream_callback.go Base URL publique pour liens m3u8.

Pattern d'activation : HLS_STREAMING=true + stream server up + transcoding pipeline active. Défaut off, fallback direct-stream suffit pour le démarrage.

Track upload storage backend (v1.0.8 Phase 0)

Variable Défaut Lu à Rôle
TRACK_STORAGE_BACKEND local config.go (bloc S3) TrackService.UploadTrack() écrit les fichiers track. Valeurs : local (disque, uploads/tracks/) ou s3 (via S3StorageService). En prod, s3 nécessite AWS_S3_ENABLED=true — boot échoue sinon (validation.go règle 11). Dev/staging warn et fallback sur local.

Pour migrer un environnement :

  1. Deploy avec TRACK_STORAGE_BACKEND=local (aucun changement).
  2. Activer S3 : AWS_S3_ENABLED=true, AWS_S3_BUCKET=<bucket>, AWS_S3_ENDPOINT=<minio-url>, credentials.
  3. Flipper : TRACK_STORAGE_BACKEND=s3. Nouveaux uploads vont sur MinIO/S3, tracks existants restent local.
  4. (Optionnel) Lancer cmd/migrate_storage (Phase 3) pour déplacer les tracks local vers s3.

Rollback : revert TRACK_STORAGE_BACKEND=local, nouveaux uploads repartent en local. Les tracks déjà migrés restent en s3 (read path les sert via signed URL en Phase 2).

14. Stream server (backend ↔ stream)

Variable Défaut Lu à Rôle
STREAM_SERVER_URL http://veza.fr:8082 config.go:344 URL stream server côté backend.
STREAM_SERVER_INTERNAL_API_KEY (vide) config.go:345 Secret partagé /internal/jobs/transcode. Doit matcher le INTERNAL_API_KEY du stream server.
CHAT_SERVER_URL http://veza.fr:8081 config.go:346 Historique — le chat est dans le backend Go depuis v0.502.

15. Elasticsearch

Variable Défaut Lu à Rôle
ELASTICSEARCH_URL (vide) elasticsearch/config.go:14 Vide = search désactivée (fallback Postgres).
ELASTICSEARCH_INDEX veza-platform elasticsearch/config.go:15 Préfixe indices.
ELASTICSEARCH_AUTO_INDEX false search service Auto-create index au boot.

Admin : POST /api/v1/admin/search/reindex pour réindexation manuelle.

16. ClamAV / antivirus

Variable Défaut Lu à Rôle
ENABLE_CLAMAV true api/router.go Active le scan AV sur upload.
CLAMAV_REQUIRED true validation.go:886 Boot prod échoue si ClamAV indispo. Dev seul peut mettre false.
CLAMAV_ADDRESS upload service host:port clamd.
CLAMAV_CLAMD_PATH upload service Alternative socket local.

17. Sentry / tracking d'erreurs

Variable Défaut Lu à Rôle
SENTRY_DSN (vide) config.go:367 Vide = Sentry désactivé.
SENTRY_ENVIRONMENT dérivé de APP_ENV config.go:368 Label UI Sentry.
SENTRY_SAMPLE_RATE_ERRORS 1.0 config.go:369 01.
SENTRY_SAMPLE_RATE_TRANSACTIONS 0.1 config.go:370 01.

18. Logging

Variable Défaut Lu à Rôle
LOG_DIR /var/log/veza config.go:444 Dossier fichiers log.
LOG_FORMAT env-aware logging json (prod) / console (dev).
LOG_AGGREGATION_ENABLED dérivé config.go:464 True auto si endpoint défini.
LOG_AGGREGATION_ENDPOINT (vide) config.go:386 Loki ou compatible.
LOG_AGGREGATION_BATCH_SIZE 100 config.go:387 Lignes par batch.
LOG_AGGREGATION_FLUSH_INTERVAL 5s config.go:388 Auto-flush.
LOG_AGGREGATION_TIMEOUT 10s config.go:389 Timeout HTTP.
LOG_AGGREGATION_LABELS service=veza-api config.go:390 CSV key=value.

19. Monitoring / metrics

Variable Défaut Lu à Rôle
PROMETHEUS_URL (vide) config.go Push gateway optionnel.
SLOW_REQUEST_THRESHOLD_MS 1000 middleware/request_logger.go Log + counter pour requêtes plus lentes.
METRICS_ALLOWED_IPS metrics middleware CIDR whitelist /metrics.
METRICS_BEARER_TOKEN metrics middleware Auth bearer optionnelle.
METRICS_PUBLIC_IN_DEV false metrics middleware Skip auth en dev.

En prod, si ni METRICS_ALLOWED_IPS ni METRICS_BEARER_TOKEN n'est défini, /metrics retourne 403.

20. Frontend (Vite)

Tout lu dans apps/web/src/lib/env.ts (+ apps/web/src/lib/featureFlags.ts). Préfixe VITE_ obligatoire — les autres vars ne sont pas exposées au navigateur.

URLs de base — dérivées de VITE_DOMAIN si omises :

Variable Défaut Rôle
VITE_DOMAIN veza.fr Domaine racine pour dérivations.
VITE_API_URL /api/v1 API backend (relatif ou absolu).
VITE_WS_URL dérivé URL WebSocket.
VITE_STREAM_URL ws://veza.fr:8082/stream WS stream server.
VITE_HLS_BASE_URL dérivé Base m3u8.
VITE_UPLOAD_URL /upload Endpoint upload.
VITE_BACKEND_PORT 18080 Target proxy Vite dev.
VITE_APP_NAME Veza Nom affiché.
VITE_API_VERSION v1 Suffix version API.

Clés tierces :

Variable Rôle
VITE_HYPERSWITCH_PUBLISHABLE_KEY Widget checkout Hyperswitch.
VITE_FCM_VAPID_KEY FCM push notifications.
VITE_SENTRY_DSN Sentry frontend.

Toggles runtime :

Variable Défaut Rôle
VITE_DEBUG false Log API verbeux (true / 1).
VITE_USE_MSW 0 Mock Service Worker.
VITE_LOG_LEVEL (utils) Niveau log frontend.
VITE_LOG_ENDPOINT (vide) Logging distant.
VITE_ENABLE_VALIDATION_ALERTING Alertes validation UI.
VITE_GITHUB_REPO Lien feedback.
VITE_STORYBOOK Mode Storybook.

21. Feature flags

Backend (config.go) :

Variable Défaut Lu à Rôle
MAINTENANCE_MODE false middleware/maintenance.go 503 pour routes non-admin. TTL-cache depuis platform_settings.
BYPASS_CONTENT_CREATOR_ROLE false validation.go:1018 Dev/test only — validation prod échoue si true.
CSRF_DISABLED false CSRF middleware Dev only.
HARD_DELETE_CRON_ENABLED false cleanup jobs Sweep nightly hard-delete.

Frontend (apps/web/src/lib/featureFlags.ts) :

Variable Défaut Feature
VITE_FEATURE_TWO_FACTOR_AUTH true 2FA.
VITE_FEATURE_PLAYLIST_COLLABORATION true Playlists partagées.
VITE_FEATURE_PLAYLIST_SEARCH false Search intra-playlist.
VITE_FEATURE_PLAYLIST_SHARE false Liens token partageables.
VITE_FEATURE_PLAYLIST_RECOMMENDATIONS false
VITE_FEATURE_HLS_STREAMING true HLS playback player (gate frontend).
VITE_FEATURE_ROLE_MANAGEMENT false Matrice rôles admin.
VITE_FEATURE_NOTIFICATIONS false Push notifications.

22. Politique de mot de passe

Variable Défaut Lu à
PASSWORD_MIN_LENGTH (built-in) password_validator.go
PASSWORD_MAX_LENGTH (built-in) password_validator.go
PASSWORD_REQUIRE_UPPER (built-in) password_validator.go
PASSWORD_REQUIRE_LOWER (built-in) password_validator.go
PASSWORD_REQUIRE_NUMBER (built-in) password_validator.go
PASSWORD_REQUIRE_SPECIAL (built-in) password_validator.go

23. Build / version info

Injecté au build via -ldflags :

Variable Défaut Lu à Rôle
APP_VERSION v1.0.0 routes_core.go Version sémantique.
GIT_COMMIT unknown routes_core.go SHA Git.
BUILD_TIME (vide) routes_core.go Timestamp RFC3339.

24. RTMP / Web Push / divers

Variable Rôle
VAPID_PRIVATE_KEY / VAPID_PUBLIC_KEY Web Push (requis si push activé).
RTMP_CALLBACK_SECRET Signature callback on_publish Nginx-RTMP.
NGINX_RTMP_HOST Hôte affiché aux streamers (rtmp_url). Défaut stream.veza.app.
NGINX_RTMP_ADDR Endpoint interne RTMP.
GEOIP_DB_PATH Chemin DB GeoIP2 (optionnel — géolocalisation IP).
HANDLER_TIMEOUT Timeout handler global (défaut 30s, config.go:377).
MAX_CONCURRENT_UPLOADS Backpressure upload (défaut 10, config.go:312).
MAX_JSON_BODY_SIZE Plafond body JSON (défaut 1MB).
CONFIG_WATCH Reload sur changement .env (T0040, défaut false, config.go:765).
FRONTEND_URL URL frontend côté backend (OAuth, emails).
BASE_URL URL publique backend (callbacks OAuth).
PGPASSWORD Pour CLI psql — pas le backend.
VEZA_ROOT / VEZA_SKIP_INTEGRATION Helpers test-suite.
E2E_TEST / TEST_EMAIL / TEST_USERNAME / TEST_PASSWORD Setup E2E.

Live streaming (v0.10.6 F471) : profiles Docker live. Ports 1935 (RTMP), 18083 (HTTP HLS). Callbacks vers POST /api/v1/live/callback/publish et .../publish_done.

25. Stream server (Rust) — schéma propre

Le stream server Rust a ~50 variables propres couvrant compression audio, TLS, workers Tokio, caching, tracing. Fichier principal : veza-stream-server/src/config/mod.rs.

Connexion : DATABASE_URL, REDIS_URL, RABBITMQ_URL, BACKEND_URL, PORT, SECRET_KEY, INTERNAL_API_KEY, ALLOWED_ORIGINS, JWT_PUBLIC_KEY_PATH, JWT_SECRET, JWT_EXPIRATION.

Stockage / audio : AUDIO_DIR, STREAM_OUTPUT_DIR, COMPRESSION_ENABLED, COMPRESSION_LEVEL, COMPRESSION_MAX_CONCURRENT_JOBS, COMPRESSION_OUTPUT_DIR, COMPRESSION_TEMP_DIR, COMPRESSION_CLEANUP_AFTER_DAYS, FFMPEG_PATH.

Pool DB : DB_POOL_SIZE, DB_CONNECTION_TIMEOUT, DB_IDLE_TIMEOUT, DB_MAX_LIFETIME, DB_MIN_CONNECTIONS, DB_MIGRATE_ON_START, DB_ENABLE_LOGGING.

Networking : TLS_CERT_PATH, TLS_KEY_PATH, TCP_NODELAY, TCP_KEEPALIVE, MAX_FILE_SIZE, MAX_RANGE_SIZE, MAX_CONCURRENT_STREAMS, STREAM_TIMEOUT, CORS_MAX_AGE.

Runtime Tokio : THREAD_STACK_SIZE, MAX_BLOCKING_THREADS, WORKER_THREADS.

Cache : CACHE_TTL_SECONDS, CACHE_MAX_SIZE_MB, CACHE_COMPRESSION, CACHE_CLEANUP_INTERVAL.

Notifications : NOTIFICATIONS_ENABLED, NOTIFICATIONS_BATCH_SIZE, NOTIFICATIONS_MAX_QUEUE_SIZE, NOTIFICATIONS_DELIVERY_WORKERS, NOTIFICATIONS_RETRY_ATTEMPTS, NOTIFICATIONS_RETRY_DELAY, ALERT_WEBHOOKS.

Sécurité : SECURE_HEADERS, CSRF_PROTECTION, SIGNATURE_TOLERANCE.

Observability : METRICS_ENABLED, METRICS_PORT, PROMETHEUS_NAMESPACE, JAEGER_ENDPOINT, HEALTH_CHECK_INTERVAL, LOG_DIR, LOG_LEVEL, LOG_FORMAT.

Documentation complète beside le stream server (veza-stream-server/.env.example) — délibérément séparé de ce catalogue (audience différente : opérateur stream vs. dev backend).

26. Security headers (rappel)

Appliqués globalement via middleware.SecurityHeaders() (veza-backend-api/internal/middleware/security_headers.go). Non configurables par env var — config dans le code.

Header Valeur Rôle
Strict-Transport-Security max-age=31536000; includeSubDomains; preload (prod only) HSTS
X-Content-Type-Options nosniff Anti MIME sniffing
X-Frame-Options DENY (SAMEORIGIN pour Swagger) Anti clickjacking
X-XSS-Protection 1; mode=block XSS legacy
Referrer-Policy strict-origin-when-cross-origin Referrer
Permissions-Policy geolocation=(), microphone=(), camera=()... Restriction features
Content-Security-Policy default-src 'none'; ... CSP strict hors Swagger
X-Permitted-Cross-Domain-Policies none Flash/PDF
Cross-Origin-Embedder-Policy require-corp COEP
Cross-Origin-Opener-Policy same-origin COOP
Cross-Origin-Resource-Policy same-origin CORP

27. Variables dépréciées / legacy

Fonctionnent encore avec un warning deprecation. Supprimées en v1.1.0 — migrer maintenant.

Déprécié Canonique Notes
REDIS_ADDR REDIS_URL URL supersede host/port/db split.
REDIS_PASSWORD REDIS_URL Embedded dans URL.
REDIS_DB REDIS_URL Path segment /0.
SMTP_USER SMTP_USERNAME Renommé v1.0.6.
FROM_EMAIL SMTP_FROM Unifié v1.0.6.
FROM_NAME SMTP_FROM_NAME Unifié v1.0.6.
GO_ENV, NODE_ENV APP_ENV
VITE_FRONTEND_URL FRONTEND_URL Frontend lit depuis backend.
JWT_ACCESS_TOKEN_DURATION (hardcoded) Hardcodé dans le service JWT.
JWT_REFRESH_TOKEN_DURATION (hardcoded)
RATE_LIMIT_ENABLED (implicite) Toujours on si Redis dispo.
DATABASE_MAX_OPEN_CONNS DB_MAX_OPEN_CONNS Bug template — renommé v1.1.0.
DATABASE_MAX_IDLE_CONNS DB_MAX_IDLE_CONNS
DATABASE_CONN_MAX_LIFETIME DB_MAX_LIFETIME

28. Règles de validation production

Config.Validate() dans veza-backend-api/internal/config/validation.go applique :

Règle Fichier:ligne
LOG_LEVEL=DEBUG refusé en prod validation.go:876
CORS_ALLOWED_ORIGINS sans wildcards en prod validation.go:869
CHAT_JWT_SECRET doit différer de JWT_SECRET en prod validation.go:891
CLAMAV_REQUIRED=false refusé en prod validation.go:886
OAUTH_ENCRYPTION_KEY ≥32 bytes requis en prod validation.go:896
HYPERSWITCH_ENABLED=true requiert HYPERSWITCH_API_KEY + webhook secret validation.go:908
REDIS_URL doit être explicite en prod (pas de fallback default) validation.go:916
TRACK_STORAGE_BACKEND must be local ou s3 (règle 11, v1.0.8) config.go ValidateForEnvironment
TRACK_STORAGE_BACKEND=s3 requiert AWS_S3_ENABLED=true en prod config.go ValidateForEnvironment
BYPASS_CONTENT_CREATOR_ROLE=true refusé en prod validation.go:1018

Si une règle est violée, boot échoue avec message humain pointant la variable fautive.

Validation manuelle : ./scripts/validate-env.sh development (ou production, test). Intégré dans make doctor.

29. Drift template ↔ code

Survey 2026-04-23 a identifié des incohérences entre .env.template et le code. Non-bloquants, cleanup v1.1.0.

Manquant dans template (le code les lit, le dev peut s'en sortir sans les définir) : HLS_STREAMING (ajouté 2026-04-23), TRACK_STORAGE_BACKEND (ajouté 2026-04-23), SLOW_REQUEST_THRESHOLD_MS, CONFIG_WATCH, HANDLER_TIMEOUT, MAX_JSON_BODY_SIZE, GEOIP_DB_PATH, VAPID_PRIVATE_KEY / VAPID_PUBLIC_KEY, RTMP_CALLBACK_SECRET, NGINX_RTMP_*, HARD_DELETE_CRON_ENABLED, ELASTICSEARCH_AUTO_INDEX.

Dans template mais non lus : REDIS_ADDR, REDIS_PASSWORD, REDIS_DB, JWT_ACCESS_TOKEN_DURATION, JWT_REFRESH_TOKEN_DURATION, RATE_LIMIT_ENABLED, DATABASE_MAX_OPEN_CONNS / DATABASE_MAX_IDLE_CONNS / DATABASE_CONN_MAX_LIFETIME (mauvais noms).

Incohérence de nommage : SMTP_USERNAME canonique vs SMTP_USER legacy ; DB_MAX_* code vs DATABASE_MAX_* template.

30. Checklist de démarrage

  1. Copier veza-backend-api/.env.template vers veza-backend-api/.env et configurer.
  2. Pour RS256 prod : exécuter scripts/generate-jwt-keys.sh et configurer JWT_PRIVATE_KEY_PATH, JWT_PUBLIC_KEY_PATH. Sinon JWT_SECRET ≥32 chars.
  3. Configurer les 5 minimums : DATABASE_URL, REDIS_URL, JWT_SECRET (ou keys RS256), CORS_ALLOWED_ORIGINS, FRONTEND_URL.
  4. Si paiements : HYPERSWITCH_ENABLED=true + HYPERSWITCH_API_KEY + HYPERSWITCH_WEBHOOK_SECRET.
  5. Valider : ./scripts/validate-env.sh development (ou production).
  6. Démarrer : make dev.
  7. En prod : ne jamais committer .env ni fichiers .pem.

Dernière sync 2026-04-23 — v1.0.7-rc1 HEAD 778c8550. Quand tu ajoutes une variable dans le code, mets à jour ce fichier + .env.template dans le même commit. Cross-référence AUDIT_REPORT.md §9 item #15.