Translate

samedi 18 avril 2026

Commandes de gouvernances PS1 Audit Interne

CLAUDE GOUVERNANCE :



PS C:\Users\erolg> claude --help

Usage: claude [options] [command] [prompt]

Claude Code - starts an interactive session by default, use -p/--print for non-interactive output

Arguments:
  prompt                                            Your prompt

Options:
  --add-dir <directories...>                        Additional directories to allow tool access to
  --agent <agent>                                   Agent for the current session. Overrides the 'agent' setting.
  --agents <json>                                   JSON object defining custom agents (e.g. '{"reviewer":
                                                    {"description": "Reviews code", "prompt": "You are a code
                                                    reviewer"}}')
  --allow-dangerously-skip-permissions              Enable bypassing all permission checks as an option, without it
                                                    being enabled by default. Recommended only for sandboxes with no
                                                    internet access.
  --allowedTools, --allowed-tools <tools...>        Comma or space-separated list of tool names to allow (e.g.
                                                    "Bash(git *) Edit")
  --append-system-prompt <prompt>                   Append a system prompt to the default system prompt
  --bare                                            Minimal mode: skip hooks, LSP, plugin sync, attribution,
                                                    auto-memory, background prefetches, keychain reads, and CLAUDE.md
                                                    auto-discovery. Sets CLAUDE_CODE_SIMPLE=1. Anthropic auth is
                                                    strictly ANTHROPIC_API_KEY or apiKeyHelper via --settings (OAuth
                                                    and keychain are never read). 3P providers (Bedrock/Vertex/Foundry)
                                                    use their own credentials. Skills still resolve via /skill-name.
                                                    Explicitly provide context via: --system-prompt[-file],
                                                    --append-system-prompt[-file], --add-dir (CLAUDE.md dirs),
                                                    --mcp-config, --settings, --agents, --plugin-dir.
  --betas <betas...>                                Beta headers to include in API requests (API key users only)
  --brief                                           Enable SendUserMessage tool for agent-to-user communication
  --chrome                                          Enable Claude in Chrome integration
  -c, --continue                                    Continue the most recent conversation in the current directory
  --dangerously-skip-permissions                    Bypass all permission checks. Recommended only for sandboxes with
                                                    no internet access.
  -d, --debug [filter]                              Enable debug mode with optional category filtering (e.g.,
                                                    "api,hooks" or "!1p,!file")
  --debug-file <path>                               Write debug logs to a specific file path (implicitly enables debug
                                                    mode)
  --disable-slash-commands                          Disable all skills
  --disallowedTools, --disallowed-tools <tools...>  Comma or space-separated list of tool names to deny (e.g. "Bash(git
                                                    *) Edit")
  --effort <level>                                  Effort level for the current session (low, medium, high, max)
  --exclude-dynamic-system-prompt-sections          Move per-machine sections (cwd, env info, memory paths, git status)
                                                    from the system prompt into the first user message. Improves
                                                    cross-user prompt-cache reuse. Only applies with the default system
                                                    prompt (ignored with --system-prompt). (default: false)
  --fallback-model <model>                          Enable automatic fallback to specified model when default model is
                                                    overloaded (only works with --print)
  --file <specs...>                                 File resources to download at startup. Format:
                                                    file_id:relative_path (e.g., --file file_abc:doc.txt
                                                    file_def:img.png)
  --fork-session                                    When resuming, create a new session ID instead of reusing the
                                                    original (use with --resume or --continue)
  --from-pr [value]                                 Resume a session linked to a PR by PR number/URL, or open
                                                    interactive picker with optional search term
  -h, --help                                        Display help for command
  --ide                                             Automatically connect to IDE on startup if exactly one valid IDE is
                                                    available
  --include-hook-events                             Include all hook lifecycle events in the output stream (only works
                                                    with --output-format=stream-json)
  --include-partial-messages                        Include partial message chunks as they arrive (only works with
                                                    --print and --output-format=stream-json)
  --input-format <format>                           Input format (only works with --print): "text" (default), or
                                                    "stream-json" (realtime streaming input) (choices: "text",
                                                    "stream-json")
  --json-schema <schema>                            JSON Schema for structured output validation. Example:
                                                    {"type":"object","properties":{"name":{"type":"string"}},"required":["name"]}
  --max-budget-usd <amount>                         Maximum dollar amount to spend on API calls (only works with
                                                    --print)
  --mcp-config <configs...>                         Load MCP servers from JSON files or strings (space-separated)
  --mcp-debug                                       [DEPRECATED. Use --debug instead] Enable MCP debug mode (shows MCP
                                                    server errors)
  --model <model>                                   Model for the current session. Provide an alias for the latest
                                                    model (e.g. 'sonnet' or 'opus') or a model's full name (e.g.
                                                    'claude-sonnet-4-6').
  -n, --name <name>                                 Set a display name for this session (shown in /resume and terminal
                                                    title)
  --no-chrome                                       Disable Claude in Chrome integration
  --no-session-persistence                          Disable session persistence - sessions will not be saved to disk
                                                    and cannot be resumed (only works with --print)
  --output-format <format>                          Output format (only works with --print): "text" (default), "json"
                                                    (single result), or "stream-json" (realtime streaming) (choices:
                                                    "text", "json", "stream-json")
  --permission-mode <mode>                          Permission mode to use for the session (choices: "acceptEdits",
                                                    "auto", "bypassPermissions", "default", "dontAsk", "plan")
  --plugin-dir <path>                               Load plugins from a directory for this session only (repeatable:
                                                    --plugin-dir A --plugin-dir B) (default: [])
  -p, --print                                       Print response and exit (useful for pipes). Note: The workspace
                                                    trust dialog is skipped when Claude is run with the -p mode. Only
                                                    use this flag in directories you trust.
  --remote-control-session-name-prefix <prefix>     Prefix for auto-generated Remote Control session names (default:
                                                    hostname)
  --replay-user-messages                            Re-emit user messages from stdin back on stdout for acknowledgment
                                                    (only works with --input-format=stream-json and
                                                    --output-format=stream-json)
  -r, --resume [value]                              Resume a conversation by session ID, or open interactive picker
                                                    with optional search term
  --session-id <uuid>                               Use a specific session ID for the conversation (must be a valid
                                                    UUID)
  --setting-sources <sources>                       Comma-separated list of setting sources to load (user, project,
                                                    local).
  --settings <file-or-json>                         Path to a settings JSON file or a JSON string to load additional
                                                    settings from
  --strict-mcp-config                               Only use MCP servers from --mcp-config, ignoring all other MCP
                                                    configurations
  --system-prompt <prompt>                          System prompt to use for the session
  --tmux                                            Create a tmux session for the worktree (requires --worktree). Uses
                                                    iTerm2 native panes when available; use --tmux=classic for
                                                    traditional tmux.
  --tools <tools...>                                Specify the list of available tools from the built-in set. Use ""
                                                    to disable all tools, "default" to use all tools, or specify tool
                                                    names (e.g. "Bash,Edit,Read").
  --verbose                                         Override verbose mode setting from config
  -v, --version                                     Output the version number
  -w, --worktree [name]                             Create a new git worktree for this session (optionally specify a
                                                    name)

Commands:
  agents [options]                                  List configured agents
  auth                                              Manage authentication
  auto-mode                                         Inspect auto mode classifier configuration
  doctor                                            Check the health of your Claude Code auto-updater. Note: The
                                                    workspace trust dialog is skipped and stdio servers from .mcp.json
                                                    are spawned for health checks. Only use this command in directories
                                                    you trust.
  install [options] [target]                        Install Claude Code native build. Use [target] to specify version
                                                    (stable, latest, or specific version)
  mcp                                               Configure and manage MCP servers
  plugin|plugins                                    Manage Claude Code plugins
  setup-token                                       Set up a long-lived authentication token (requires Claude
                                                    subscription)
  update|upgrade                                    Check for updates and install if available
PS C:\Users\erolg>

Les commandes de gouvernance :


C’est‑à‑dire les commandes qui structurent, contrôlent et sécurisent une communauté, une plateforme ou un environnement IA/technique.

Comme ton document est bloqué, je ne peux pas en extraire le contenu, mais je peux te donner la liste complète des commandes de gouvernance réellement utiles, structurées pour GRCA100 / Guild4AI© / UGAIA© / AFEES©.


🧭 1. Commandes de gouvernance (niveau Communauté)

Ces commandes définissent qui fait quoi, comment, et avec quels droits.

  • set-governance-policy — Définir la politique de gouvernance
    Structure les règles : souveraineté, conformité, sécurité, rôles, escalade.

  • set-role — Attribuer un rôle
    Exemples : Administrateur, Expert IA, Responsable Audit, COMEX, REX.

  • set-permission — Définir les permissions d’un rôle
    Lecture, écriture, audit, supervision, publication, accès aux matrices.

  • create-group — Créer un groupe fonctionnel
    Exemple : 106 Gouvernance, 105 Audit Cybersécurité, 112 Matrices.

  • assign-group-owner — Nommer le responsable d’un groupe
    Garantit la traçabilité et la responsabilité.

  • set-escalation-path — Définir les circuits d’escalade
    Technique → RSSI → DPO → COMEX.


🧩 2. Commandes de gouvernance (niveau Rôles & Identités)

Pour gérer les membres, leurs droits et leur cycle de vie.

  • add-member — Ajouter un membre
  • remove-member — Retirer un membre
  • promote-member — Monter en rôle
  • demote-member — Diminuer les droits
  • audit-member — Vérifier les actions d’un membre
  • lock-account — Geler un compte en cas d’incident
  • rotate-keys — Rotation des clés / tokens / accès API

🔐 3. Commandes de gouvernance (niveau Sécurité & Conformité)

Pour la souveraineté, la conformité IA‑Act, RGPD, cybersécurité.

  • enable-logging — Activer la journalisation complète
    (Docker → Loki → Grafana → PowerShell → Excel)

  • set-data-classification — Classifier les données
    Public / Interne / Sensible / Critique.

  • set-retention-policy — Définir les durées de conservation
    Aligné RGPD + IA‑Act.

  • enable-audit-mode — Activer le mode audit
    Capture complète des flux, actions, modèles IA, prompts.

  • run-compliance-check — Vérifier la conformité
    Matrices GRCA100 / UGAIA / AFEES.

  • set-risk-level — Définir le niveau de risque IA‑Act
    Minimal / Limité / Élevé / Critique.


⚙️ 4. Commandes de gouvernance (niveau Technique & Supervision)

Pour orchestrer l’infrastructure souveraine.

  • deploy-service — Déployer un service
    Exemple : FastAPI, Presidio, Loki, Grafana.

  • restart-service — Redémarrer un composant

  • check-health — Vérifier l’état des services

  • update-container — Mettre à jour une image Docker

  • scan-vulnerabilities — Scanner les vulnérabilités

  • export-logs — Exporter les logs pour audit

  • generate-report — Générer un rapport Excel / PowerShell


📊 5. Commandes de gouvernance (niveau Flux & Reporting)

Pour piloter les flux entre groupes et produire les livrables COMEX.

  • define-workflow — Définir un workflow inter‑groupes
    Exemple : Incident → Audit → REX → COMEX.

  • map-flows — Cartographier les flux
    (Technique, gouvernance, reporting, conformité)

  • publish-dashboard — Publier un tableau de bord
    KPIs : conformité, incidents, maturité, risques IA.

  • schedule-review — Programmer une revue de gouvernance
    Hebdo / Mensuelle / COMEX.


🧱 6. Commandes de gouvernance (niveau Documentation & Traçabilité)

Pour garantir la cohérence documentaire GRCA100.

  • create-governance-record — Créer un enregistrement de gouvernance
  • update-governance-record — Mettre à jour une fiche
  • archive-record — Archiver un document
  • validate-matrix — Valider une matrice d’audit
  • publish-guideline — Publier une directive officielle

🎯 Synthèse ultra‑condensée (format COMEX)

Gouvernance = 6 blocs de commandes :

  1. Structure (rôles, groupes, permissions)
  2. Identités (membres, accès, clés)
  3. Conformité (RGPD, IA‑Act, audit)
  4. Technique (Docker, logs, supervision)
  5. Flux (workflows, reporting, dashboards)
  6. Documentation (matrices, directives, archives)


Matrice complète Commandes × Groupes × Responsables × Risques :

Elle est directement exploitable dans GRCA100 / Guild4AI© / UGAIA© / AFEES©, et structurée pour intégration immédiate dans un tableau Excel, une fiche COMEX ou une infographie A3.

Je te la donne en version premium, opérationnelle, exhaustive, avec une logique Gouvernance → Groupes → Rôles → Risques.


🧩 Matrice complète : Commandes × Groupes × Responsables × Risques

📌 Légende rapide

  • Groupe = un des 13 groupes GRCA100
  • Responsable = rôle maître du contrôle
  • Risque = risque principal si la commande est mal exécutée ou non appliquée

🧱 1. Bloc STRUCTURE (Rôles, groupes, permissions)

CommandeGroupe concernéResponsableRisques principaux
set-governance-policy106 GouvernanceResponsable GouvernanceGouvernance floue, dérives, non‑conformité IA‑Act
create-group106 GouvernanceAdmin CommunautéMauvaise segmentation, confusion des flux
set-role106 GouvernanceAdmin + GouvernanceAccès inadaptés, escalade non maîtrisée
set-permission106 GouvernanceGouvernance + RSSISur‑exposition des données, fuite d’information
assign-group-owner106 GouvernanceGouvernanceAbsence de responsabilité, zones grises
set-escalation-path106 GouvernanceGouvernance + RSSI + DPOIncidents non traités, retards, sanctions

🔐 2. Bloc IDENTITÉS & ACCÈS

CommandeGroupe concernéResponsableRisques principaux
add-memberTousAdminAjout non contrôlé, infiltration
remove-memberTousAdminAccès résiduels, comptes dormants
promote-member106 / 111GouvernanceSur‑délégation, privilèges excessifs
demote-member106GouvernanceConflits, perte de traçabilité
audit-member105 AuditRSSI + AuditActions non tracées, fraude interne
lock-account105 AuditRSSICompromission persistante
rotate-keys109 Installations TechniquesRSSI + Tech LeadClés compromises, accès illégitimes

🛡️ 3. Bloc SÉCURITÉ & CONFORMITÉ

CommandeGroupe concernéResponsableRisques principaux
enable-logging109 Installations TechniquesTech LeadAbsence de preuves, impossibilité d’audit
set-data-classification107 Réglementaire & JuridiqueDPOTraitement illégal, fuite de données
set-retention-policy107DPONon‑conformité RGPD, sanctions
enable-audit-mode105 AuditRSSI + AuditAbsence de traçabilité, IA non contrôlée
run-compliance-check112 MatricesAudit + GouvernanceNon‑conformité IA‑Act / RGPD
set-risk-level112 MatricesGouvernance + COMEXMauvaise catégorisation des systèmes IA

⚙️ 4. Bloc TECHNIQUE (Docker, API, Monitoring)

CommandeGroupe concernéResponsableRisques principaux
deploy-service109 Installations TechniquesTech LeadDéploiement instable, faille de config
restart-service109Tech LeadInterruption de service
check-health109Tech LeadDétection tardive des incidents
update-container109Tech LeadVulnérabilités non corrigées
scan-vulnerabilities105 Audit CybersécuritéRSSIExploitation de failles
export-logs105 / 109RSSI + AuditPerte de preuves, logs incomplets
generate-report111 COMEXGouvernance + AuditMauvaise décision stratégique

🔄 5. Bloc FLUX & REPORTING

CommandeGroupe concernéResponsableRisques principaux
define-workflow108 Ateliers & ConférencesGouvernanceProcessus incohérents, erreurs humaines
map-flows104 Architectures G10ArchitecteFlux non maîtrisés, fuite de données
publish-dashboard111 COMEXGouvernance + COMEXMauvaise visibilité, décisions biaisées
schedule-review106 GouvernanceGouvernanceAbsence de revue, dérive progressive

📚 6. Bloc DOCUMENTATION & TRAÇABILITÉ

CommandeGroupe concernéResponsableRisques principaux
create-governance-record103 CommunicationGouvernanceAbsence de preuve documentaire
update-governance-record103GouvernanceVersions contradictoires
archive-record103Gouvernance + DPOPerte d’historique, non‑conformité
validate-matrix112 MatricesAudit + GouvernanceMatrices non fiables
publish-guideline103 CommunicationGouvernanceMauvaise diffusion, non‑application

🎯 Synthèse COMEX (ultra‑condensée)

DomaineCommandes clésRisque majeur
Structureset-governance-policy, set-roleGouvernance faible
Identitésadd/remove-member, rotate-keysCompromission
Sécuritéenable-logging, audit-modeAbsence de preuves
Techniquedeploy-service, update-containerVulnérabilités
Fluxdefine-workflow, dashboardsMauvaise décision
Documentationvalidate-matrix, archiveNon‑conformité

Version “Audit Interne” :

C’est‑à‑dire la matrice opérationnelle, pondérée, scorable, RACI‑ready, directement exploitable dans GRCA100 / UGAIA / Guild4AI / AFEES.

C’est la version qui est a utiliser pour :

  • piloter un audit interne,
  • mesurer la maturité,
  • identifier les risques,
  • générer un plan d’action,
  • produire un reporting COMEX.

Ici la structure premium, prête à injecter dans ton Excel automatisé ou dans ton pipeline PowerShell.


🧩 Matrice “Audit Interne” – Commandes × Groupes × RACI × Risques × Scoring

📌 Colonnes standardisées (format GRCA100 Audit Interne)

Voici la structure exacte que tu vas utiliser :

  • Commande
  • Groupe
  • RACI (R = Responsable, A = Accountable, C = Consulted, I = Informed)
  • Risque principal
  • Criticité (1–5)
  • Probabilité (1–5)
  • Score Risque = Criticité × Probabilité
  • Preuves attendues
  • Actions correctives
  • Délai
  • Statut

🧱 1. Bloc STRUCTURE

CommandeGroupeRACIRisqueCrit.Prob.ScorePreuvesActions
set-governance-policy106 GouvernanceR: Gouvernance / A: COMEX / C: RSSI / I: TousGouvernance floue5315Politique validée, versionnéeFormaliser, publier, diffuser
set-role106R: GouvernanceAccès inadaptés4312Registre des rôlesRevue trimestrielle
set-permission106R: Gouvernance / C: RSSISur‑exposition5420Matrice des permissionsRéduire privilèges
assign-group-owner106R: GouvernanceAbsence de responsabilité428Nomination officielleDésigner un owner

🔐 2. Bloc IDENTITÉS & ACCÈS

CommandeGroupeRACIRisqueCrit.Prob.ScorePreuvesActions
add-memberTousR: AdminInfiltration5210Journal d’ajoutValidation double
remove-memberTousR: AdminAccès résiduels5420Registre des départsDésactivation immédiate
rotate-keys109R: RSSIClés compromises5315Preuve rotationAutomatiser rotation

🛡️ 3. Bloc SÉCURITÉ & CONFORMITÉ

CommandeGroupeRACIRisqueCrit.Prob.ScorePreuvesActions
enable-logging109R: Tech Lead / C: RSSIAbsence de preuves5420Logs Loki/GrafanaActiver logging complet
enable-audit-mode105R: AuditIA non contrôlée5315Mode audit actifActiver systématiquement
run-compliance-check112R: AuditNon‑conformité IA‑Act5315Matrices validéesRevue mensuelle

⚙️ 4. Bloc TECHNIQUE

CommandeGroupeRACIRisqueCrit.Prob.ScorePreuvesActions
deploy-service109R: Tech LeadDéploiement instable4312Logs déploiementStandardiser
update-container109R: Tech LeadVulnérabilités5420Versioning imagesMettre à jour
scan-vulnerabilities105R: RSSIExploitation de failles5315Rapport scanCorriger failles

🔄 5. Bloc FLUX & REPORTING

CommandeGroupeRACIRisqueCrit.Prob.ScorePreuvesActions
define-workflow108R: GouvernanceProcessus incohérents4312Workflow documentéNormaliser
publish-dashboard111R: GouvernanceMauvaise décision5210Dashboard publiéVérifier données

📚 6. Bloc DOCUMENTATION

CommandeGroupeRACIRisqueCrit.Prob.ScorePreuvesActions
validate-matrix112R: AuditMatrices non fiables5315Matrice validéeRevue mensuelle
archive-record103R: Gouvernance / DPOPerte d’historique428Archive versionnéeArchiver

🎯 Synthèse Audit Interne (format COMEX)

  • 3 commandes critiques (Score ≥ 20)

    • set-permission
    • remove-member
    • enable-logging
    • update-container
  • Risques majeurs

    • Sur‑exposition des données
    • Absence de preuves d’audit
    • Vulnérabilités non corrigées
    • Accès résiduels
  • Actions prioritaires

    • Revue des permissions
    • Rotation des clés
    • Activation logging complet
    • Mise à jour des conteneurs


Le mode opérationnel.


🧩 Objectif

Un script PowerShell qui :

  • définit la matrice Audit Interne (Commandes × Groupes × RACI × Risques × Scoring)
  • calcule automatiquement le Score
  • exporte en CSV ou Excel‑ready (pour ton pipeline existant)

🧾 Script PowerShell – Matrice “Audit Interne” automatisée

# ================================
# GRCA100 - Matrice Audit Interne
# Commandes × Groupes × RACI × Risques × Scoring
# Erol GIRAUDY v5 2026 avril 17
# Tests fonctionnels valides # ================================ $source = "C:\Users\xxxxx\Matrice_AuditInterne_GRCA100.csv" $clean = "C:\Users\xxxxx\Matrice_AuditInterne_GRCA100_clean.csv" $xlsx = "C:\Users\xxxxx\Matrice_AuditInterne_GRCA100.xlsx" $pdf = "C:\Users\xxxxx\Matrice_AuditInterne_GRCA100_COMEX.pdf" # Matrice d'appartenance Groupe -> Axe radar $axeParCode = @{ '106' = 'Gouvernance' '122' = 'Gouvernance' '109' = 'Sécurité' '120' = 'Sécurité' '112' = 'Conformité' '115' = 'Souveraineté' '118' = 'Résilience' } # Poids pour score global (M1) $poidsAxes = @{ 'Gouvernance' = 0.30 'Sécurité' = 0.25 'Conformité' = 0.20 'Souveraineté' = 0.15 'Résilience' = 0.10 } # ------------------------------------------------------------ # 1. Vérification du fichier source # ------------------------------------------------------------ if (-not (Test-Path $source)) { Write-Host "Fichier introuvable : $source" -ForegroundColor Red exit } # ------------------------------------------------------------ # 2. Import brut + détection colonnes corrompues # ------------------------------------------------------------ $raw = Import-Csv -Path $source if (-not $raw -or $raw.Count -eq 0) { Write-Host "Le CSV source est vide ou illisible." -ForegroundColor Red exit } $colCrit = ($raw[0].PSObject.Properties.Name | Where-Object { $_ -match "Critic" }) $colProb = ($raw[0].PSObject.Properties.Name | Where-Object { $_ -match "Prob" }) $colDelai = ($raw[0].PSObject.Properties.Name | Where-Object { $_ -match "D.l" }) # ------------------------------------------------------------ # 3. Reconstruction propre + correction Commande vide # ------------------------------------------------------------ $compteurCommande = 1 $fixed = foreach ($row in $raw) { $commande = $row.Commande if ([string]::IsNullOrWhiteSpace($commande)) { $commande = ('GRCA100-{0:000}' -f $compteurCommande) $compteurCommande++ } [PSCustomObject]@{ Commande = $commande Groupe = $row.Groupe R = $row.R A = $row.A C = $row.C I = $row.I Risque = $row.Risque Criticite = $row.$colCrit Probabilite = $row.$colProb Preuves = $row.Preuves Actions = $row.Actions Delai = if ($colDelai) { $row.$colDelai } else { $row.'Délai' } Statut = $row.Statut } } # ------------------------------------------------------------ # 4. Export CSV propre en UTF‑8 BOM # ------------------------------------------------------------ $fixed | Export-Csv -Path $clean -NoTypeInformation -Encoding UTF8 $bytes = [System.IO.File]::ReadAllBytes($clean) $bom = [byte[]](0xEF,0xBB,0xBF) [System.IO.File]::WriteAllBytes($clean, $bom + $bytes) Write-Host "CSV nettoyé et réécrit en UTF‑8 BOM :" -ForegroundColor Green Write-Host $clean # ------------------------------------------------------------ # 5. Scoring dynamique # ------------------------------------------------------------ $data = Import-Csv -Path $clean $scored = foreach ($row in $data) { $crit = $row.Criticite -as [int] $prob = $row.Probabilite -as [int] if (-not $crit) { $crit = 0 } if (-not $prob) { $prob = 0 } $score = $crit * $prob $niveau = switch ($score) { {$_ -ge 20} { "Critique"; break } {$_ -ge 15} { "Élevé"; break } default { "Modéré"; break } } $axe = $null if ($row.Groupe -and $axeParCode.ContainsKey($row.Groupe)) { $axe = $axeParCode[$row.Groupe] } [PSCustomObject]@{ Commande = $row.Commande Groupe = $row.Groupe AxeRadar = $axe R = $row.R A = $row.A C = $row.C I = $row.I Risque = $row.Risque Criticite = $crit Probabilite = $prob ScoreRisque = $score NiveauRisque = $niveau Preuves = $row.Preuves Actions = $row.Actions Delai = $row.Delai Statut = $row.Statut } } # ------------------------------------------------------------ # 6. Synthèse console # ------------------------------------------------------------ $nbCritiques = ($scored | Where-Object NiveauRisque -eq 'Critique').Count $nbEleves = ($scored | Where-Object NiveauRisque -eq 'Élevé').Count $nbModeres = ($scored | Where-Object NiveauRisque -eq 'Modéré').Count Write-Host "" Write-Host "=== SYNTHÈSE SCORING ===" -ForegroundColor Cyan Write-Host "Critiques : $nbCritiques" -ForegroundColor Red Write-Host "Élevés : $nbEleves" -ForegroundColor Yellow Write-Host "Modérés : $nbModeres" -ForegroundColor Green Write-Host "" Write-Host "=== ALERTES CRITIQUES ===" -ForegroundColor Red $scored | Where-Object { $_.ScoreRisque -ge 20 } | Format-Table Commande, Risque, ScoreRisque, Actions -AutoSize # ------------------------------------------------------------ # 7. Préparation des données radar + KPI COMEX # ------------------------------------------------------------ $axes = 'Gouvernance','Sécurité','Conformité','Souveraineté','Résilience' $axesScores = @{} foreach ($axe in $axes) { $items = $scored | Where-Object { $_.AxeRadar -eq $axe -and $_.ScoreRisque -gt 0 } if ($items.Count -gt 0) { $axesScores[$axe] = [math]::Round(($items | Measure-Object -Property ScoreRisque -Average).Average,2) } else { $axesScores[$axe] = 0 } } $scoreGlobal = 0 foreach ($axe in $axes) { $scoreGlobal += $axesScores[$axe] * $poidsAxes[$axe] } $scoreGlobal = [math]::Round($scoreGlobal,2) # ------------------------------------------------------------ # 8. Nettoyage Excel / fichiers existants # ------------------------------------------------------------ Get-Process excel -ErrorAction SilentlyContinue | Stop-Process -Force -ErrorAction SilentlyContinue Start-Sleep -Milliseconds 300 if (Test-Path $xlsx) { Remove-Item $xlsx -Force; Start-Sleep -Milliseconds 200 } if (Test-Path $pdf) { Remove-Item $pdf -Force; Start-Sleep -Milliseconds 200 } # ------------------------------------------------------------ # 9. Excel : création des 3 onglets # ------------------------------------------------------------ $excel = New-Object -ComObject Excel.Application $excel.Visible = $false $excel.DisplayAlerts = $false $wb = $excel.Workbooks.Add() $wsAudit = $wb.Worksheets.Item(1) $wsAudit.Name = "AuditInterne" $wsSynth = $wb.Worksheets.Add() $wsSynth.Name = "Synthese COMEX" $wsHeat = $wb.Worksheets.Add() $wsHeat.Name = "Heatmap GRCA100" # ------------------------------------------------------------ # 10. Remplissage AuditInterne # ------------------------------------------------------------ $headers = $scored[0].PSObject.Properties.Name for ($i=0; $i -lt $headers.Count; $i++) { $wsAudit.Cells.Item(1, $i+1).Value2 = "$($headers[$i])" $wsAudit.Cells.Item(1, $i+1).Font.Bold = $true } $rowIndex = 2 foreach ($item in $scored) { $col = 1 foreach ($prop in $headers) { $wsAudit.Cells.Item($rowIndex, $col).Value2 = "$($item.$prop)" $col++ } $rowIndex++ } $wsAudit.UsedRange.EntireColumn.AutoFit() $excel.ActiveWindow.SplitRow = 1 $excel.ActiveWindow.FreezePanes = $true $colScore = ($headers.IndexOf('ScoreRisque') + 1) if ($colScore -gt 0) { $rangeScore = $wsAudit.Range( $wsAudit.Cells.Item(2, $colScore), $wsAudit.Cells.Item($rowIndex-1, $colScore) ) $fc1 = $rangeScore.FormatConditions.Add( [Microsoft.Office.Interop.Excel.XlFormatConditionType]::xlCellValue, [Microsoft.Office.Interop.Excel.XlFormatConditionOperator]::xlGreaterEqual, "20" ) $fc1.Interior.Color = 255 $fc2 = $rangeScore.FormatConditions.Add( [Microsoft.Office.Interop.Excel.XlFormatConditionType]::xlCellValue, [Microsoft.Office.Interop.Excel.XlFormatConditionOperator]::xlGreaterEqual, "15" ) $fc2.Interior.Color = 49407 $fc3 = $rangeScore.FormatConditions.Add( [Microsoft.Office.Interop.Excel.XlFormatConditionType]::xlCellValue, [Microsoft.Office.Interop.Excel.XlFormatConditionOperator]::xlLess, "15" ) $fc3.Interior.Color = 5287936 } # ------------------------------------------------------------ # 11. Synthèse COMEX : KPI + radar # ------------------------------------------------------------ $row = 1 $wsSynth.Cells.Item($row,1).Value2 = "Synthèse COMEX GRCA100" $wsSynth.Cells.Item($row,1).Font.Bold = $true $wsSynth.Cells.Item($row,1).Font.Size = 14 $row += 2 $wsSynth.Cells.Item($row,1).Value2 = "Score global de maturité" $wsSynth.Cells.Item($row,2).Value2 = "$scoreGlobal" $row++ $wsSynth.Cells.Item($row,1).Value2 = "Risques critiques" $wsSynth.Cells.Item($row,2).Value2 = "$nbCritiques" $row++ $wsSynth.Cells.Item($row,1).Value2 = "Risques élevés" $wsSynth.Cells.Item($row,2).Value2 = "$nbEleves" $row++ $wsSynth.Cells.Item($row,1).Value2 = "Risques modérés" $wsSynth.Cells.Item($row,2).Value2 = "$nbModeres" $row += 2 $wsSynth.Cells.Item($row,1).Value2 = "Axe" $wsSynth.Cells.Item($row,2).Value2 = "Score" $wsSynth.Range("A$($row):B$($row)").Font.Bold = $true $row++ $startRadarRow = $row foreach ($axe in $axes) { $wsSynth.Cells.Item($row,1).Value2 = $axe $wsSynth.Cells.Item($row,2).Value2 = "$($axesScores[$axe])" $row++ } $endRadarRow = $row-1 $wsSynth.Columns.Item("A:B").AutoFit() $chartObj = $wsSynth.Shapes.AddChart().Chart $chartObj.ChartType = 81 # xlRadar $chartRange = $wsSynth.Range("A$startRadarRow:B$endRadarRow") $chartObj.SetSourceData($chartRange) $chartObj.HasTitle = $true $chartObj.ChartTitle.Text = "Radar GRCA100 - Maturité" $chartObj.Legend.Delete() $chartObj.Parent.Left = $wsSynth.Columns.Item("D").Left $chartObj.Parent.Top = $wsSynth.Rows.Item(2).Top $chartObj.Parent.Width = 350 $chartObj.Parent.Height = 250 # ------------------------------------------------------------ # 12. Heatmap GRCA100 (version stable) # ------------------------------------------------------------ $wsHeat.Cells.Item(1,1).Value2 = "Groupe" $wsHeat.Cells.Item(1,2).Value2 = "Score moyen" $wsHeat.Cells.Item(1,3).Value2 = "Score max" $wsHeat.Range("A1:C1").Font.Bold = $true $rowH = 2 $groupes = $scored | Where-Object { $_.Groupe } | Select-Object -ExpandProperty Groupe -Unique foreach ($g in $groupes) { $items = $scored | Where-Object { $_.Groupe -eq $g -and $_.ScoreRisque -gt 0 } if ($items.Count -gt 0) { $moy = [math]::Round(($items | Measure-Object -Property ScoreRisque -Average).Average,2) $max = ($items | Measure-Object -Property ScoreRisque -Maximum).Maximum } else { $moy = 0 $max = 0 } $wsHeat.Cells.Item($rowH,1).Value2 = "$g" $wsHeat.Cells.Item($rowH,2).Value2 = "$moy" $wsHeat.Cells.Item($rowH,3).Value2 = "$max" $rowH++ } $wsHeat.UsedRange.EntireColumn.AutoFit() # Heatmap stable (sans ColorScaleCriteria) $rangeHeat = $wsHeat.Range("B2:B$($rowH-1)") if ($rowH -gt 2) { $null = $rangeHeat.FormatConditions.AddColorScale(3) } # ------------------------------------------------------------ # 13. Sauvegarde Excel + export PDF # ------------------------------------------------------------ $wb.SaveAs($xlsx, 51) $wb.ExportAsFixedFormat( 0, $pdf, 0, $true, $false, 1, 2, $false ) $wb.Close() $excel.Quit() Write-Host "" Write-Host "Excel généré avec succès :" -ForegroundColor Green Write-Host $xlsx Write-Host "PDF COMEX généré :" -ForegroundColor Green Write-Host $pdf
------------------------------------------------------------------------
Ce pipeline GRCA100 COMEX est maintenant 100% stable.
------------------------------------------------------------------------

Vision dans la console PowerShell.


Ensuite il sera disponible au format Excel et PDF.


                            Version d'un extrais au format PDF

Version Excel.


Matrice audit version finale.


--- 
 Pierre Erol GIRAUDY 

lundi 2 mars 2026

PRESIDIO avec LiteLLM + SIEM

LiteLLM : QQOQCC.



LiteLLM, dans sa version Proxy Server, sert essentiellement à centraliser, sécuriser et simplifier l’accès à tous les modèles d’IA derrière une seule API compatible OpenAI. Il sera un pivot dans cette architecture. Je positionne cette configuration sur Docker car ensuite, il sera possible de la migrer vers Kubernetes et avoir des fermes en pré production, puis production. 

Représentation du projet d'architecture sécurisée et IA P2DS.


LiteLLM, dans sa version Proxy Server, sert essentiellement à centraliser, sécuriser et simplifier l’accès à tous les modèles d’IA derrière une seule API compatible OpenAI.

Voici une explication simple et structurée, basée sur le blog.stephane-robert.info.


🧩 Ce que fait LiteLLM (en version simple)

LiteLLM joue le rôle de passerelle unique entre vos applications et des dizaines de fournisseurs de modèles IA (OpenAI, Anthropic, Azure, Bedrock, Hugging Face…).
Au lieu de gérer plusieurs API, formats, clés et règles, vous passez toujours par LiteLLM, qui s’occupe du reste.


⚙️ Les fonctions essentielles (explication simple)

1) Accès unifié à 100+ modèles

  • Vous appelez toujours la même API (format OpenAI).
  • LiteLLM traduit automatiquement vers le bon fournisseur.
  • Vous pouvez changer de modèle sans changer votre code.

