SSD Nodes Learn 🎉 VPS dès $5.50/mois
Guides Matt ConnorPar Matt Connor

Télémétrie des coding agents : que transmettent-ils ?

Quatre flux sortent d’un coding agent, mais un seul est incontournable. Apprenez à les auditer depuis la machine et à bloquer ceux que vous n’avez pas acceptés.

Ce que couvre réellement la télémétrie des coding agents

La télémétrie d’un coding agent regroupe quatre flux de données distincts sous un même terme, et chacun possède son propre contrôle. L’inférence du modèle transmet vos prompts et votre code au fournisseur qui sert le modèle ; aucun paramètre ne permet de la désactiver. Les analytics produit et les rapports de crash sont envoyés à l’éditeur, et souvent à une entreprise de logging rémunérée par celui-ci. La conservation des données à des fins d’entraînement relève d’une question contractuelle, pas d’une question réseau. Le quatrième flux est souvent oublié : chaque intégration que vous ajoutez peut ouvrir une connexion vers un hôte que vous n’avez pas choisi.

La liste des valeurs par défaut actuelles des fournisseurs est la partie de ce sujet qui évolue le plus vite. Une release peut modifier une valeur par défaut, et une nouvelle fonctionnalité peut ajouter une destination qu’aucun switch existant ne contrôle. La compétence durable consiste donc à réaliser un audit que vous pouvez répéter avec n’importe quel agent : lire la documentation du fournisseur, vérifier quelle configuration a réellement été appliquée sur cette machine, monitorer le processus depuis la machine elle-même, puis choisir les contrôles que vous acceptez de financer. Chaque commande ci-dessous s’exécute sur votre propre machine et porte sur votre propre trafic.

Les quatre catégories et les raisons pour lesquelles elles nécessitent des contrôles différents

Le trafic d’inférence du modèle est inévitable. L’agent envoie votre prompt, les fichiers qu’il a lus, la sortie des commandes qu’il a exécutées et son propre texte généré vers un endpoint de modèle. C’est le fonctionnement normal du produit. La seule véritable décision concerne le destinataire : une API exploitée par un tiers ou un modèle que vous exécutez vous-même. Un compte cloud d’entreprise (Bedrock, Vertex, Foundry) change le destinataire, mais ne supprime pas le flux. Rien dans la suite de cet article ne réduit le trafic d’inférence. Vous devez donc le distinguer mentalement des trois autres catégories.

Les analytics produit et les rapports de crash correspondent à un autre flux vers d’autres hôtes. Les compteurs d’utilisation, les mesures de latence, les vérifications de feature flags et les stack traces sont généralement envoyés vers des hostnames qui n’ont aucun rapport avec l’API du modèle, souvent vers un outil tiers de suivi des erreurs. Les fournisseurs documentent généralement ces flux sous les termes « métriques » et « rapports d’erreur », et fournissent habituellement une variable d’environnement par catégorie. Le volume est minime. Les compteurs d’octets ne les détecteront donc jamais. Vous devez rechercher les hostnames, pas la bande passante.

La conservation et l’entraînement relèvent des règles, pas des paquets réseau. La conservation de vos prompts par le fournisseur, sa durée et l’utilisation éventuelle de ces prompts pour entraîner un futur modèle sont définies dans les conditions associées à votre offre. Les offres grand public et les offres commerciales diffèrent généralement, et un dispositif de conservation nulle fait normalement l’objet d’un accord distinct. Vous ne pouvez rien vérifier de tout cela avec tcpdump, car les paquets sont identiques dans les deux cas. Lisez les conditions et, si cela concerne votre employeur, obtenez une confirmation écrite.

Les intégrations ajoutent discrètement un saut réseau. Un serveur MCP (model context protocol), une marketplace de plugins, une vérification de mise à jour automatique, un outil de recherche web ou un contrôle de sécurité qui résout une URL avant de la récupérer : chacun correspond à une requête vers un hôte qui n’est pas l’endpoint du modèle. C’est là que se produisent les surprises, car un harness peut faire transiter par son propre service une tâche que vous pensiez locale, et une release peut commencer à le faire sans modifier une seule ligne de votre configuration. Considérez chaque outil ajouté comme une nouvelle destination jusqu’à ce que vous l’ayez observé sur le réseau.

Étape 1 : que documente l’éditeur ?

Ouvrez la référence des paramètres et la page consacrée à l’utilisation des données de votre agent. Lisez-les avec une liste de termes sous les yeux : metrics, analytics, error reporting, crash, feedback, survey, update check, safety check, marketplace. Chacun de ces termes correspond généralement à un switch distinct. Notez les noms exacts des variables, car l’étape 2 les recherchera avec grep.

