0f63b3addd
Modèle de menace centré prompt-injection + défenses par couche (surface réduite, socket-proxy obligatoire, scoping tokens, egress ollama.com only, secrets par référence, lecture seule renforcée, audit). Documente réseaux interne/egress et filtrage Docker en lecture seule P1. Normalise les fins de ligne (.gitattributes). Palier de risque : n/a (doc + conventions). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
69 lines
3.4 KiB
Markdown
69 lines
3.4 KiB
Markdown
# 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`. Voir `infra/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.sock` monté dans l'agent ou le MCP Portainer.
|
|
- `tecnativa/docker-socket-proxy` filtre 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_CREATE` absent…).
|
|
Détail dans `infra/socket-proxy/README.md`.
|
|
|
|
### 3. Scoping des tokens
|
|
- Token **n8n** : portée minimale (lecture en P1).
|
|
- Token **Portainer** : portée minimale + `PORTAINER_READ_ONLY=true` en P1
|
|
(le serveur MCP annote `readOnlyHint` et **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. Voir `infra/networks.md`.
|
|
|
|
### 5. Secrets par référence
|
|
- Tous les secrets (dont `OLLAMA_API_KEY`) via variables d'env / coffre, **jamais
|
|
en dur**. `.env` n'est jamais commité (`.env.example` fait foi des clés requises).
|
|
- L'agent manipule des **références**, pas des valeurs. `config.ts` **plante 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 le `PORTAINER_READ_ONLY=true` cô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).
|
|
|
|
## Invariants vérifiés par test
|
|
- Aucun outil non-read-only n'est exposé en Phase 1 (`readonly-filter.test.ts`).
|
|
- Un asset `privileged` ne peut pas être reclassé `reversible` (`gatekeeper.test.ts`).
|
|
- `config.ts` refuse 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
|