UNPKG

overmind-mcp

Version:

Orchestrateur universel agents IA multi-modeles via MCP. Inclut le protocole 'Custom-Nickname' pour identifier vos agents avec des surnoms originaux (The Chaos Prophet, Shadow Sniper, etc.), l'isolation mémoire (Private Memory Context) et le support pour

467 lines (381 loc) • 22 kB
# Plan d'intégration Loi 25 — Overmind-MCP > **Version** : 1.1 (décisions périmètre validées) > **Date** : 21 juillet 2026 > **Statut** : ✅ Périmètre validé — prêt à coder > **Cible** : overmind-mcp v3.9.0 > > **Décisions validées** : > - **Périmètre RP** : Mixte — consentement explicite (tiers externes) + intérêt légitime (usage interne) > - **Transferts hors QC** : Documentation seule, aucun blocage de providers > - **Rétention** : 30 jours par défaut pour tout, option de backup/archivage 5 ans > - **Activation** : Flag `OVERMIND_AUDIT_ENABLED=true` dans `.env` (désactivé = pas de garde) --- ## 1. Contexte L'Overmind est un **responsable de traitement** au sens de la Loi 25 (Loi moderneisant des dispositions législatives en matière de protection des renseignements personnels). Il collecte, stocke et transfère des renseignements personnels (RP) via : - **Mémoire PostgreSQL/pgvector** : `agent_runs` (prompts/résultats), `knowledge_chunks` (texte + embeddings) - **8 runners LLM externes** : Claude, Gemini, Kilo, QwenCLI, OpenClaw, Cline, OpenCode, Hermes - **Bridge Discord** : messages utilisateurs → LLM - **Profils Hermes** : `.env` (credentials), `SOUL.md` (personas), `state.db` (SQLite local) La conformité Loi 25 n'est pas optionnelle : la CAI a publié son cadre d'application des SAP en septembre 2023, et une vague d'application est imminente (2026-2027). ## 2. Articles Loi 25 applicables (matrice de conformité) | Article | Obligation | État Overmind | Priorité | |---|---|---|---| | **3-3.1** | RPRP désigné + reddition de comptes | ❌ Aucun | P0 | | **3.5-3.8** | Notification d'incident (CAI + personnes) | ❌ Aucun | P0 | | **4** | Finalité légitime + collecte pertinente | ⚠️ Implicite | P1 | | **8.1-8.2** | Consentement (libre, éclairé, spécifique) | ❌ Aucun | P0 | | **12.1** | Évaluation de l'atteinte (échelle de gravité) | ❌ Aucun | P1 | | **14-17.3** | Droits : accès, rectification, opposition, notification | ❌ Aucun | P0 | | **18.1** | EFVP (évaluation facteurs vie privée) pour nouveaux projets | ❌ Aucun | P1 | | **21-22** | Transferts hors Québec (documentation + garanties) | ❌ Aucun | P0 | | **23.1** | Anonymisation (technique, non-réidentification) | ❌ Aucun | P1 | | **26** | Droit d'accès (confirmation + communication) | ❌ Aucun | P0 | | **27** | Droit de rectification | ❌ Aucun | P1 | | **35.2-35.3** | Conservation et destruction des RP | ❌ Aucune rétention | P0 | | **35.18** | Registre des traitements / politique de confidentialité | ❌ Aucun | P0 | ## 3. Architecture cible — Privacy by Design ``` ┌─────────────────────────────────────────┐ │ Overmind MCP (FastMCP, 16 outils) │ │ │ Requête ──────────▶ │ ┌────────────────────────────────────┐ │ (prompt + │ │ 🛡️ LOI25 GUARD (middleware) │ │ data_subject_id + │ │ • Capture legal_basis │ │ legal_basis) │ │ • Valide consentement │ │ │ │ • Hash/anonymise si requis │ │ │ │ • Log transfert hors QC │ │ │ │ • Check rétention │ │ │ └─────────────┬──────────────────────┘ │ │ │ │ │ ┌───────────┼───────────┐ │ │ ▼ ▼ ▼ │ │ Runner Memory A2A Hub │ │ (8 LLM) (PG/vec) (bridges) │ └────┬──────────┬──────────┬───────────────┘ │ │ │ ┌────────▼──────────▼──────────▼──────────────┐ │ 📋 LOI25 DATA LAYER (nouveau) │ │ • consent_records │ │ • data_subjects (registre) │ │ • processing_registry │ │ • incident_log │ │ • access_log │ │ • retention_policies │ │ • transfer_log (hors QC) │ └─────────────────────────────────────────────┘ ``` ## 4. Plan d'intégration — 8 axes, 4 phases ### Phase 1 — Fondations (P0, fondement légal) **Objectif** : rendre l'Overmind capable de répondre aux droits d'accès, d'effacement et de reddition de comptes. #### 1.1 Schema DB — Gouvernance des RP **Modifier** `src/memory/PostgresMemoryProvider.ts` (initialisation des tables) : ```sql -- Extensions de agent_runs ALTER TABLE agent_runs ADD COLUMN IF NOT EXISTS data_subject_id TEXT, -- identifiant pseudonymisé de la personne legal_basis TEXT, -- 'consent' | 'contract' | 'legitimate_interest' | 'legal_obligation' consent_ref TEXT, -- FK vers consent_records.id retention_expires_at BIGINT, -- timestamp d'expiration (art. 35.2) anonymized INTEGER DEFAULT 0, -- 1 si anonymisé (art. 23.1) created_for TEXT; -- finalité (art. 4) -- Extensions de knowledge_chunks ALTER TABLE knowledge_chunks ADD COLUMN IF NOT EXISTS data_subject_id TEXT, legal_basis TEXT, consent_ref TEXT, retention_expires_at BIGINT, anonymized INTEGER DEFAULT 0; ``` **Nouvelles tables** (migration `scripts/audit_migration.mjs`) : ```sql CREATE TABLE IF NOT EXISTS data_subjects ( id TEXT PRIMARY KEY, -- UUID pseudonymisé (jamais l'identité brute) display_name TEXT, -- étiquette optionnelle (ex: "user_discord_123") source TEXT, -- 'discord' | 'api' | 'manual' created_at BIGINT, metadata JSONB -- infos non-RP (compteur de requêtes, etc.) ); CREATE TABLE IF NOT EXISTS consent_records ( id TEXT PRIMARY KEY, data_subject_id TEXT NOT NULL, purpose TEXT NOT NULL, -- 'agent_execution' | 'memory_storage' | 'embedding' legal_basis TEXT NOT NULL, granted_at BIGINT, expires_at BIGINT, -- consentement peut expirer withdrawn_at BIGINT, -- null si actif evidence TEXT, -- hash du message/source de consentement FOREIGN KEY (data_subject_id) REFERENCES data_subjects(id) ); CREATE TABLE IF NOT EXISTS processing_registry ( id TEXT PRIMARY KEY, name TEXT NOT NULL, -- 'agent_run_storage' | 'embedding_generation' purpose TEXT NOT NULL, legal_basis TEXT NOT NULL, data_categories TEXT, -- 'prompts' | 'embeddings' | 'discord_messages' recipients TEXT, -- providers LLM, vector DB retention_days INTEGER, created_at BIGINT, updated_at BIGINT ); CREATE TABLE IF NOT EXISTS incident_log ( id TEXT PRIMARY KEY, detected_at BIGINT NOT NULL, severity TEXT NOT NULL, -- 'low' | 'moderate' | 'high' category TEXT, -- 'data_leak' | 'unauthorized_access' | 'breach' description TEXT, data_subjects_affected INTEGER, cai_notified INTEGER DEFAULT 0, subjects_notified INTEGER DEFAULT 0, resolved_at BIGINT ); CREATE TABLE IF NOT EXISTS access_log ( id TEXT PRIMARY KEY, data_subject_id TEXT, accessed_by TEXT, -- agent_name ou 'system' action TEXT, -- 'read' | 'write' | 'delete' | 'transfer' resource_type TEXT, -- 'agent_run' | 'knowledge_chunk' resource_id TEXT, purpose TEXT, timestamp BIGINT ); CREATE TABLE IF NOT EXISTS retention_policies ( id TEXT PRIMARY KEY, category TEXT NOT NULL, -- 'agent_runs' | 'knowledge_chunks' | 'discord_messages' retention_days INTEGER NOT NULL, legal_basis TEXT, anonymize_after_days INTEGER, -- anonymiser avant suppression (art. 23.1) active INTEGER DEFAULT 1 ); CREATE TABLE IF NOT EXISTS transfer_log ( id TEXT PRIMARY KEY, data_subject_id TEXT, destination TEXT NOT NULL, -- 'anthropic' | 'google' | 'openai' | etc. destination_region TEXT, -- 'US' | 'EU' | 'QC' legal_mechanism TEXT, -- 'standard_contractual_clauses' | 'adequacy' | 'explicit_consent' data_type TEXT, timestamp BIGINT ); ``` #### 1.2 Nouveaux outils MCP (7 outils Loi 25) Créer dans `src/tools/` : | Outil | Article | Rôle | |---|---|---| | `audit_access_request` | 26 | Extrait tous les RP liés à un `data_subject_id` (export JSON) | | `audit_rectification` | 27 | Modifie un RP sur demande du sujet | | `audit_erasure` | 27 / 35.3 | Efface/anonymise les RP d'un sujet (droit à l'oubli) | | `audit_consent` | 8.1-8.2 | Enregistre/vérifie/révoque un consentement | | `audit_processing_registry` | 3-3.1 / 35.18 | Consulte le registre des traitements | | `audit_report_incident` | 3.5-3.8 | Signale un incident + génère notification CAI | | `audit_efvp` | 18.1 | Lance/consulte une évaluation des facteurs vie privée | Chaque outil suit le pattern existant : `audit_<nom>.ts` exporte `loi25<Nom>Schema` + `loi25<Nom>Function`, enregistré dans `server.ts`. #### 1.3 Migration de données existantes Script `scripts/audit_backfill.mjs` : - Scanne les `agent_runs` / `knowledge_chunks` existants - Pour chaque enregistrement sans `data_subject_id` : tente de détecter un identifiant dans le prompt (regex email/Discord ID) ou marque `data_subject_id = 'legacy_unknown'` - Applique une politique de rétention rétroactive (ex: 90 jours) - Anonymise les enregistrements expirés --- ### Phase 2 — Privacy Guard (P0, exécution) **Objectif** : intercepter chaque flux de RP pour appliquer les contrôles Loi 25. #### 2.1 Middleware AuditGuard Créer `src/lib/audit/guard.ts` — wrapper appliqué à chaque outil manipulant des RP : ```typescript export interface AuditContext { dataSubjectId?: string; // obligatoire si RP détectés legalBasis: LegalBasis; // 'consent' | 'contract' | 'legitimate_interest' consentRef?: string; // requis si legalBasis = 'consent' purpose: string; // finalité (art. 4) anonymize?: boolean; // anonymiser avant stockage } ``` **Mode mixte validé** — détection automatique de la base légale : - **Tiers externes** (clients, citoyens via Discord/API) → `consent` obligatoire - Détection : `dataSubjectId` absent du registre interne → flag `external = true` - Le guard rejecte si pas de consentement valide - **Usage interne** (toi + équipe) → `legitimate_interest` suffisant - Détection : `dataSubjectId` dans allowlist `OVERMIND_AUDIT_INTERNAL_SUBJECTS` - Pas de blocage, mais log quand même dans `access_log` - **Fallback** : si `OVERMIND_AUDIT_ENABLED=false` → guard inactif, comportement v3.8 Le guard : 1. **Si `OVERMIND_AUDIT_ENABLED=false`** → pass-through (zero overhead) 2. **Détection de la base légale** selon l'origine du sujet (interne vs tiers) 3. **Valide le consentement** si tiers → reject si expiré/révoqué 4. **Détecte les RP** dans le prompt (regex PII : email, téléphone, NAS, carte crédit) 5. **Hash/anonymise** si `anonymize = true` (SHA-256 de l'identifiant avant stockage) 6. **Log le transfert** si un runner LLM externe est appelé (art. 21) — documentation seule, pas de blocage 7. **Calcule la rétention** selon `retention_policies` et pose `retention_expires_at` #### 2.2 Capture au niveau du Bridge Modifier `src/bridge/OverBridgeService.ts` : - Chaque message Discord entrant génère un `data_subject_id` (hash du Discord user ID) - Le consentement est capturé : 1er message = capture implicite `legitimate_interest`, ou explicit si commande `!consent` / `!revoke` - Le `AuditContext` est propagé jusqu'à `storeRun()` #### 2.3 Hooks runners Modifier chaque `*Runner.ts` (8 fichiers) : - Avant l'appel LLM : log dans `transfer_log` (provider, région, mécanisme légal) - **Pas de blocage** (décision validée) — tous les providers restent accessibles - Config flag optionnel `OVERMIND_PII_FILTER=true` : filtre les RP du prompt avant envoi - La cartographie des transferts est consultable via l'outil `audit_processing_registry` --- ### Phase 3 — Lifecycle & Anonymisation (P1) #### 3.1 Cron de rétention + archivage 5 ans Créer `scripts/audit_retention_cron.mjs` (exécutable via systemd / Hermes cron) : - **Rétention active** : 30 jours pour `agent_runs` ET `knowledge_chunks` (défaut validé) - **Avant suppression** : archive vers table `archived_runs` / `archived_chunks` (cold storage) - **Archivage 5 ans** : les archives sont conservées 5 ans puis purgées définitivement - Suit `retention_policies` table : configurable par catégorie - Anonymise d'abord (art. 23.1), archive, puis supprime de la table active **Double table** (hot → cold → delete) : ```sql -- Archive cold storage (5 ans) CREATE TABLE IF NOT EXISTS archived_runs (LIKE agent_runs INCLUDING ALL); ALTER TABLE archived_runs ADD COLUMN archived_at BIGINT; ALTER TABLE archived_runs ADD COLUMN archive_expires_at BIGINT; -- +5 ans CREATE TABLE IF NOT EXISTS archived_chunks (LIKE knowledge_chunks INCLUDING ALL); ALTER TABLE archived_chunks ADD COLUMN archived_at BIGINT; ALTER TABLE archived_chunks ADD COLUMN archive_expires_at BIGINT; ``` **Workflow cron (chaque 24h)** : 1. `SELECT * FROM agent_runs WHERE retention_expires_at < now()` → anonymise → insert dans `archived_runs` (avec `archive_expires_at = now + 5 ans`) → delete de `agent_runs` 2. Idem pour `knowledge_chunks` → `archived_chunks` 3. `DELETE FROM archived_* WHERE archive_expires_at < now()` (purge définitive >5 ans) #### 3.1.1 Feature flag `.env` ```bash # .env — Loi 25 feature flag OVERMIND_AUDIT_ENABLED=true # master switch (false = pas de guard, comportement v3.8) OVERMIND_AUDIT_RETENTION_DAYS=30 # rétention active (défaut 30j) OVERMIND_AUDIT_ARCHIVE_YEARS=5 # archivage cold storage (défaut 5 ans) OVERMIND_AUDIT_DEFAULT_BASIS=legitimate_interest # base légale par défaut OVERMIND_AUDIT_AUTO_ANONYMIZE=true # anonymisation à l'expiration ``` #### 3.2 Anonymisation technique Créer `src/lib/audit/anonymize.ts` : - Pseudonymisation : remplace identifiants directs par hash SHA-256 + salt - K-anonymité sur embeddings : bruit gaussien pour réduire la ré-identification - Généralisation : tronque timestamps à la journée, géoloc à la région #### 3.3 Détection d'incident Étendre le système d'alerte existant (`triggerMemoryAlert`) : - Alertes → `incident_log` au lieu de log seul - Détection d'anomalies : accès inhabituel, volume anormal, erreur DB répétée - Workflow de notification (art. 3.5) : template CAI + template sujet --- ### Phase 4 — Transparence & Documentation (P1) #### 4.1 Politique de confidentialité machine-readable Créer `docs/PRIVACY_POLICY.json` (structuré, consommable par `audit_processing_registry`) : - Finalités par traitement - Bases légales - Destinataires (providers LLM + leurs régions) - Durées de conservation - Droits des personnes + modalités d'exercice #### 4.2 Cartographie des transferts Créer `src/lib/audit/transfer_map.ts` — référentiel des 8 providers : ```typescript export const PROVIDER_REGISTRY = { anthropic: { region: 'US', mechanism: 'standard_contractual_clauses', documented: true }, google: { region: 'US', mechanism: 'standard_contractual_clauses', documented: true }, openai: { region: 'US', mechanism: 'standard_contractual_clauses', documented: true }, minimax: { region: 'CN', mechanism: 'explicit_consent', documented: false }, zai: { region: 'CN', mechanism: 'explicit_consent', documented: false }, kimi: { region: 'CN', mechanism: 'explicit_consent', documented: false }, // ... }; ``` #### 4.3 Documentation EFVP Créer `docs/EFVP_OVERMIND.md` (évaluation des facteurs relatifs à la vie privée) : - Template structuré selon grille CAI - Analyse des 8 axes Loi 25 - Mesures d'atténuation #### 4.4 Dashboard conformité Étendre `get_metrics` tool (existant) : - Ajoute une section `loi25` : consentements actifs, incidents ouverts, rétention à venir, transferts des dernières 24h --- ## 5. Nouveaux fichiers à créer ``` src/ ├── lib/ │ └── loi25/ │ ├── guard.ts # Middleware Privacy Guard │ ├── anonymize.ts # Fonctions d'anonymisation │ ├── transfer_map.ts # Registre des providers/transferts │ ├── retention.ts # Moteur de rétention │ └── types.ts # Types AuditContext, etc. ├── tools/ │ ├── audit_access_request.ts │ ├── audit_rectification.ts │ ├── audit_erasure.ts │ ├── audit_consent.ts │ ├── audit_processing_registry.ts │ ├── audit_report_incident.ts │ └── audit_efvp.ts scripts/ ├── audit_migration.mjs # Schema migration ├── audit_backfill.mjs # Migration des données legacy └── audit_retention_cron.mjs # Cron de purge/anonymisation docs/ ├── PRIVACY_POLICY.json # Politique machine-readable ├── EFVP_OVERMIND.md # Évaluation facteurs vie privée └── PLAN_AUDIT_INTEGRATION.md # Ce document ``` ## 6. Fichiers à modifier | Fichier | Modification | |---|---| | `src/memory/PostgresMemoryProvider.ts` | + colonnes governance, + 7 nouvelles tables | | `src/memory/types.ts` | + types Audit (ConsentRecord, IncidentLog, etc.) | | `src/server.ts` | + enregistrement 7 nouveaux outils Loi 25 | | `src/bridge/OverBridgeService.ts` | + capture consentement + data_subject_id | | `src/services/*Runner.ts` (8 fichiers) | + hook transfer_log | | `src/tools/get_metrics.ts` | + section conformité Loi 25 | | `package.json` | bump 3.9.0 + bin `overmind-loi25-migrate` | | `.env.example` | + flags `OVERMIND_DATA_RESIDENCY`, `OVERMIND_PII_FILTER` | ## 7. Estimation effort | Phase | Fichiers | LOC estimé | Tests | |---|---|---|---| | 1 — Fondations | 12 | ~1500 | 10 tests | | 2 — Privacy Guard | 12 | ~1200 | 8 tests | | 3 — Lifecycle | 4 | ~600 | 5 tests | | 4 — Transparence | 5 | ~400 | 3 tests | | **Total** | **33** | **~3700** | **26 tests** | ## 8. Risques 1. **Rétrocompatibilité** : les colonnes ajoutées sont nullable → pas de cassure 2. **Performance** : le guard ajoute ~5ms par requête (regex PII + log) — négligeable 3. **Providers CN** (zai/kimi/minimax-cn) : transferts Chine = mécanisme `explicit_consent` obligatoire → bloquant si pas de consentement explicite 4. **Embeddings legacy** : les `knowledge_chunks` existants n'ont pas de `data_subject_id` → backfill best-effort + anonymisation conservative ## 9. Tests de conformité (critères d'acceptation) - ✅ `audit_access_request(data_subject_id)` retourne tous les RP en <2s - ✅ `audit_erasure(data_subject_id)` supprime/hash tous les RP + embeddings - ✅ Chaque `agent_run` stocké a un `legal_basis` + `retention_expires_at` - ✅ Chaque appel runner LLM génère une entrée `transfer_log` - ✅ Cron de rétention purge les enregistrements expirés sans erreur - ✅ `get_metrics` affiche le taux de conformité (consentements actifs / incidents) - ✅ Anonymisation : un RP effacé ne peut pas être ré-identifié via embeddings ## 10. Décisions de périmètre (validées 21 juillet 2026) | Question | Décision | Impact | |---|---|---| | **Périmètre RP** | Mixte — consentement explicite (tiers) + intérêt légitime (interne) | Guard détecte l'origine automatiquement, allowlist `.env` | | **Transferts hors QC** | Documentation seule, aucun blocage | `transfer_log` + cartographie, mais tous les providers restent accessibles | | **Rétention** | 30 jours active + 5 ans archivage cold storage | Double table `archived_*`, cron anonymise → archive → purge | | **Activation** | Feature flag `OVERMIND_AUDIT_ENABLED=true` | Désactivé = comportement v3.8 inchangé (rétrocompatible) | --- ## 11. Ordre d'exécution recommandé ``` Étape 1 → scripts/audit_migration.mjs (schema) Étape 2 → src/lib/audit/types.ts + guard.ts + transfer_map.ts Étape 3 → src/tools/audit_*.ts (7 outils) Étape 4 → src/server.ts (enregistrement outils) Étape 5 → Hooks runners (8 fichiers) Étape 6 → Bridge capture consentement Étape 7 → scripts/audit_retention_cron.mjs Étape 8 → scripts/audit_backfill.mjs (migration legacy) Étape 9 → Tests + docs Étape 10 → Bump version 3.9.0 + changeset ``` **Prêt à coder quand tu dis go.**