Catégories

🔍 Licence d'Utilisation 🔍

Sauf mention contraire, le contenu de ce blog est sous licence CC BY-NC-ND 4.0.

© 2025 à 2042 Sébastien Gioria. Tous droits réservés.

Les stratégies de mitigation définissent comment réagir aux différentes situations détectées par les guardrails. Une approche adaptative et contextuelle est essentielle pour maintenir l’équilibre entre sécurité et utilisabilité.

Actions de Mitigation Disponibles ⚡

Actions de mitigation
Action Description Cas d'Usage Impact
🛑 exception Arrêt immédiat et signalement Violations graves de sécurité Faible
🔍 filter Suppression/masquage du contenu Contenu inapproprié mineur Moyen
🔄 reask Nouvelle génération par le LLM Réponses de qualité insuffisante Élevé
🔧 fix Correction automatique Erreurs de format simples Moyen

Remarque : les niveaux d'impact sont indicatifs. Adaptez les couleurs et labels selon votre charte.

Détails et exemples par action

🛑 🛑 Exception

RUPTURE (exception)

QUAND Fuite de secret, exécution de code arbitraire détectée, attaque active.
EFFET Arrêt immédiat → réponse bloquée (403 / message neutre), génération d'un événement d'alerte.
IMPACT Interruption ponctuelle mais protection forte; nécessite triage rapide.
Voir pseudo-code
if detector.is_severe(hit):
    mitigation.raise_exception(code=403, reason="policy-violation", context=ctx)
    audit.log_event(detector=hit.src, severity="critical")

🔍 🔍 Filter

REDACTION (filter)

QUAND Contenu sensible modéré (PII partielle), langage inapproprié léger, fuite mineure.
STRATÉGIES mask-first pour garder structure ([REDACTED]) • redact-last pour suppression tardive.
PRATIQUES Compter tokens filtrés, conserver hash du texte original (forensic), limiter sur-filtrage (éviter faux positifs).
Voir exemple RegExp
const masked = text.replace(/\b(SSN|\d{3}-\d{2}-\d{4})\b/g, '[REDACTED]')

🔄 🔄 Reask

RE-GÉNÉRATION (reask)

QUAND Réponse hors-sujet, incohérente, léger non-respect format; risque faible.
TECHNIQUES Renforcer instructions (zero→few-shot), ajuster température/top_p, changer modèle (fallback spécialisé).
PROMPT DELTA Préfixe forçant un format JSON strict + contraintes de champs / longueur.
LIMITES Bornage max_reasks; stopper si pattern d'échec identique (éviter boucle coûteuse).
Voir exemple de renforcement de prompt
SYSTEM: Tu dois répondre en JSON strict valide avec les clés: topic, risks, summary.
USER: 
GUARDRAIL: Si la réponse initiale ne respecte pas le format, régénère avec structure JSON correcte sans ajout hors-schéma.

🔧 🔧 Fix

TRANSFORMATION (fix)

QUAND Erreurs mineures de format, enrichissement léger, harmonisation.
EXEMPLES Normaliser URLs, corriger JSON (clé manquante), trim / case, compléter champs dérivés.
RISQUE Mutation silencieuse → journaliser diff (hash avant/après), garantir idempotence.
Voir pseudo-code de transformation
def fix(payload):
    before = hash_payload(payload)
    p = normalize_urls(payload)
    p = ensure_json_schema(p, schema)
    p = trim_strings(p)
    audit_diff(before, hash_payload(p))
    return p

Ordre recommandé (par coût) : filter → fix → reask → exception (sauf criticité immédiate).

Ces actions peuvent être combinées et ordonnancées (p.ex. filter → reask → fix) selon la politique définie.

Choix de la Stratégie de Mitigation

Objectif : sélectionner la séquence d’actions la plus efficace (sécurité + coût + UX) en fonction de la situation détectée.

Entrées de Décision

Élément Source Exemple
🧪 Type de signal détecteur pii, prompt_injection, toxicity
🔥 Criticité normalisée (1–5) 4 (clé API détectée)
🎯 Confiance score 0–1 0.87
🛡️ Profil risque contexte utilisateur/données high
Coûts restants budget reask / tokens reasks_remaining=1
♻️ Historique requête tentatives précédentes reask_count=0

Astuce : loggez ce snapshot (JSON) avant décision → facilite le tuning des heuristiques.