Un terme peut vous induire en erreur. Dans plusieurs agents, « telemetry » désigne dans la documentation un export OpenTelemetry que vous configurez pour envoyer des metrics à un collector que vous gérez. C’est l’inverse d’un envoi de données à l’éditeur. Claude Code en fait partie : définir CLAUDE_CODE_ENABLE_TELEMETRY=1 active un export vers l’endpoint indiqué dans OTEL_EXPORTER_OTLP_ENDPOINT. Ce paramètre n’a aucun rapport avec les analytics de l’éditeur, qui disposent d’un autre mécanisme d’opt-out. Déterminez le sens du flux de données avant de modifier un paramètre.

Prévoyez un master switch, mais aussi des exceptions. En août 2026, CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC de Claude Code désactive simultanément les metrics, les rapports d’erreur, la commande feedback et les enquêtes de session. La même documentation précise que ce paramètre ne couvre pas le contrôle de sécurité du domaine WebFetch. Celui-ci envoie à l’API de l’éditeur le hostname que vous êtes sur le point de récupérer et possède son propre paramètre. Il ne s’agit pas d’un problème propre à un produit. C’est la structure du problème dans tous les cas : un master switch couvre les catégories qui existaient au moment de sa rédaction.

L’opt-out peut également avoir un coût. La même documentation indique que la désactivation de la telemetry désactive aussi l’évaluation des feature flags dont dépendent certaines fonctionnalités. Un switch activé pour protéger la confidentialité peut donc désactiver une fonctionnalité que vous utilisez, sans message d’erreur établissant le lien entre les deux. Lisez la phrase située à côté du flag, et pas uniquement le nom du flag.

Étape 2 : quelle configuration a réellement été appliquée ?

Un paramètre que vous avez écrit n’est pas nécessairement un paramètre qui a été appliqué. Les agents fusionnent la configuration provenant de plusieurs fichiers, dont l’un se trouve dans le dépôt que vous venez de cloner depuis un tiers. Commencez par l’environnement de votre propre shell.

env | grep -Ei 'telemetry|otel|analytics|error_report|do_not_track|proxy'

Affichez ensuite tous les fichiers de configuration lus par l’outil, dans l’ordre indiqué par la documentation. Pour Claude Code, en août 2026, il s’agit du fichier utilisateur, des deux fichiers du projet et d’un répertoire de stratégie gérée sous Linux.

for f in ~/.claude/settings.json .claude/settings.json .claude/settings.local.json; do
  echo "== $f"; [ -f "$f" ] && cat "$f"
done
ls -l /etc/claude-code/ 2>/dev/null

Un fichier de projet arrivé avec un git clone contient une configuration écrite par un tiers. Elle peut réactiver un paramètre que votre fichier utilisateur avait désactivé. Si l’agent dispose d’une commande d’état qui répertorie les sources chargées, c’est la référence la plus fiable : Claude Code affiche les sources de configuration chargées dans /status.

Le contrôle le plus fiable lit le processus en cours plutôt qu’un fichier. Commencez par attribuer à l’agent son propre compte utilisateur Linux. Cela raccourcit toutes les commandes de cet article. Lisez ensuite l’environnement avec lequel le processus a été démarré.

pgrep -u agent -a node
sudo tr '\0' '\n' < /proc/$(pgrep -u agent -n node)/environ | grep -Ei 'telemetry|proxy|otel'

/proc/<pid>/environ affiche les variables présentes dans le processus au moment de l’exécution de exec. Cela permet de détecter le cas où votre export .bashrc n’est jamais parvenu à un service démarré par systemd. Si une variable que vous avez définie est absente ici, elle n’a jamais été appliquée, quels que soient vos fichiers dotfiles.

Étape 3 : à quels hôtes se connecte-t-il ?

Commencez par les sockets ouverts, en les filtrant selon le compte utilisé par l’agent.

sudo ss -tnpe state established

-e ajoute un champ uid: à chaque ligne. Vous pouvez ainsi distinguer les connexions de l’agent de celles de votre navigateur sans examiner les noms des processus. Notez les adresses distantes, puis recherchez les noms correspondants. La source de noms la plus fiable est la négociation TLS (transport layer security), car chaque nouvelle connexion commence par un ClientHello contenant un champ SNI (server name indication). Ce champ contient le nom d’hôte demandé par le client.

sudo apt install -y tshark
sudo tshark -i any -f 'tcp port 443' -Y 'tls.handshake.type == 1' \
  -T fields -e ip.dst -e tls.handshake.extensions_server_name