2) Compatibilité totale OpenAI

  • Endpoints /chat/completions, /embeddings, /batches.
  • Vos outils existants fonctionnent sans modification.

3) Clés virtuelles pour utilisateurs/équipes

  • Vous créez des API keys internes pour vos équipes.
  • Vous contrôlez qui utilise quoi, et combien.
  • Vous évitez de distribuer vos vraies clés OpenAI/Anthropic.

4) Suivi des coûts

  • LiteLLM calcule automatiquement les dépenses :
    • par modèle
    • par utilisateur
    • par équipe
  • Très utile pour éviter les mauvaises surprises.

5) Budgets et limites

  • Vous fixez des quotas :
    ex : 20€ par mois pour l’équipe marketing, 1000 requêtes/jour pour un service.

6) Interface d’administration

  • Une UI web pour gérer :
    • utilisateurs
    • équipes
    • clés
    • modèles
    • budgets
    • logs

7) Fallbacks et load balancing

  • Si un modèle tombe en panne, LiteLLM bascule vers un autre.
  • Vous pouvez répartir la charge entre plusieurs fournisseurs.

8) Cache Redis

  • Réduit les coûts et accélère les réponses.
  • Très utile pour les prompts répétitifs.

9) Alertes

  • Notifications Slack / Teams / Email quand :
    • un budget est dépassé
    • un incident survient

