Configuration
Simmetric Chat dispose de deux niveaux de configuration : des variables d'environnement validées avec Zod au démarrage du processus, et un niveau de configuration runtime stocké en base de données que les administrateurs peuvent modifier depuis l'interfa…
Simmetric Chat dispose de deux niveaux de configuration : des variables d'environnement validées avec Zod au démarrage du processus, et un niveau de configuration runtime stocké en base de données que les administrateurs peuvent modifier depuis l'interface sans redémarrer aucun service.
- Variables d'environnement (démarrage du processus) - validées avec Zod dans
packages/<pkg>/src/config/env.ts;process.exit(1)si invalides. - Configuration runtime (DB `SystemConfig`) - modifiable depuis l'interface admin sans redémarrage.
Résolution :
- Clés
ALWAYS_READONLY(JWT_SECRET,DATABASE_URL,SERVER_PORT,COLLECTOR_PORT,SERVER_URL,COLLECTOR_URL,LICENSE_SECRET) :ENV > Default, non modifiables depuis l'interface. - Toutes les autres :
DB > ENV > Default, modifiables viaPUT /api/system/settings.
Les trois packages lisent .env via path.resolve(__dirname, "../../.env") (indépendant du répertoire courant). Le document de référence est .env.example à la racine du dépôt.
Variables d'environnement - server
Schéma : packages/server/src/config/env.ts. Valeurs par défaut affichées ; OBL = obligatoire.
Core / infra
| Variable | Default | Obl. | Description |
|---|---|---|---|
NODE_ENV | development | opt | development/production/test |
SERVER_PORT | 3000 | opt | Port de l'API serveur |
COLLECTOR_PORT | 3210 | opt | Port du collector (pour l'URL par défaut) |
SERVER_URL | http://localhost:3000 | opt | URL publique du serveur |
COLLECTOR_URL | http://localhost:3210 | opt | URL du collector |
WIDGET_SERVICE_URL | http://localhost:3211 | opt | URL du service widget (push cache-bust) |
WIDGET_API_KEY | — | opt | Secret partagé du push widget ; absent → cache-bust no-op (TTL 5 min) |
DATABASE_URL | postgresql://simmetricchat:[email protected]:5432/simmetricchat | opt | URL PostgreSQL |
JWT_SECRET | — | OBL | Secret JWT |
ENCRYPTION_KEY | — | opt | Base64 de 32 octets pour AES-256-GCM (data-at-rest). Non défini → repli scryptSync(JWT_SECRET, salt) |
SESSION_EXPIRY | 86400000 (24h ms) | opt | Expiration JWT |
ALLOWED_ORIGINS | http://localhost:5173,127.0.0.1:5173,localhost:3000 | opt | Allowlist CORS globale (CSV). /api/internal/widget exclu |
LOG_LEVEL | info | opt | debug/info/warn/error |
ALLOW_REGISTRATION | false | opt | Interrupteur d'auto-inscription |
DISABLE_TELEMETRY | true | opt | Désactive la télémétrie |
Bootstrap admin (seed)
| Variable | Default | Description |
|---|---|---|
SEED_BOOTSTRAP_ADMIN | true | Auto-seed de l'admin au premier démarrage (transform custom : false/0/no/off/"" = désactivé) |
SEED_ADMIN_USERNAME | admin | Nom d'utilisateur de l'admin bootstrap |
SEED_ADMIN_PASSWORD | admin123 | Mot de passe (min 8) ; compte mustChangePassword=true |
SEED_ADMIN_EMAIL | [email protected] | Email de l'admin bootstrap |
LLM
| Variable | Default | Description |
|---|---|---|
LLM_PROVIDER | ollama | openai/anthropic/ollama/openrouter |
LLM_MODEL | gemma4:latest | Modèle par défaut |
LLM_TEMPERATURE | 0.7 | 0–2 |
LLM_MAX_TOKENS | 4096 | Plafond de tokens de complétion |
LLM_TIMEOUT | 0 | Timeout Axios en ms (0 = aucun, pour les LLM locaux lents) |
LLM_API_KEY / LLM_API_BASE_URL | — | Overrides génériques |
OPENAI_API_KEY / OPENAI_MODEL | — | OpenAI |
ANTHROPIC_API_KEY / ANTHROPIC_MODEL | — | Anthropic |
OLLAMA_BASE_URL | http://ollama:11434 | Point d'accès Ollama |
OLLAMA_MODEL / OLLAMA_API_KEY | — | Override Ollama |
OPENROUTER_API_KEY / OPENROUTER_BASE_URL / OPENROUTER_MODEL | https://openrouter.ai/api / — | OpenRouter |
Watchdog d'agent (prévention des boucles/stalls)
| Variable | Default | Description |
|---|---|---|
AGENT_WALLCLOCK_TIMEOUT_MS | 600000 (10 min) | Borne supérieure absolue pour une requête ReAct |
AGENT_MAX_TOTAL_TOKENS | 200000 | Total prompt+completion par requête |
AGENT_MAX_CONTEXT_BYTES | 500000 (500 Ko) | Plafond de taille du tableau de contexte |
AGENT_MAX_TOOL_OUTPUT_LENGTH | 5000 | Troncature de la sortie par skill |
AGENT_MAX_SKILL_EXECUTION_MS | 60000 | Timeout par skill |
AGENT_LOOP_DETECTION_WINDOW | 3 | Abandon après N tool+input identiques consécutifs |
CHAT_MAX_CONCURRENT_PER_USER | 5 | Limite de concurrence des chats par utilisateur |
Embedding / Vector DB / OCR / Synthesis
| Variable | Default | Description |
|---|---|---|
EMBEDDING_PROVIDER | local | local/openai/ollama |
EMBEDDING_MODEL | Xenova/all-MiniLM-L6-v2 | Modèle d'embedding |
EMBEDDING_API_KEY | — | Clé API d'embedding |
VECTOR_DB_PROVIDER | lancedb | lancedb/qdrant |
VECTOR_DB_URL / VECTOR_DB_API_KEY | — | Pour Qdrant distant |
OCR_MODEL | glm-ocr:latest | Modèle vision OCR (format model:version) |
OCR_TIMEOUT | 600000 | Timeout OCR vision |
SYNTHESIS_LLM_MODEL | gemma4:latest | Modèle du pipeline de synthèse |
PUPPETEER_EXECUTABLE_PATH | — | Chromium pour l'export PDF des archives |
Licence, push, email, collector
| Variable | Default | Description |
|---|---|---|
LICENSE_KEY | — | JWT de licence Enterprise (HS256). Absent → Community |
LICENSE_SECRET | — | Secret de vérification JWT (recommandé) ; repli sur LICENSE_KEY |
COLLECTOR_SECRET | — | OBL — secret partagé server↔collector |
VAPID_PUBLIC_KEY / VAPID_PRIVATE_KEY / VAPID_SUBJECT | — | Web Push ; non défini → clés éphémères générées en dev |
SMTP_HOST / SMTP_PORT / SMTP_USER / SMTP_PASS / SMTP_FROM | — | SMTP pour la réinitialisation de mot de passe + notifications d'échec de sauvegarde |
LEGACY_PREVIOUS_ENCRYPTION_KEYS | — | CSV base64 32 octets pour la rotation des clés |
Variables dans.env.examplemais gérées comme settings DB (pas dansenvSchema) :OCR_ENABLED,OCR_PRECHECK_CHARS,STORAGE_PATH(collector),RESET_PASSWORD_STRATEGY.
Variables d'environnement - collector
Schéma : packages/collector/src/config/env.ts.
| Variable | Default | Obl. | Description |
|---|---|---|---|
COLLECTOR_PORT | 3210 | opt | Port HTTP |
COLLECTOR_URL | http://localhost:3210 | opt | URL propre |
SERVER_URL | http://localhost:3000 | opt | URL du serveur (callback) |
EMBEDDING_PROVIDER | local | opt | local/openai/ollama |
EMBEDDING_MODEL | — | opt | Modèle d'embedding |
EMBEDDING_API_KEY | — | opt | Clé API |
VECTOR_DB_PROVIDER | lancedb | opt | lancedb/qdrant |
VECTOR_DB_URL / VECTOR_DB_API_KEY | — | opt | Qdrant |
OLLAMA_BASE_URL | http://ollama:11434 | opt | Ollama |
STORAGE_PATH | ./storage | opt | Stockage filesystem |
COLLECTOR_SECRET | — | OBL | Doit correspondre au serveur |
Variables d'environnement - widget
Schéma : packages/widget/src/config/env.ts.
| Variable | Default | Obl. | Description |
|---|---|---|---|
NODE_ENV | development | opt | Environnement |
WIDGET_PORT | 3211 | opt | Port HTTP |
SERVER_URL | http://localhost:3000 | opt | URL du serveur |
WIDGET_API_KEY | — | OBL | Secret partagé widget↔server (doit correspondre) |
LOG_LEVEL | info | opt | Niveau de log |
Frontend : aucune variableVITE_*ni fichier.env. Le frontend lit le branding/config depuis le serveur (GET /api/system/settings,GET /api/license/info).
Feature flags & licence
Définis dans packages/shared/src/constants/license.ts (FEATURE_FLAGS + valeurs par défaut). Vérification dans packages/server/src/services/licenseService.ts.
Comment passer de Community à Enterprise
- Définissez
LICENSE_KEY(JWT HS256) et, recommandé,LICENSE_SECRET. jwt.verify→ payload validé contrelicensePayloadSchema(tier,iss,sub,iat,exp,features).tier=enterprise→ démarre depuisENTERPRISE_FEATURE_DEFAULTS+ les overridesfeaturesdu JWT.- Expiré/invalide → repli Community avec avertissement.
Dégradation progressive : getLicenseInfo() vérifie l'expiration à l'exécution ; si Enterprise expire pendant l'utilisation, elle dégrade vers Community sans redémarrage. requireFeature(flag) → HTTP 402 si désactivé ; requireFeatureLimit(flag, model) → 402 si count >= limit (Enterprise = Infinity).
Flags commodity toujours actifs : depuis la suppression EPA-02, les 8 flags commodity n'existent plus dans FEATURE_FLAGS - webhooks, push_notifications, web search, memory, lead_export, widget_analytics, auto_title, synthesis_rate_limit sont toujours actifs en Community (les routes commodity tournent sans gating). priority_support n'est pas un flag : c'est un contrat commercial/SLA (EPA-08). Il reste 11 flags enterprise, dont widget_credits_editing (édition des crédits widget, Community false / Enterprise true) et custom_agents comme limite numérique (Community 3, Enterprise Infinity).
Tableau des flags (11)
| Flag | Type | Community | Enterprise | Ce qu'il gate |
|---|---|---|---|---|
sso_enabled | bool | false | true | SSO Enterprise |
audit_log_immutable | bool | false | true | Immuabilité du journal d'audit |
white_label | bool | false | true | Branding BRANDING_* |
max_workspaces | num | 3 | Infinity | Création de workspace |
max_projects | num | 3 | Infinity | Création de projet |
custom_agents | num | 3 | Infinity | Agents custom (limite) |
widget_enabled | bool | false | true | Widget embarquable |
max_widgets | num | 1 | Infinity | Création de widget |
backup_enabled | bool | false | true | Système de sauvegarde |
max_backup_destinations | num | 1 | Infinity | Destinations de sauvegarde |
widget_credits_editing | bool | false | true | Édition des crédits widget |
Runtime config (DB SystemConfig)
Modifiable via GET/PUT /api/system/settings (bulk) et PUT /api/system/chat-retention (spécifique, audité). Les valeurs par défaut vivent dans CONFIG_DEFAULTS (packages/shared/src/constants/permissions.ts).
Groupes de clés : LLM (LLM_PROVIDER, LLM_MODEL, LLM_TEMPERATURE, ...), Embedding/Vector, Ports/URL serveur, Auth (SESSION_EXPIRY), Branding (BRANDING_APP_NAME, BRANDING_PRIMARY_COLOR, BRANDING_APP_SUBTITLE, BRANDING_APP_ICON_URL - gated white_label), Feature (DISABLE_TELEMETRY, ALLOW_REGISTRATION, DLP_ENABLED), OCR (OCR_DEFAULT_MODEL, OCR_DEFAULT_MODE, OCR_DEFAULT_CUSTOM_INSTRUCTIONS, OCR_ENABLED, OCR_PRECHECK_CHARS), Synthesis (SYNTHESIS_LLM_PROVIDER_ID, SYNTHESIS_LLM_MODEL), Retention (upload_draft_retention_days, ALLOW_NON_ADMIN_UPLOAD, chat_message_retention_days).
PUT /api/system/settings renvoie toujours 200 avec { updated: [...], rejected: [...] } (les clés readonly sont rejetées tandis que les autres sont appliquées).
Rétention des messages de chat (reaper)
Service : packages/server/src/services/chatMessageReaperJob.ts. Knob DB : chat_message_retention_days.
- Pass 1 (soft-delete) : tombstones les messages des chats ACTIFS au-delà de
retentionDays. No-op si la valeur estnull/""/<=0. - Pass 2 (hard-purge) : supprime les lignes tombstonées au-delà d'une grâce de 7 jours (codée en dur). S'exécute toujours, indépendamment de la config de rétention (anti-fuite de PII).
- Cadence :
setIntervalde 24h, premier passage à 03:00 heure locale. MutexisRunning. - Uniquement
PUT /api/system/chat-retention(audité,confirmDataLoss: true,retentionDays: integer|null, min 1) ; l'endpoint bulk rejette cette clé.
Rétention des sauvegardes
Par job (champ retentionDays sur BackupJob, défaut 30). backupRetentionService.ts nettoie les journaux/fichiers au-delà de cutoffDate. Ce n'est pas global.
Rotation des clés de chiffrement
packages/server/src/services/encryptionService.ts (AES-256-GCM, clé 32 octets, IV 16 octets, sel simmetric-chat-encryption-salt).
- Clé courante :
ENCRYPTION_KEY(base64 32 octets) si définie ; sinonscryptSync(JWT_SECRET, salt, 32). LEGACY_PREVIOUS_ENCRYPTION_KEYS(CSV base64 32 octets) → chaîne de clés de déchiffrement[current, ...previous, scryptLegacy?].encrypt()utilisechain[0]. Aucun job automatique de ré-encryption : la procédure est manuelle déchiffrer-avec-l'ancienne → rechiffrer-avec-la-nouvelle.
Cross-link
- Endpoints de configuration : 04 - API Reference
- Fonctionnalités internes : 05 - Feature Guide
- Env vars de déploiement : 09 - Deployment