
Un proxy transparent de masquage des PII pour le trafic API LLM. Se place entre une application et un fournisseur LLM (actuellement Anthropic), pseudonymisant les données sensibles en sortie et les restaurant en entrée. Construit avec FastAPI + httpx.
Un proxy transparent de réduction des données personnelles pour le trafic API des LLM. Se place entre votre application et le fournisseur de LLM, pseudonymisant les données sensibles à l'aller et les restaurant au retour.
Votre LLM ne voit jamais de vrais noms, e-mails, IP ou domaines — il travaille exclusivement avec des pseudonymes structurés comme [email protected]. Votre application récupère les valeurs originales, de manière transparente.
Lors de l'utilisation de LLM pour des opérations de sécurité, de réponse à incident ou toute tâche impliquant des données clients réelles, vous risquez d'envoyer des données personnelles à des API tierces. Ce proxy résout ce problème en :
# 1. Créez votre configuration
cp config.json.example config.json
# Modifiez config.json avec vos domaines internes, entités connues, etc.
# 2. Lancez avec Docker
docker build -t llm-token-proxy .
docker run -p 8090:8080 -v ./config.json:/app/config.json llm-token-proxy
# 3. Pointez votre application vers le proxy
export ANTHROPIC_BASE_URL=http://localhost:8090/session/my-session/
Voilà. Vos appels API Anthropic passent désormais par le proxy avec les données personnelles réductées.

Flux typique : Application → Token Proxy (réduction des données personnelles) → API LLM (pseudonymes uniquement) → Token Proxy (restauration des originaux) → Application
admin de [email protected])| Type d'entité | Exemple interne | Exemple externe |
|---|---|---|
[email protected] | [email protected] | |
| Domaine | domain-internal-001.com | domain-external-001.net |
| IP | 10.99.99.1 (RFC1918) | IP donneuse basée sur l'ASN (voir ci-dessous) |
| Personne | person_internal_001 | person_external_001 |
| Organisation | org_internal_001 | org_external_001 |
| Nom d'hôte | host_001 | host_001 |
Les pseudonymes sont déterministes au sein d'une session — une même valeur réelle correspond toujours au même pseudonyme.
Lorsqu'un LLM analyse des journaux de sécurité, le fournisseur d'hébergement et la géolocalisation d'une adresse IP comptent — une connexion depuis une IP Hetzner en Allemagne raconte une histoire différente d'une connexion depuis un FAI résidentiel aux États-Unis. Un simple remplacement par des IP de plage de documentation (ex. 198.51.100.x) détruit ce contexte.
Avec la base de données optionnelle MaxMind GeoLite2-ASN, le proxy remplace les IP réelles par une IP différente du même ASN et sous-réseau. Le LLM voit une IP d'apparence réelle qui résout le même fournisseur d'hébergement et une géographie approximative — mais ce n'est pas l'adresse réelle.
10.99.99.x (aucun contexte ASN à préserver)198.51.100.x (plage de documentation)L'IP donneuse est choisie de manière déterministe via HMAC avec un sel par session, de sorte qu'une même IP réelle corresponde toujours au même donneur au sein d'une session, mais différentes sessions produisent des mappages différents.
Le proxy est livré avec un config.json vide — aucune liste de mots intégrée ni hypothèse spécifique au domaine. Le config.json.example inclus est paramétré pour les opérations de sécurité avec Microsoft Sentinel et Entra ID (plus de 8 000 noms de tables/colonnes KQL, termes d'autorisation Graph API, domaines de référence sécurité). Si cela correspond à votre cas d'usage, copiez ce dont vous avez besoin. Si vous utilisez le proxy pour un domaine différent (santé, juridique, finance, etc.), partez de la configuration vide et construisez vos propres listes.
config.json{
"internal_domains": ["yourcompany.com"],
"partner_domains": ["partnercorp.com"],
"internal_ip_ranges": ["10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16"],
"known_persons": ["John Smith"],
"known_orgs": ["YourCompany"],
"known_hostnames": ["DC01", "FS01"],
"ner_enabled": true,
"ner_skiplist": [],
"redaction_enabled": true
}
_internal_)spacy + en_core_web_sm)false, le proxy devient un simple passagefalse, les domaines sont transmis sans modification (les e-mails, IP, noms sont toujours réduits). Utile lorsque les noms de domaine portent un contexte important pour le LLM (par exemple, distinguer outlook.com de protonmail.com) et ne sont pas considérés comme sensibles.| Variable | Valeur par défaut | Rôle |
|---|---|---|
ANTHROPIC_API_BASE | https://api.anthropic.com | URL de l'API Anthropique en amont |
TOKEN_PROXY_CONFIG_PATH | /app/config.json | Chemin vers le fichier de configuration |
LOG_LEVEL | info | Niveau de journalisation |
GEOIP_ASN_DB_PATH | /app/data/GeoLite2-ASN.mmdb | Base de données MaxMind GeoLite2-ASN (optionnelle) |
Gérez les listes blanches et activez/désactivez la réduction sans redémarrer :
# Voir toutes les listes blanches
curl http://localhost:8090/token-proxy/config/whitelist
# Ajouter des termes à la liste de saut NER (réduit les faux positifs)
curl -X POST http://localhost:8090/token-proxy/config/whitelist \
-H "Content-Type: application/json" \
-d '{"category": "ner_skiplist", "values": ["EvoSTS", "Hetzner"]}'
# Ajouter des domaines à la liste blanche (ne jamais pseudonymiser ceux-ci)
curl -X POST http://localhost:8090/token-proxy/config/whitelist \
-H "Content-Type: application/json" \
-d '{"category": "domain_allowlist", "values": ["github.com"]}'
# Désactiver la réduction (mode passage)
curl -X POST http://localhost:8090/token-proxy/config/status \
-H "Content-Type: application/json" \
-d '{"redaction_enabled": false}'
Catégories de liste blanche : ner_skiplist, domain_allowlist, known_persons, known_orgs, known_hostnames
Inspectez ce que fait le proxy en temps réel :
# Lister les sessions actives
curl http://localhost:8090/token-proxy/sessions