Fonctions avancées (version Enterprise)

Toujours en explication simple :

Authentification avancée

  • SSO, OIDC, Azure AD, Keycloak.
  • Gestion automatique des tokens temporaires.

Gestion d’organisations

  • Structure hiérarchique : organisations → équipes → utilisateurs.
  • Admins délégués.
  • Modèles privés par équipe.

Observabilité avancée

  • Métriques Prometheus.
  • Logging vers Datadog, S3, GCS, Azure Data Lake.

Sécurité renforcée

  • Guardrails (politiques de contenu).
  • Rotation automatique des clés.

Comment ça fonctionne (simplement)

LiteLLM est un reverse proxy intelligent :

  1. Votre application envoie une requête au format OpenAI.
  2. LiteLLM la reçoit et regarde quel modèle utiliser.
  3. Il transforme la requête pour le fournisseur choisi.
  4. Il renvoie la réponse au format OpenAI.

Vous n’avez donc jamais à gérer les différences entre fournisseurs.


Pourquoi les entreprises l’utilisent

  • Pour centraliser l’accès aux IA.
  • Pour sécuriser les clés et les accès.
  • Pour maîtriser les coûts.
  • Pour éviter le shadow IT.
  • Pour changer de fournisseur facilement (multi-sourcing).
  • Pour industrialiser l’usage des LLM.
  • Pour ma part créer une architecture plus renforcée