Heuristiques Principales

  1. Si criticité ≥ seuil_critique → exception prioritaire.
  2. Si contenu partiellement sûr et corrigeable → tenter filter ou fix avant tout reask.
  3. Si structure attendue non respectée mais risque faible → reask (ajout de contraintes) limité par max_reasks.
  4. Éviter reask si latence cumulée > budget p95 du profil.
  5. Sur multi-signaux : appliquer l’action la plus restrictive des actions candidates.

Matrice Décisionnelle (Résumé)

Situation Signal Dominant Confiance Profil Action Prioritaire Fallback Motif
Fuite critique secret / code exec >0.8 high 🛑 exception bloquer immédiatement
PII partielle pii 0.4–0.7 medium 🔍 filter 🔄 reask préserver UX
Réponse hors format format_error >0.6 low 🔧 fix 🔄 reask coût minimal
Réponse incohérente coherence <0.5 medium 🔄 reask 🤖 fallback model améliorer qualité
Toxicité légère toxicity 0.3–0.5 low 🔍 filter 🔄 reask nettoyer contenu

Les icônes reflètent la première action candidate; journalisez aussi decision_path pour post-analyse.

Score Combiné (exemple)

base = criticite * 2 + (1 - confiance)
if profil == 'high': base += 2
if signal in ['secret','code_exec']: base += 3
decision = case base:
  >=7  -> exception
  5-6  -> filter/fix (si applicable) sinon reask
  <5   -> reask ou fix

Adapter pondérations via analyse rétrospective des incidents et coûts mensuels.

Pseudo-code Sélection

def choose_strategy(signal, profile, ctx):
    if signal.is_critical():
        return ['exception']
    seq = []
    if signal.is_maskable():
        seq.append('filter')
    if signal.is_structural_issue():
        seq.append('fix')
    if ctx.can_reask() and signal.needs_regeneration():
        seq.append('reask')
    # Dernière barrière
    if not seq:
        seq.append('exception')
    return dedupe(seq)

💡 Conseil : tracer (signal, profil, stratégie choisie) pour affiner la matrice de décision.

Implémentation des Stratégies

🧩 Interfaces Recommandées

Composant Rôle Contrat Minimal
Detector Produire signaux detect(payload)->[Signal]
Classifier Normaliser criticité score(signals)->RiskLevel
PolicyStore Fournir politique active get(profile)->Policy
MitigationAction Exécuter transformation execute(ctx)->Result
AuditSink Traçabilité record(event)

Séparer strictement détection, décision et exécution pour limiter le couplage.

📦 Schéma d’un Result

{
  "handled": true,
  "action": "filter",
  "latency_ms": 18,
  "notes": "2 tokens masqués",
  "reask_suggested": false
}

Gardez ce schéma contractuel versionné — utilisez un test de régresion JSON Schema.

🛠️ Orchestration (JS)

async function mitigate(req){
  const signals = await detectors.runAll(req);
  const profile = deriveProfile(req, signals);
  const actions = chooseStrategy(signals, profile, req.ctx);
  for (const name of actions){
    const impl = registry.action(name);
    const t0 = performance.now();
    const result = await impl.execute(req, signals);
    audit.record({action:name, latency_ms:performance.now()-t0, profile});
    metrics.action_latency.observe(name, performance.now()-t0);
    if (result.handled) return result.payload;
  }
  throw new Error('Unmitigated');
}

Implémentez un timeout global et une politique de rollback si aucune action ne gère.

📈 Observabilité

  • Métriques par action : latence (histogram), taux succès / échec.
  • Log structuré : req_id, profile, action, policy_version, decision_path.
  • Traces : span parent “mitigation” + sous-spans par action.

Ajoutez un sample payload hash pour corréler sans stocker le contenu.

⚙️ Performance & Idempotence

Risque Mesure Stratégie
Explosion de latence cumul actions Limiter profondeur, timeouts par action
Boucles reask reask répétés max_reasks, hash de réponse précédente
Mutations destructives perte forensic Diff + hash avant/après dans audit

Exposez un compteur mitigation_chain_length pour surveiller les dérives.

✅ Tests Essentiels

Type Objectif Exemple
Unitaire Validation logique action test filter regex PIIs
Contract Structure résultat stable JSON schema output fix
Simulation Ratio FP/FN dataset annoté
Charge P95 latence stable 1k req/s guardrail pipeline
Chaos Robustesse détecteurs timeout + fallback