Vous obtenez une ligne par nouvelle connexion. C’est exactement l’inventaire recherché : l’API du modèle, le serveur de mise à jour, l’hôte d’analytics, le système de suivi des erreurs et tout ce qu’une intégration a ajouté. Une colonne de nom vide signifie que le client a utilisé ECH (encrypted client hello). Le nom d’hôte n’est donc pas visible sur le réseau. Utilisez alors l’adresse IP de destination, une recherche DNS inverse ou le proxy de l’étape 4.

La vue DNS (domain name system) constitue une vérification utile. Elle affiche les noms recherchés par l’agent, y compris pour les connexions qui n’ont pas abouti.

sudo tcpdump -ni any -l 'udp port 53'

Chaque ligne de requête se termine par le type d’enregistrement et le nom, sous la forme A? host.example.net. (39). Capturez le trafic sur any plutôt que sur l’interface externe. Avec systemd-resolved, l’application communique avec un listener stub local sur 127.0.0.53, et seul le stub communique avec l’extérieur. Si vous ne voyez aucun trafic DNS alors que l’agent fonctionne clairement, son runtime utilise directement DNS over HTTPS. Seule l’étape 4 vous fournira alors les noms.

Effectuez la capture pendant que l’agent réalise un travail réel. Démarrez une session, faites-lui lire un fichier, exécuter une commande, puis provoquer une erreur. Le trafic qui ne se produit qu’une fois au démarrage, ou uniquement lorsqu’une exception est levée, n’apparaît jamais dans une capture effectuée au repos. Or une capture au repos est le moyen le plus courant pour qu’un audit aboutisse à une conclusion erronée mais rassurante.

Étape 4 : que contiennent les requêtes ?

Les noms d’hôte indiquent qui contacter. Pour voir le contenu des requêtes, placez un proxy que vous contrôlez devant l’agent et faites-lui confiance uniquement pour l’autorité de certification (CA) de ce runtime. mitmproxy est l’outil habituel. Le projet recommande les binaires autonomes disponibles sur mitmproxy.org et documente uv tool install mitmproxy comme méthode d’installation via le package Python.

mitmdump -w /tmp/agent-flows.mitm

Lors de sa première exécution, l’outil écrit une CA dans ~/.mitmproxy/, où mitmproxy-ca-cert.pem correspond au certificat seul. Dans le shell depuis lequel vous lancerez l’agent, configurez le client pour utiliser le proxy et ce certificat.

export HTTP_PROXY=http://127.0.0.1:8080
export HTTPS_PROXY=http://127.0.0.1:8080
export NODE_EXTRA_CA_CERTS="$HOME/.mitmproxy/mitmproxy-ca-cert.pem"
export REQUESTS_CA_BUNDLE="$HOME/.mitmproxy/mitmproxy-ca-cert.pem"
export SSL_CERT_FILE="$HOME/.mitmproxy/mitmproxy-ca-cert.pem"

De nombreux CLI d’agents sont des programmes Node, et Node lit NODE_EXTRA_CA_CERTS au démarrage du processus. Exportez donc cette variable avant de lancer l’agent, et non dans un autre terminal ensuite. Les clients Python lisent REQUESTS_CA_BUNDLE ou SSL_CERT_FILE, et un binaire Go utilisant la bibliothèque standard lit SSL_CERT_FILE sous Linux. Vérifiez que le chemin fonctionne avec curl avant d’incriminer l’agent.

curl -sS -o /dev/null -w '%{http_code}\n' https://example.com

Un proxy fonctionnel affiche 200, et la requête apparaît dans la sortie de mitmdump. Une CA non approuvée produit curl: (60) SSL certificate problem: self-signed certificate in certificate chain. L’équivalent dans un agent Node est une erreur contenant le code SELF_SIGNED_CERT_IN_CHAIN. Consultez ensuite les flux enregistrés avec le visualiseur de console. Vous pourrez y ouvrir une requête et lire ses en-têtes et son corps.

mitmproxy -r /tmp/agent-flows.mitm

Quatre résultats méritent d’être distingués. Vous voyez les requêtes. Vous pouvez alors les lire et prendre une décision. L’agent refuse de démarrer avec une erreur de certificat. Il s’agit d’un problème de confiance dans ce runtime, et non d’un constat concernant le fournisseur. Vous ne voyez que l’API du modèle. Cela signifie que les autres catégories sont désactivées ou qu’elles se déclenchent lors d’un événement que vous n’avez pas provoqué. Enfin, vous ne voyez absolument rien alors que l’agent fonctionne clairement. Le client ignore alors les variables d’environnement du proxy ou utilise le certificate pinning. Aucun paramètre applicatif ne peut donc être considéré comme fiable pour vous indiquer la réalité. Ce dernier résultat est le plus important. Il vous ramène à l’étape 3, car une capture de paquets ne peut pas être convaincue de ne pas voir une connexion.