Architecture D2S – Version RSSI (DMZ, Double Firewall, Flux contrôlés).

L’ajout d’un SIEM dans mon architecture :

c’est une exigence DSI/DPO/RSSI dès qu’on manipule des données sensibles, qu’on expose des API internes/externes, et qu’on introduit des briques comme LiteLLM, Presidio, Open WebUI ou des modèles IA.

L’idée clé : le SIEM n’est pas là pour l’IA, il est là pour la sécurité du SI dans lequel l’IA s’insère.

Pourquoi un SIEM dans cette architecture

1) Détection d’incidents de sécurité

Les flux IA (LiteLLM, Open WebUI, API Gateway, Presidio) deviennent de nouveaux vecteurs d’attaque :

  • tentatives d’accès non autorisé

  • exfiltration de données via prompts

  • appels massifs anormaux (DoS applicatif)

  • utilisation frauduleuse de clés virtuelles

  • contournement des règles DPO (ex : envoi de PII vers un modèle cloud)

Le SIEM permet de corréler ces événements avec le reste du SI.

2) Traçabilité réglementaire (DPO / RSSI)

Dans un contexte RGPD, santé, OIV ou souveraineté, il faut pouvoir répondre à :

  • Qui a accédé à quoi ?

  • Quand ?

  • Depuis où ?

  • Avec quel modèle ?

  • Sur quelles données ?