Automatisez un benchmark hebdo pour détecter la dérive de latence.

⚠️ Anti-Patterns

Anti-pattern Impact Alternative
Mélanger logique métier & mitigation Couplage fort Couche dédiée orchestrateur
Actions non mesurées Invisibilité Métriques obligatoires
Reask sans limite Coût imprévisible Politique avec bornes
Exceptions silencieuses Perte audit AuditSink central

Revue trimestrielle: supprimer actions rarely-used (<0.1%).

📊 Instrumentation (Prometheus - Python)

🚀 Checklist de Déploiement

Étape Objectif Actions Clés
Préparation Base saine Politique initiale versionnée (policy_v1.yml), schéma Result figé, secrets en vault
Intégration Isolation Orchestrateur middleware dédié, pas de logique métier mélangée
Détection Qualité signaux Tests FP/FN dataset annoté (>200 cas), seuils calibrés
Observabilité Visibilité Dash latence, reask, exception_rate, chain_length, logs structurés
Performance Limiter dérive Budget p95 défini, timeouts action, test charge baseline
Sécurité Durcissement AuditSink unique, hash payload, contrôle accès PolicyStore
Validation Non régression Tests contract, simulation, canary 5% trafic
Lancement Mise en prod sûre Alertes armées, runbook publié, rollback prêt
Post-prod (30j) Ajustement Revue métriques, purge actions inutiles, affiner seuils

Automatisez la checklist dans un pipeline (quality gate blocante si un point critique manque).

🗂️ Récapitulatif Métriques Clés

Catégorie Métriques But
Performance latency_p50/p95/p99, action_latency{action} Maîtriser coûts temps
Sécurité exception_rate, secret_blocked_total Détecter dérives critiques
Qualité reask_rate, format_fix_count Suivre friction modèle
Coût tokens_total, model_switch_total Budgets & optimisation
Fiabilité unmitigated_errors_total, retry_after_mitigation Robustesse pipeline
Chaîne mitigation_chain_length Prévenir séquences trop longues
Détecteurs detector_fp, detector_fn Ajuster seuils
Expérience user_abort_rate, feedback score Préserver UX

Définissez des SLO : ex. exception_rate (high) < 0.1%, reask_rate (medium) < 3%.

action_latency = Histogram('guardrail_action_latency_seconds', 'Latency', ['action'])
def execute_action(action, fn):
    start = time.time()
    try:
        return fn()
    finally:
        action_latency.labels(action=action).observe(time.time()-start)

Ajoutez un Counter pour les échecs et un Summary expérimental pour tail latence.

Impact des Actions 📊

Mesurer et valider l’impact

Objectif : prouver que les actions de mitigation protègent le système sans dégrader l’expérience utilisateur ni faire exploser les coûts.

Pour être opérationnel, liez chaque métrique aux labels suivants : profile, detector, model_version, region — cela permet de segmenter l’impact par cas d’usage.

Métriques recommandées

Métrique Description Unité
Latence end-to-end (p50 / p95 / p99) Temps total client→guardrail→modèle→client ms
Durée par étape detection_time, mitigation_time, model_time (labels) ms
Coût opérationnel reasks, tokens consommés, bascules de modèle count
Fiabilité taux d’exceptions / échecs de mitigation %
Qualité UX taux d’abandon, retries manuels, feedback % / score
Exactitude des détecteurs faux positifs / faux négatifs ratio

Bonnes pratiques : échantillonnez traces et payloads pour debug (safeguard PII), conservez id_corrélation pour chaque métrique afin de suivre la requête dans les logs et traces.

Seuils et targets (exemples)

Profil exception_rate reask_rate latence p95 additionnelle
🟢 Low < 0.5% < 5% < 100ms
🟡 Medium < 0.2% < 3% < 200ms
🔴 High < 0.1% < 1% < 300ms

Astuce : adaptez ces targets par profile, detector et region. Utilisez des alertes graduées (warning/critical) pour suivre les déviations.

Exemple de KPI minimal (récapitulatif)

  • Taux d’exception critique : < 0.1% des requêtes (profil high)
  • Taux de reask : < 3% (profil medium cible, adapter par cas d’usage)
  • Latence p95 supplémentaire acceptée : 200ms (profil medium)