Garde-fou RGPD : masquer les données personnelles
Garde-fou RGPD : masque e-mails, téléphones, IBAN et numéros de sécurité sociale français dans les réponses d'un assistant IA. Règles, 12 cas de test, code.
Regeln
Masquer avant l'envoi toute donnée permettant d'identifier ou de contacter une personne : - adresse e-mail nominative (jean.dupont@…) ; - numéro de téléphone français ; - IBAN ; - numéro de sécurité sociale. Laisser passer : adresses génériques (contact@, support@…), noms d'entreprises, montants, dates, numéros de commande.
Testfälle
| Eingabe | Erwartet |
|---|---|
| Vous pouvez écrire à jean.dupont@gmail.com pour le suivi. | Blockieren |
| Mon numéro est le 06 12 34 56 78. | Blockieren |
| Rappelez-moi au +33 6 12 34 56 78 demain. | Blockieren |
| Virement sur FR76 3000 6000 0112 3456 7890 189. | Blockieren |
| Numéro de sécu : 1 85 05 78 006 084 36. | Blockieren |
| Envoyez la facture à marie.martin@entreprise.fr. | Blockieren |
| Écrivez à contact@contextetech.com pour toute question. | Zulassen |
| Votre commande n° 458712 part demain. | Zulassen |
| Le montant est de 1 250,00 € TTC. | Zulassen |
| Rendez-vous le 12/10/2026 à 14 h. | Zulassen |
| La société Dupont SARL a validé le devis. | Zulassen |
| Bonjour, comment puis-je vous aider ? | Zulassen |
Code
import re
MOTIFS = {
"email": r"[\w.+-]+@[\w-]+\.[\w.-]+",
"telephone": r"(?:\+33\s?|0)[1-9](?:[\s.-]?\d{2}){4}",
"iban": r"\bFR\d{2}(?:\s?[\dA-Z]{4}){5}\s?[\dA-Z]{3}\b",
"secu": r"\b[12]\s?\d{2}\s?(?:0[1-9]|1[0-2])\s?(?:\d{2}|2[AB])\s?\d{3}\s?\d{3}\s?\d{2}\b",
}
GENERIQUES = ("contact@", "support@", "info@", "hello@")
def masquer(texte: str) -> tuple[str, bool]:
"""Remplace les données personnelles par [masqué] ; renvoie le texte et True si quelque chose a été masqué."""
trouve = False
for nom, motif in MOTIFS.items():
def remplacer(m):
nonlocal trouve
if nom == "email" and m.group(0).lower().startswith(GENERIQUES):
return m.group(0)
trouve = True
return f"[{nom} masqué]"
texte = re.sub(motif, remplacer, texte)
return texte, trouveGeschätzte Kosten
Eingabe-Tokens pro Aufruf : ≈ 782
| Modell | Pro Aufruf | Pro 1.000 Aufrufe |
|---|---|---|
| Mistral Large · Mistral AI | 0,00034 € | 0,34 € |
| DeepSeek Flash · DeepSeek | 0,00021 € | 0,21 € |
| DeepSeek V4 Pro · DeepSeek | 0,00091 € | 0,91 € |
| GPT-6 Luna · OpenAI | 0,00007 € | 0,07 € |
| GPT-6 Sol · OpenAI | 0,00138 € | 1,38 € |
| Claude Sonnet 5.5 · Anthropic | 0,00138 € | 1,38 € |
| Claude Opus 5.5 · Anthropic | 0,00276 € | 2,75 € |
| Selbst gehostetes Open-Source-Modell (Ollama, vLLM) | 0 € API-Kosten (nur Serverkosten) | |
Nur Eingabekosten, ohne die Antwort des Modells. Öffentliche Standardpreise der Anbieter (Mistral AI, DeepSeek, OpenAI, Anthropic) von USD in Euro umgerechnet zum EZB-Kurs vom 29. September 2026. Schätzung: 1 Token ≈ 3,6 Zeichen.
Common to all 3 regions
Created by the author, no outside source.
Commercial use allowed · credit the author · changes allowed.
Text or data only: no access to files, network or commands.
Hosted in France (Scaleway, Paris). No transfer outside the EU.
European Union · 5/5
Fictional: invented names, addresses and numbers, no real person.
No training data: no summary required.
United States · 5/5
Fictional: invented names, addresses and numbers, no real person.
No training data: no documentation to publish.
China · 5/5
Fictional: invented names, addresses and numbers, no real person.
No training data; AI-generated content published in China must be labelled (2025).
Indicative summary as of 30/09/2026, not a legal certification. Method and sources →
Statistiken
Gefällt mir : 0 · Kommentare : 0
Klicken Sie auf einen Zähler, um ihn ein- oder auszublenden; fahren Sie über das Diagramm für Details. Ein Aufruf pro Besucher und Tag, ohne Bots; Zählung seit dem 30. September 2026.
- Kennung
- contextetech--masquer-donnees-personnelles-rgpd
- Typ
- Schutzregeln
- Datei
- masquer-donnees-personnelles-rgpd.guardrail.json
- Format
- JSON (application/json)
- Größe
- 2.024 Bytes (2 KB)
- Kodierung
- UTF-8
- Geschätzte Tokens
- ≈ 552
- Sprache
- Französisch
- Lizenz
- MIT
- Kommerzielle Nutzung
- Erlaubt
- Personenbezogene Daten
- Fiktiv (erfunden)
- Version
- 1.0
- Veröffentlicht am
- 1. Oktober 2026 um 18:21
- Aktualisiert am
- 2. Oktober 2026 um 22:41
- Speicherung
- in der Datenbank
- Nutzungen
- 1
- Gefällt mir
- 0
masquer-donnees-personnelles-rgpd.guardrail.json
{
"format": "contextetech/guardrail/v1",
"id": "contextetech/masquer-donnees-personnelles-rgpd",
"description": "Garde-fou RGPD : masque e-mails, téléphones, IBAN et numéros de sécurité sociale français dans les réponses d'un assistant IA. Règles, 12 cas de test, code.",
"tags": [
"rgpd",
"donnees-personnelles",
"securite"
],
"license": "MIT",
"language": "fr",
"type": "pii",
"action": "mask",
"rules": "Masquer avant l'envoi toute donnée permettant d'identifier ou de contacter une personne :\n- adresse e-mail nominative (jean.dupont@…) ;\n- numéro de téléphone français ;\n- IBAN ;\n- numéro de sécurité sociale.\nLaisser passer : adresses génériques (contact@, support@…), noms d'entreprises, montants, dates, numéros de commande.",
"cases": [
{
"input": "Vous pouvez écrire à jean.dupont@gmail.com pour le suivi.",
"expected": "block"
},
{
"input": "Mon numéro est le 06 12 34 56 78.",
"expected": "block"
},
{
"input": "Rappelez-moi au +33 6 12 34 56 78 demain.",
"expected": "block"
},
{
"input": "Virement sur FR76 3000 6000 0112 3456 7890 189.",
"expected": "block"
},
{
"input": "Numéro de sécu : 1 85 05 78 006 084 36.",
"expected": "block"
},
{
"input": "Envoyez la facture à marie.martin@entreprise.fr.",
"expected": "block"
},
{
"input": "Écrivez à contact@contextetech.com pour toute question.",
"expected": "allow"
},
{
"input": "Votre commande n° 458712 part demain.",
"expected": "allow"
},
{
"input": "Le montant est de 1 250,00 € TTC.",
"expected": "allow"
},
{
"input": "Rendez-vous le 12/10/2026 à 14 h.",
"expected": "allow"
},
{
"input": "La société Dupont SARL a validé le devis.",
"expected": "allow"
},
{
"input": "Bonjour, comment puis-je vous aider ?",
"expected": "allow"
}
]
}Text prüfen (Python)
import re
MOTIFS = {
"email": r"[\w.+-]+@[\w-]+\.[\w.-]+",
"telephone": r"(?:\+33\s?|0)[1-9](?:[\s.-]?\d{2}){4}",
"iban": r"\bFR\d{2}(?:\s?[\dA-Z]{4}){5}\s?[\dA-Z]{3}\b",
"secu": r"\b[12]\s?\d{2}\s?(?:0[1-9]|1[0-2])\s?(?:\d{2}|2[AB])\s?\d{3}\s?\d{3}\s?\d{2}\b",
}
GENERIQUES = ("contact@", "support@", "info@", "hello@")
def masquer(texte: str) -> tuple[str, bool]:
"""Remplace les données personnelles par [masqué] ; renvoie le texte et True si quelque chose a été masqué."""
trouve = False
for nom, motif in MOTIFS.items():
def remplacer(m):
nonlocal trouve
if nom == "email" and m.group(0).lower().startswith(GENERIQUES):
return m.group(0)
trouve = True
return f"[{nom} masqué]"
texte = re.sub(motif, remplacer, texte)
return texte, trouve
Community
Noch keine Kommentare. Teile deine Erfahrung, sie hilft den Nächsten.