LiteLLM génère des logs riches (requêtes, modèles, coûts, utilisateurs). Presidio génère des logs de détection PII. Open WebUI génère des logs d’accès.

Le SIEM centralise et conserve ces traces pour audit.

3) Supervision de la chaîne IA (DSI)

L’IA devient une chaîne de production :

  • API Gateway

  • Presidio

  • LiteLLM

  • Providers (Cloud / On‑Prem / Ollama)

  • Open WebUI

  • Grafana / Prometheus

Le SIEM permet de détecter :

  • un modèle qui répond trop lentement

  • un provider qui tombe

  • un pic de consommation anormal

  • un comportement utilisateur suspect

C’est la vision transverse que Grafana seul ne fournit pas.

4) Conformité et souveraineté

Pour un DPO/RSSI, le SIEM est indispensable pour :

  • prouver que les données sensibles n’ont pas quitté le périmètre autorisé

  • tracer les appels vers les modèles cloud

  • détecter les violations de politiques (ex : modèle non autorisé)

  • conserver les logs pour les audits CNIL / internes

Sans SIEM, tu n’as aucune preuve en cas d’incident.

5) Corrélation avec les autres couches du SI

L’IA n’est qu’un composant du SI, le SIEM permet de corréler :

  • logs réseau

  • logs firewall

  • logs IAM / SSO

  • logs applicatifs

  • logs LiteLLM / Presidio / WebUI

