e97c885ebf
Backend exposé via Traefik+TLS (réseau traefik-public externe, labels, CHLOVA_DOMAIN) — surface unique. Script provision-auth (hash scrypt + TOTP otpauth + JWT). .env.example section API/UI. security.md : surface exposée Phase 4. Compose revalidé. Palier de risque : privilégié (exposition réseau) — non déployé ; auth requise pour activer l'API. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
4.3 KiB
4.3 KiB
Sécurité CHLOVA
Non négociable. Risque n°1 : la prompt injection. L'agent a un accès quasi-root via Portainer — le modèle de menace part du principe qu'une entrée hostile peut détourner l'agent.
Modèle de menace
- Prompt injection : une donnée lue (message, contenu de workflow, log) tente de faire exécuter à l'agent une action non voulue.
- Exfiltration de secrets : l'agent ne doit jamais voir de secret en clair.
- Escalade : reclasser un asset privilégié en réversible pour contourner la
review. Interdit par construction (voir
risk-tiers.md). - Exposition réseau : une brique interne deviendrait joignable de l'extérieur.
Défenses (par couche)
1. Réduction de la surface
- Seul le backend CHLOVA est exposé (auth + TLS). Ollama, n8n, Portainer et
les serveurs MCP n'écoutent que sur
chlova-internal. Voirinfra/networks.md. - Phase 1 : surface Telegram en long-polling → aucun port publié.
2. Accès Docker via socket-proxy (obligatoire)
- Jamais de
/var/run/docker.sockmonté dans l'agent ou le MCP Portainer. tecnativa/docker-socket-proxyfiltre les endpoints Docker autorisés.- Phase 1 (lecture seule) : n'autoriser que les endpoints de lecture
(
CONTAINERS=1,IMAGES=1,NETWORKS=1,VOLUMES=1,INFO=1,VERSION=1) et interdire tout le reste (POST=0,EXEC=0,CONTAINERS_CREATEabsent…). Détail dansinfra/socket-proxy/README.md.
3. Scoping des tokens
- Token n8n : portée minimale (lecture en P1).
- Token Portainer : portée minimale +
PORTAINER_READ_ONLY=trueen P1 (le serveur MCP annotereadOnlyHintet réécrit les secrets en[REDACTED]avant qu'ils n'atteignent le modèle). - Un token = un usage. Rotation documentée.
4. Egress filtré
- Sortie réseau par défaut refusée pour les conteneurs de l'agent.
- Seule exception :
ollama.com(proxy cloud Ollama). À appliquer au niveau pare-feu hôte / réseau Docker. Voirinfra/networks.md.
5. Secrets par référence
- Tous les secrets (dont
OLLAMA_API_KEY) via variables d'env / coffre, jamais en dur..envn'est jamais commité (.env.examplefait foi des clés requises). - L'agent manipule des références, pas des valeurs.
config.tsplante au boot (fail-closed) si un secret requis manque.
6. Lecture seule renforcée (Phase 1)
- Le readonly-filter de l'orchestrateur n'expose au LLM que les outils MCP
readOnlyHint=true. Les outils mutants ne sont pas branchés. Double barrière avec lePORTAINER_READ_ONLY=truecôté serveur MCP.
7. Audit
- Toute opération mutante est audit-loggée (qui/quoi/quand/résultat). En P1, toute exécution d'outil est tracée même si read-only.
- Déploiements de stacks en GitOps dès que possible (rollback + audit gratuits).
Surface exposée API/UI (Phase 4)
- Seul le backend est exposé, via Traefik + TLS (label compose, réseau
traefik-public). Ollama, MCP, n8n, Portainer restent internes. - Login fort obligatoire : mot de passe (scrypt) + TOTP 2FA → JWT court
(HS256).
/api/auth/loginest rate-limité (anti brute-force) ; tout le reste exige un Bearer valide. - L'API/UI ne s'active que si l'auth est configurée (
apiAuth(): 4 secrets présents). Sinon, surface Telegram seule (fail-safe). - Secrets d'auth via env (
provision-authles génère) ; jamais commités, masqués dans les logs (redactedConfig). - CORS restreint à
CHLOVA_WEB_ORIGIN(dev) ; en prod le SPA est servi en same-origin par le backend (Phase 4 frontend). - La capacité d'écriture reste derrière le gatekeeper (Phase 2) quelle que soit la surface : l'API n'élève aucun privilège.
Invariants vérifiés par test
- Aucun outil non-read-only n'est exposé en Phase 1 (
readonly-filter.test.ts). - Un asset
privilegedne peut pas être reclasséreversible(gatekeeper.test.ts). config.tsrefuse de démarrer si un secret requis manque.
Checklist de revue avant tout passage en Phase 2 (écriture)
- socket-proxy en place, endpoints d'écriture toujours refusés tant que non requis
- gatekeeper câblé (vérif statut avant exécution)
- egress toujours limité à
ollama.com - audit log couvre toute opération mutante
- tokens re-scopés au strict besoin de la capacité ajoutée