Contrôles, du plus faible au plus fort

Paramètres d’exclusion. C’est l’option la moins coûteuse et la moins efficace, car elle repose sur le respect de ces paramètres par l’éditeur et ne couvre qu’une catégorie déjà existante. Configurez-les à un emplacement qui persiste après un redémarrage et dans un nouveau terminal, dans le fichier de paramètres utilisateur ou dans votre profil shell. Ajoutez aussi DO_NOT_TRACK=1 pendant que vous y êtes : de nombreux outils en ligne de commande le respectent, notamment certains agents, et cela ne coûte rien. Reprenez ensuite l’étape 3 après la prochaine mise à jour, car c’est à ce moment que la couverture change.

Restriction du trafic sortant. Vous cessez alors de demander et commencez à imposer une règle. Exécutez l’agent avec son propre compte utilisateur, puis autorisez pour ce compte le loopback et le DNS et bloquez le reste. Cela ajoute sa propre table et laisse donc intactes les règles de pare-feu existantes.

table inet agentegress {
  chain output {
    type filter hook output priority filter; policy accept;
    meta skuid "agent" ip daddr 127.0.0.0/8 accept
    meta skuid "agent" udp dport 53 accept
    meta skuid "agent" counter log prefix "agent-egress-drop " drop
  }
}

Appliquez-la avec sudo nft -f /etc/nftables.d/agent.nft, surveillez le compteur avec sudo nft list table inet agentegress et consultez les paquets bloqués avec sudo journalctl -k -g agent-egress-drop. Un compteur de paquets bloqués qui augmente avec un nom d’hôte inattendu est précisément le résultat recherché. Deux limites importantes. meta skuid correspond à l’utilisateur propriétaire de la socket. Cette règle ne tient donc que tant que ce compte ne peut pas devenir un autre utilisateur : un sudo sans mot de passe pour l’agent transforme cette règle en simple suggestion. De plus, laisser UDP 53 ouvert vers n’importe quel serveur conserve un canal capable d’exfiltrer des données dans les noms de requêtes. Fermez donc aussi ce canal si votre modèle de menace l’exige, en configurant le résolveur de l’agent pour qu’il utilise un hôte que vous administrez. Les listes blanches de noms d’hôte doivent être configurées dans un proxy plutôt que dans nftables, car les endpoints d’API sont hébergés derrière des réseaux de diffusion de contenu dont les adresses IP changent sans préavis. Le coût de ce contrôle est le risque de panne et la maintenance : les installations de paquets, git via SSH et la vérification de mise à jour de l’agent échouent jusqu’à ce que vous les autorisiez, et cette liste vous appartient désormais. Si vous mettez cela en place sur un serveur plutôt que sur un laptop, la même organisation des comptes et du pare-feu constitue la base de l’exécution sûre de Claude Code sur un VPS.

Une machine jetable. Donnez à l’agent une machine virtuelle (VM) qui ne contient aucun identifiant important et qui est détruite à la fin de la tâche. Cela ne réduit pas ce que l’agent envoie ; cela réduit ce à quoi il peut accéder pour l’envoyer, ce qui correspond généralement au risque qui vous importe réellement. Combinez cette approche avec les règles de trafic sortant ci-dessus, car une VM neuve avec un accès Internet sans restriction peut tout de même atteindre chaque hôte présent dans votre périmètre de collecte. La méthode et l’état à recréer à chaque fois sont présentés dans l’exécution d’agents de programmation dans une VM jetable, et la question du dimensionnement dans l’exécution d’un agent de programmation sur un VPS.

Héberger soi-même le modèle. C’est le seul contrôle qui supprime le flux d’inférence, car l’invite ne quitte jamais votre matériel. Le coût est réel : vous ne pouvez pas héberger vous-même un modèle fermé. Cela implique donc de choisir des poids ouverts, d’accepter un écart de capacités pour les tâches complexes et de disposer du matériel nécessaire pour les servir. Ce compromis est analysé dans la possibilité d’héberger vous-même Claude, et les différences de capacités entre les principaux agents dans les différences entre Claude Code, Cursor, Codex et Copilot.