Exemple :

Un utilisateur se connecte via SSO → appelle Open WebUI → envoie un prompt suspect → Presidio détecte des PII → LiteLLM bloque → SIEM corrèle → alerte RSSI.

Comment le SIEM s’intègre dans mon schéma

Dans mon architecture, la brique Supervision & Audit inclut :

  • Grafana (métriques)

  • Logs (Loki / Elastic)

  • SIEM (corrélation + sécurité)

Le SIEM il est obligatoire dès que vous avez :

  • des données sensibles (santé, RH, finance)

  • des flux externes

  • des API exposées

  • des modèles IA (risque d’exfiltration)

  • des obligations réglementaires (RGPD, HDS, OIV)

Synthèse en une phrase

Le SIEM est indispensable pour détecter, corréler, tracer et auditer tous les événements de sécurité liés à la chaîne IA, et pour garantir la conformité DPO/RSSI dans un environnement où les modèles peuvent devenir des vecteurs d’attaque ou de fuite de données.

PRESIDIO → LiteLLM

Fiche d'Intégration Opérationnelle — Architecture IA Souveraine UGAIA

 

Version

1.0 — Mars 2026

Statut

Appliquer dès Phase 2 (J+30)

Classification

Données N3/N4 — Confidentiel

Prérequis

Ollama + Phi-4 installés, LiteLLM Gateway opérationnel

Objectif

Anonymisation PII obligatoire avant tout flux vers le modèle d'inférence

 

🎯  Contexte UGAIA

Presidio s'intègre comme middleware dans LiteLLM Proxy, garantissant qu'aucune donnée personnelle (PII) ne transite en clair vers Ollama/Phi-4. Les journaux produits sont « audit-ready » dès leur création — conformité RGPD Art. 5, règle des 48h CNIL, et assurabilité cyber.

 

1. Architecture de la chaîne d'anonymisation

Le schéma suivant représente le flux Zero Trust IA avec Presidio en position de garde-frontière :

 

  Utilisateur

      |  (prompt brut — peut contenir PII N3/N4)

      v

  Open WebUI

      |

      v

  [ PRESIDIO — Anonymisation PII ]  <===  MIDDLEWARE LiteLLM

      |  (prompt anonymisé : <NOM_PERSONNE>, <EMAIL>, <NIR>...)

      v

  LiteLLM Proxy (Gateway)

      |  (corrélation : mlflow_run_id injecté)

      v

  Ollama / Phi-4  (inférence locale — zéro dépendance cloud)

      |

      v

  OpenTelemetry Collector

      |

      +----> ELK Stack  (journaux anonymisés — preuves forensiques)

      |

      +----> Langfuse   (observabilité LLM — traçabilité prompt/réponse)

      |

      +----> MLflow     (registre modèle — version + run_id)

 

⚠️  Règle d'or — Audit-by-Design

Aucune donnée nominative ne doit figurer dans les journaux d'audit. Presidio filtre le flux en mémoire vive avant tout écrit dans ELK ou Langfuse.

 

2. Installation de Presidio (Python)

Prérequis système : Python 3.9+, pip, accès Docker optionnel. Déploiement recommandé en on-premise.

 

2.1 Installation des packages

# Installation des composants Presidio

pip install presidio-analyzer presidio-anonymizer

 

# Modèle NLP français (support N3/N4 textes RH, santé, finance)

python -m spacy download fr_core_news_lg

 

# Optionnel : modèle anglais pour documents bilingues

python -m spacy download en_core_web_lg

 

2.2 Test de validation post-install

from presidio_analyzer import AnalyzerEngine

from presidio_anonymizer import AnonymizerEngine

 

analyzer  = AnalyzerEngine()

anonymizer = AnonymizerEngine()

 

test_text = "Jean Dupont, né le 15/03/1982, NIR : 1 82 03 75 108 045 28"

results   = analyzer.analyze(text=test_text, language='fr')

output    = anonymizer.anonymize(text=test_text, analyzer_results=results)

 

print(output.text)

# Attendu : <PERSON>, né le <DATE_TIME>, NIR : <FR_NIR>

 

✅  Cible de détection

Taux de détection cible : > 95% sur jeu de données représentatif métier. Valider impérativement avant mise en production N3/N4.

 

3. Configuration du middleware LiteLLM

Presidio s'intègre comme hook de pré-traitement (pre-call hook) dans LiteLLM. Les données sont filtrées en mémoire avant routage vers Ollama.

 

3.1 Classe middleware Presidio

# presidio_middleware.py

from presidio_analyzer import AnalyzerEngine

from presidio_anonymizer import AnonymizerEngine

from presidio_anonymizer.entities import OperatorConfig

import litellm

 