Aucun de ces quatre contrôles ne modifie ce que l’agent est autorisé à lire sur le disque, et le trafic d’inférence transporte tout ce qu’il lit. Si un fichier .env se trouve dans le répertoire de travail, il est envoyé au modèle dès que l’agent recherche un nom de variable avec grep. Garder ces données hors de sa portée est une tâche distincte, présentée dans la protection des secrets dans le contexte d’un agent d’IA.

Vérifications à effectuer après chaque mise à jour

  1. Comparez les pages du fournisseur consacrées aux paramètres et à l’utilisation des données avec vos relevés précédents. Recherchez les nouveaux commutateurs et les nouveaux services nommés.
  2. Relisez l’environnement du processus depuis /proc/<pid>/environ pour confirmer que vos options de retrait sont toujours appliquées au processus en cours d’exécution.
  3. Affichez de nouveau les fichiers de paramètres du projet, car un git pull peut charger un fichier de configuration modifié par un collègue.
  4. Effectuez la capture SNI pendant une session complète de travail réel, puis comparez la liste des noms d’hôte avec la précédente.
  5. Vérifiez le compteur des paquets rejetés par le pare-feu, car une nouvelle destination y apparaît généralement avant que vous ne la remarquiez ailleurs.

Cette vérification prend environ dix minutes. C’est la seule partie du processus qui ne devient pas obsolète. Une valeur par défaut vérifiée en août 2026 est un fait concernant août 2026. La capture est un fait concernant aujourd’hui.

FAQ

Puis-je empêcher mon agent de programmation d’envoyer mon code au modèle ?

Non, et tout paramètre qui affirme le contraire décrit autre chose. L’envoi de votre prompt, des fichiers lus par l’agent et de la sortie des commandes qu’il a exécutées vers l’endpoint du modèle est le fonctionnement même de l’inférence. La seule variable est donc le destinataire. Vous pouvez modifier ce destinataire en configurant l’agent pour utiliser un compte cloud d’entreprise ou un modèle que vous hébergez vous-même. Vous pouvez aussi réduire les données envoyées en limitant les fichiers qu’il est autorisé à lire. La désactivation des analytics et du signalement des erreurs ne modifie aucunement ce flux.

Comment voir les hôtes auxquels mon agent de programmation se connecte-t-il ?

Exécutez l’agent avec son propre utilisateur Linux, puis capturez le TLS ClientHello de chaque nouvelle connexion pendant son utilisation : sudo tshark -i any -f 'tcp port 443' -Y 'tls.handshake.type == 1' -T fields -e ip.dst -e tls.handshake.extensions_server_name. Une ligne apparaît par connexion, avec l’adresse de destination et le nom d’hôte demandé. Vérifiez les noms avec sudo tcpdump -ni any 'udp port 53', en capturant sur any, car un stub de résolution local sur 127.0.0.53 traite d’abord la requête. Effectuez la capture pendant que l’agent exécute un vrai travail, car les pings de démarrage et les rapports de crash n’apparaissent jamais dans une capture réalisée lorsque l’agent est inactif.

Mon proxy n’affiche aucun trafic pendant que l’agent fonctionne. Que s’est-il passé ?

Soit le client ignore HTTP_PROXY et HTTPS_PROXY, soit il utilise le certificate pinning et refuse votre CA. Testez d’abord le chemin avec curl : si curl accède à Internet via le proxy et que l’agent n’apparaît pas dans la liste des flux, c’est qu’il n’utilise pas les variables d’environnement du proxy. Certains runtimes exigent que la CA soit fournie d’une manière particulière. Node, en particulier, ne lit NODE_EXTRA_CA_CERTS qu’au démarrage du processus. L’exporter après le lancement de l’agent n’a donc aucun effet. Lorsque le proxy ne peut pas voir le trafic, utilisez une capture de paquets, car aucun paramètre de l’application ne peut la contourner.

La désactivation de la télémétrie empêche-t-elle l’utilisation de mon code pour l’entraînement ?

Non. Les analytics et le signalement des crashs constituent un flux différent de celui de l’inférence. Leur désactivation supprime donc les compteurs d’utilisation et les stack traces, mais laisse chaque prompt envoyé au modèle exactement comme avant. La conservation de ces prompts et leur utilisation éventuelle pour entraîner un futur modèle dépendent des conditions de votre offre. Les offres grand public et les offres commerciales diffèrent généralement sur ce point. Il s’agit d’une question contractuelle, et non d’un paquet à capturer. Consultez donc la page d’utilisation des données correspondant à votre offre et, lorsque c’est nécessaire, mettez en place un accord commercial ou zero-retention avant la première session.

#telemetry#privacy#coding-agents#secrets#auditing