class PresidioMiddleware:

    def __init__(self):

        self.analyzer  = AnalyzerEngine()

        self.anonymizer = AnonymizerEngine()

 

    def anonymize(self, text: str, level: str = 'N3') -> dict:

        """

        Anonymise le texte et retourne le texte filtré

        + la liste des entités détectées pour journalisation.

        """

        results = self.analyzer.analyze(

            text=text,

            language='fr',

            entities=[

                'PERSON', 'EMAIL_ADDRESS', 'PHONE_NUMBER',

                'IBAN_CODE', 'CREDIT_CARD', 'DATE_TIME',

                'LOCATION', 'IP_ADDRESS', 'NRP',

                'FR_NIR',   # Numéro de sécurité sociale FR

                'MEDICAL_LICENSE',

            ]

        )

 

        # Stratégie de masquage selon niveau de classification

        operators = {

            'PERSON':        OperatorConfig('replace', {'new_value': '<NOM_PERSONNE>'}),

            'EMAIL_ADDRESS': OperatorConfig('replace', {'new_value': '<EMAIL>'}),

            'PHONE_NUMBER':  OperatorConfig('replace', {'new_value': '<TEL>'}),

            'IBAN_CODE':     OperatorConfig('hash',    {'hash_type': 'sha256'}),

            'CREDIT_CARD':   OperatorConfig('mask',    {'masking_char': '*', 'chars_to_mask': 12}),

            'FR_NIR':        OperatorConfig('hash',    {'hash_type': 'sha256'}),

            'DATE_TIME':     OperatorConfig('replace', {'new_value': '<DATE>'}),

            'LOCATION':      OperatorConfig('replace', {'new_value': '<LOCALISATION>'}),

            'IP_ADDRESS':    OperatorConfig('replace', {'new_value': '<IP>'}),

        }

 

        anonymized = self.anonymizer.anonymize(

            text=text,

            analyzer_results=results,

            operators=operators

        )

 

        return {

            'anonymized_text': anonymized.text,

            'detected_entities': [r.entity_type for r in results],

            'pii_detected': len(results) > 0,

        }

 

3.2 Hook LiteLLM — pré-traitement du prompt

# litellm_config.py

import litellm

import mlflow

import json

from presidio_middleware import PresidioMiddleware

from datetime import datetime

 

presidio = PresidioMiddleware()

 

def pre_call_hook(kwargs, result, start_time, end_time):

    """

    Hook exécuté avant chaque appel LiteLLM.

    Anonymise le prompt et journalise les métadonnées d'audit.

    """

    messages = kwargs.get('messages', [])

    run_id = mlflow.active_run().info.run_id if mlflow.active_run() else 'no_run'

 

    for msg in messages:

        if msg.get('role') == 'user':

            raw_text = msg['content']

            result   = presidio.anonymize(raw_text)

 

            # Remplacement du contenu par la version anonymisée

            msg['content'] = result['anonymized_text']

 

            # Journalisation des métadonnées uniquement (jamais le texte brut)

            audit_meta = {

                'mlflow_run_id':     run_id,

                'timestamp':         datetime.utcnow().isoformat(),

                'pii_detected':      result['pii_detected'],

                'entities_detected': result['detected_entities'],

                'anonymized':        True,

            }

            # Envoi vers Langfuse / ELK (via OpenTelemetry)

            print(json.dumps(audit_meta))  # remplacer par otel_logger

 

litellm.pre_call_hook = pre_call_hook

 

3.3 Configuration litellm_config.yaml

# litellm_config.yaml

model_list:

  - model_name: phi4-local

    litellm_params:

      model: ollama/phi4

      api_base: http://localhost:11434

 

general_settings:

  presidio_enabled: true

  presidio_language: fr

  pii_masking: true

  log_decision_process: true    # Traçabilité audit CNIL

 

litellm_settings:

  success_callback: ["langfuse", "mlflow"]

  failure_callback: ["langfuse"]

  telemetry: true

 

4. Workflow opérationnel — 5 étapes

 

1

Réception du prompt brut

Open WebUI reçoit la requête utilisateur. Le texte peut contenir des PII N3/N4 non contrôlées.

 

2

Anonymisation Presidio (< 50ms)

Le middleware analyse le texte, détecte les entités PII, applique le masquage configuré. Le prompt anonymisé remplace le texte original en mémoire.

 

3

Injection du mlflow_run_id

Un identifiant unique est généré et injecté dans les métadonnées de la requête. Ce run_id devient l'identifiant pivot de toute la chaîne d'audit.

 

4

Inférence Ollama / Phi-4

Le modèle reçoit uniquement le prompt anonymisé. Zéro PII ne transite vers le moteur d'inférence. Conformité RGPD Art. 5 (minimisation) garantie.

 

5

Journalisation audit-ready

ELK et Langfuse reçoivent uniquement les métadonnées anonymisées + mlflow_run_id. Les logs sont immédiatement utilisables pour réponse CNIL 48h ou rapport assureur.

 

5. Validation et contrôle qualité

5.1 Suite de tests de non-régression

# test_presidio_validation.py

import pytest

from presidio_middleware import PresidioMiddleware

 

pii = PresidioMiddleware()

 

TEST_CASES = [

    # (description, texte_brut, entités_attendues)

    ('Nom complet FR',

     'Mme Marie Curie signe le contrat.',

     ['PERSON']),

    ('Email professionnel',

     'Contactez pierre.martin@entreprise.fr pour confirmation.',

     ['EMAIL_ADDRESS']),

    ('NIR sécurité sociale',

     'Mon numéro est 1 82 03 75 108 045 28.',

     ['FR_NIR']),

    ('IBAN bancaire',

     'Virement sur FR76 3000 6000 0112 3456 7890 189.',

     ['IBAN_CODE']),

    ('Donnée de santé composée',

     'Dr. Benoit, né le 12/06/1975, consultation le 03/03/2026.',

     ['PERSON', 'DATE_TIME']),

]

 

@pytest.mark.parametrize('desc, text, expected_entities', TEST_CASES)

def test_detection(desc, text, expected_entities):

    result = pii.anonymize(text)

    assert result['pii_detected'], f'Aucune PII détectée pour : {desc}'

    for entity in expected_entities:

        assert entity in result['detected_entities'], \

            f'{entity} non détecté pour : {desc}'

 

def test_no_pii_preserved():

    """Vérifie qu'aucun PII ne subsiste après anonymisation."""

    text = 'Marie Dupont, née le 01/01/1990'

    result = pii.anonymize(text)

    assert 'Marie Dupont' not in result['anonymized_text']

    assert '01/01/1990' not in result['anonymized_text']

 

5.2 Matrice de conformité RGPD

 

Exigence RGPD

Sans Presidio

Avec Presidio

Art. 5 — Minimisation des données

❌ Non conforme

✅ Conforme

Art. 25 — Privacy by Design

❌ Risque élevé

✅ Implémenté

Art. 32 — Sécurité du traitement

⚠️ Partiel

✅ Garanti

Art. 33 — Notification 72h ANSSI

❌ Impossible

✅ Prêt

Règle 48h CNIL — Dossier d'audit

❌ Manuel (jours)

✅ Automatique

Assurabilité cyber 2026

❌ < 50 pts

✅ +15 pts score

 

6. Contribution au Score de Résilience UGAIA

L'intégration de Presidio comme middleware actif contribue directement au score de résilience. Le tableau ci-dessous détaille les points acquis par composant UGAIA :

 

Composant UGAIA

Sans Presidio

Avec Presidio

C1 — Journalisation & Traçabilité

6/12

11/12

C2 — Protection des Données (RGPD)

4/15

13/15

C3 — Sécurité des Accès

6/10

8/10

C4 — Gouvernance & Conformité

5/13

11/13

C5 — Résilience Technique

8/15

12/15

TOTAL / 100

44/100 ⚠️ Non assurable

78/100 ✅ Assurable

 

🏆  Seuils d'assurabilité 2026

Score ≥ 75/100 : éligibilité assurance cyber. Score ≥ 80/100 : statut SOUVERAIN+. L'intégration de Presidio fait passer l'organisation de 44/100 (non assurable) à 78/100 (assurable).

 

7. Résolution des problèmes courants

Symptôme

Cause probable

Solution

Noms FR non détectés

Modèle spaCy EN chargé

Installer fr_core_news_lg et spécifier language='fr'

Latence > 200ms

Modèle NLP trop lourd

Utiliser fr_core_news_md ou migrer vers rs-presidio (Rust)

NIR non reconnu

Reconnaisseur FR_NIR manquant

Ajouter recognizer FR personnalisé (regex NIR)

Hook LiteLLM ignoré

Version LiteLLM < 1.30

Mettre à jour : pip install --upgrade litellm

mlflow_run_id absent

MLflow non initialisé

Appeler mlflow.start_run() avant le hook

Taux détection < 90%

Jargon métier non reconnu

Ajouter des reconnaisseurs personnalisés (contrats, IDs internes)

 

8. Checklist de mise en production

 

VALIDATION PRE-PRODUCTION N3/N4

Toutes les cases doivent être cochées avant activation

 

▶  Installation

        ☐  presidio-analyzer et presidio-anonymizer installés (pip)

        ☐  Modèle spaCy fr_core_news_lg téléchargé et validé

        ☐  Test unitaire de base exécuté avec succès

 

▶  Configuration

        ☐  PresidioMiddleware instancié et configuré (entités FR activées)

        ☐  Hook pre_call_hook enregistré dans LiteLLM

        ☐  litellm_config.yaml : presidio_enabled: true et log_decision_process: true

        ☐  mlflow_run_id injecté dans les métadonnées de chaque requête

 

▶  Validation

        ☐  Suite pytest complète : taux de détection ≥ 95% sur jeu de test métier

        ☐  Contrôle : aucun PII en clair dans les logs ELK et Langfuse

        ☐  Test règle 48h : dossier d'audit généré automatiquement sans donnée brute

        ☐  Fallback testé : désactivation Presidio = rejet de la requête (pas de bypass)

 

▶  Documentation

        ☐  Fiche de procédure archivée dans le système de gestion documentaire

        ☐  Score de résilience UGAIA recalculé et validé (≥ 75/100)

        ☐  Rapport d'audit CNIL préparé avec preuves d'anonymisation

 


 

Références et ressources

 

Documentation officielle

https://microsoft.github.io/presidio/ 

API Reference

https://microsoft.github.io/presidio/api-docs/api-docs.html

Démo Hugging Face

https://huggingface.co/spaces/presidio/presidio_demo

ModernBERT PII classifier

https://huggingface.co/llm-semantic-router/pii_classifier_modernbert-base_presidio_token_model

rs-presidio (Rust)

https://github.com/posidron/rs-presidio

LiteLLM Proxy docs

https://docs.litellm.ai/docs/proxy/quick_start

Blog GOUVERNANCES. — Art. 1

https://gouver2020.blogspot.com/2026/02/microsoft-presidio-est-le-framework.html

Blog GOUVERNANCES. — Art. 2

https://gouver2020.blogspot.com/2026/02/tests-installation-de-presidio.html

Blog GOUVERNANCES. — Art. 3

https://gouver2020.blogspot.com/2026/03/pii-de-identification-avec-microsoft.html

Guide UGAIA V10 — Chapitre 5

Gouv˙IA-Secu-Audit-IA_V10_2026.docx

 

📋  Intégration dans le Passeport Souveraineté UGAIA V4

Cette fiche répond directement à la Question 6 du Passeport : traçabilité complète prompt → modèle → accès → évaluation qualité. Le mlflow_run_id est l'identifiant pivot. Sa présence dans chaque enregistrement ELK, Langfuse et MLflow constitue la preuve technique d'intégrité exigée par les auditeurs et les assureurs.

 











Successfully installed PyJWT-2.11.0 apscheduler-3.11.2 azure-core-1.38.2 azure-identity-1.25.2 azure-storage-blob-12.28.0 backoff-2.2.1 boto3-1.40.76 botocore-1.40.76 cffi-2.0.0 croniter-6.0.0 cryptography-46.0.5 dnspython-2.8.0 email-validator-2.3.0 fastapi-0.132.0 fastapi-sso-0.16.0 gunicorn-23.0.0 httpx-sse-0.4.3 isodate-0.7.2 jmespath-1.1.0 litellm-enterprise-0.1.32 litellm-proxy-extras-0.4.46 mcp-1.26.0 msal-1.34.0 msal-extensions-1.3.1 oauthlib-3.3.1 orjson-3.11.7 polars-1.38.1 polars-runtime-32-1.38.1 pycparser-3.0 pydantic-settings-2.13.1 pynacl-1.6.2 python-multipart-0.0.22 pywin32-311 redis-7.2.0 rich-13.7.1 rq-2.7.0 s3transfer-0.14.0 soundfile-0.12.1 sse-starlette-3.2.0 starlette-0.52.1 tzlocal-5.3.1 websockets-15.0.1
PS C:\> litellm --model gpt-4o
INFO:     Started server process [15012]
INFO:     Waiting for application startup.

Ollama peut être utilisé à l’intérieur de LiteLLM comme un fournisseur de modèles locaux.

LiteLLM = Proxy multi‑fournisseurs + gouvernance + coûts

LiteLLM sert à :

  • unifier l’accès à tous les modèles (OpenAI, Anthropic, Azure, Bedrock, Ollama…)

  • gérer les clés virtuelles, quotas, budgets, équipes

  • suivre les coûts et les logs

  • appliquer des politiques de sécurité

  • faire du load balancing et du fallback

  • exposer une API OpenAI unique

LiteLLM n’exécute pas les modèles : il orchestrationne.


Ollama = Serveur local de modèles open‑source

Ollama sert à :

  • télécharger et exécuter des modèles localement (Llama, Mistral, Phi, Qwen…)
  • gérer le chargement en RAM, le quantization, le GPU
  • fournir une API simple pour interroger un modèle local

Ollama n’a pas :

  • de gestion d’utilisateurs
  • de quotas
  • de budgets
  • de logs avancés
  • de multi‑fournisseurs
  • de compatibilité OpenAI complète
  • de load balancing
  • de sécurité d’entreprise

Comment ils s’articulent ensemble

Le schéma réel dans les entreprises

Code
Application → LiteLLM → (OpenAI / Anthropic / Azure / Bedrock / Ollama local)

LiteLLM devient la couche de gouvernance, Ollama devient un fournisseur parmi d’autres.

Conclusion simple

  • Ollama = moteur local

  • LiteLLM = gouvernance + proxy multi‑modèles

Ollama ne remplace pas LiteLLM. Ollama complète LiteLLM.

1) Démarrer LiteLLM Proxy avec Docker, c'est fait

Autrement si tu as déjà téléchargé l’image.

Lance-la :

docker run -p 4000:4000 -e LITELLM_LOG=info docker.litellm.ai/berriai/litellm:main-latest

Cela démarre le proxy LiteLLM sur :

http://localhost:4000   voir copie écran ci-dessus

2) Tester avec l’API OpenAI (via LiteLLM)

Exemple :

curl http://localhost:4000/v1/chat/completions `
  -H "Content-Type: application/json" `
  -H "Authorization: Bearer votrecledetest" `
  -d "{""model"":""gpt-4o-mini"", ""messages"":[{""role"":""user"",""content"":""Bonjour""}]}"

3) Ajouter Ollama comme fournisseur local (si tu veux)

Si tu as Ollama installé :

ollama run mistral

Puis dans LiteLLM, tu peux appeler :

curl http://localhost:4000/v1/chat/completions `
  -H "Content-Type: application/json" `
  -d "{""model"":""ollama/mistral"", ""messages"":[{""role"":""user"",""content"":""Bonjour""}]}"

Résumé clair

  • La ligne “Application → LiteLLM → …” était un schéma, pas une commande.
  • PowerShell a essayé de l’exécuter → erreur normale.
  • Tu as bien installé LiteLLM.
  • Prochaine étape : lancer le proxy et tester une requête.