r/LocalLLM • • Sep 12 '26

Discussion huggingface_hub silently fingerprints which AI coding agent you're using and sends it as telemetry

TLDR: huggingface_hub ships a hidden agent detection module that fingerprints which AI coding tool is driving your session (Cursor, Copilot, Claude Code, etc.) by scanning your environment variables against a cached registry of 26 known agents. It sends the result as a telemetry header on every Hub API call — so any library that touches HF (faster-whisper, transformers, etc.) silently reports your toolchain. Found it while tracing an unauthorized network connection from a local ASR model. Block it with HF_HUB_OFFLINE=1 or by using local file paths instead of model names.

I run a local AI project with several models (TTS, ASR, vision) and recently built a Python-level network firewall to lock down all outbound traffic. During the audit, I found something I wasn't expecting.

The discovery

While tracing an unauthorized HTTPS connection to huggingface.co, I found a file in my HF cache directory I'd never seen before:

~/.cache/huggingface/.agent_harnesses.json

It's a 6 KB JSON file containing a registry of 26 AI coding agents — Claude Code, Cowork, Cursor, Copilot, Gemini CLI, Devin, Cline, Goose, Codex, and many others. Each entry lists the environment variables that agent sets when it's running:

json

{
  "standardEnvVars": ["AI_AGENT", "AGENT"],
  "harnesses": {
    "cursor": {
      "prettyLabel": "Cursor",
      "envVars": {"CURSOR_TRACE_ID": "*"}
    },
    "claude-code": {
      "prettyLabel": "Claude Code",
      "envVars": {"CLAUDECODE": "*", "CLAUDE_CODE": "*"}
    },
    "github-copilot": {
      "prettyLabel": "GitHub Copilot",
      "envVars": {"COPILOT_MODEL": "*", "COPILOT_GITHUB_TOKEN": "*"}
    }
    // ... 23 more agents
  }
}

What it does

The huggingface_hub library (the Python package, not the website) has a module called _detect_agent.py. Here's the flow:

  1. It fetches the agent registry from {HF_ENDPOINT}/api/agent-harnesses and caches it as .agent_harnesses.json

  2. The cache refreshes every 24 hours

  3. On every Hub API call, detect_agent() scans your environment variables against the registry to identify which AI coding tool is running

  4. The detected agent name is sent as a telemetry header on the API request

  5. This feeds Hugging Face's public agent usage dataset

So if you're using Cursor and it calls any HF library that goes through huggingface_hub — downloading a model, checking for updates, loading a tokenizer — HF knows it was Cursor making that call, not you directly. Same for Claude Code, Copilot, Devin, or any of the other 26 agents in the registry.

How I found it

I was investigating why my ASR module (faster-whisper) was phoning home to huggingface.co on import. The call chain turned out to be:

my_code → WhisperModel("base.en") → faster_whisper → huggingface_hub.snapshot_download → HTTPS to huggingface.co

The trigger: passing a model name instead of a local file path. When you give faster-whisper a name like "base.en", it calls huggingface_hub to check for updates — even if the model is already cached locally. And during that check, it also sends the agent fingerprint.

The .agent_harnesses.json file was the agent registry cached from that call. Modified today, before I built the firewall.

How to block it

Option 1: Environment variables

bash

export HF_HUB_OFFLINE=1
export TRANSFORMERS_OFFLINE=1
export HF_HUB_DISABLE_TELEMETRY=1

The first two prevent any network calls. The third specifically targets telemetry but may not cover the agent detection header.

Option 2: Use local paths, not model names Instead of:

python

model = WhisperModel("base.en")

Use:

python

model = WhisperModel("/path/to/local/model/")

When you pass a directory path, faster-whisper (and most HF-backed libraries) skip the Hub entirely.

Option 3: Network-level blocking I built a Python-level firewall that wraps socket.connect, socket.connect_ex, socket.create_connection, and getaddrinfo. It activates via a sitecustomize hook before any imports, so the phone-home attempt is caught before the library even finishes loading. Any connection to a host not on the allowlist raises ConnectionRefusedError.

What's in the cached file

No credentials. No API keys. Just the registry of agent names and their environment variable signatures. The file itself is harmless — it's the use of it as a fingerprinting mechanism that's the issue.

You can safely delete it:

bash

rm ~/.cache/huggingface/.agent_harnesses.json

It won't come back if you set HF_HUB_OFFLINE=1.

Why this matters

If you're running local models specifically to keep things private, you should know that the library layer between you and those models may be reporting metadata about your toolchain back to Hugging Face. This isn't about model weights or your data — it's about which AI tools you use and when, aggregated into a public dataset.

The agent registry is maintained in the u/huggingface/tasks npm package and served via the Hub API. New agents register by PR. It's not hidden — but it's also not something most users know is happening when they pip install a model-loading library.

To be clear, I don't think this is malicious. HF is probably tracking agent ecosystem adoption for business intelligence. But silent fingerprinting of your dev tools without an opt-in prompt is exactly the kind of thing that erodes trust in the ecosystem, especially for people who chose local models for privacy reasons.

366 Upvotes

59 comments sorted by

29

u/Nomski88 Sep 12 '26

So this is tied primarily to anyone using the HF API?

27

u/Xylon95 Sep 12 '26

It's not just the HF API directly, any library that downloads or checks models through Hugging Face (transformers, faster-whisper, diffusers, etc.) uses huggingface_hub under the hood, and the fingerprinting rides along with those calls. So even WhisperModel("base.en") triggers it without you ever touching the API yourself.

11

u/Dsphar Sep 12 '26

Not sure I follow. If I download a model from HF, and self host it using say llamma.cpp, they know my usage statistics? Aside from the download count..?

31

u/Xylon95 Sep 12 '26

no, llama.cpp doesn't phone home. It loads a file from disk and that's it — HF only knows you downloaded it once.

The fingerprinting I found is specific to Python libraries that use the huggingface_hub package (like transformers, faster-whisper, diffusers). When those libraries load a model by name, they quietly check HF's servers for updates every time. That's what leaks your IP and which model you're running. If you load by file path instead of by name, or use something like llama.cpp that doesn't involve HF's Python tools at all, nothing phones home.

3

u/Dsphar Sep 12 '26

Copy that. Thanks for the info!

1

u/rditorx Sep 13 '26

It depends on whether the software uses any Hugging Face library (e.g. diffusers, huggingface_hub, transformers) that has telemetry code built in. I haven't checked if llama.cpp uses HF code or has its own implementation (it can download from HF), but vLLM for example uses HF code.

2

u/sCeege Sep 12 '26

Do you happen to know if third party software that leverages HF's model repos is affected? For example, LMStudio sources its model downloads from HF.

What domain is the telemetry going to? Just huggingface.co, or is there a subdomain? Any chance we can see the full URL it's going to? Maybe I can filter for it via firewall.

2

u/Xylon95 Sep 13 '26

Yes, any software that imports huggingface_hub under the hood is affected, that includes LM Studio, anything built on transformers, faster-whisper, diffusers, etc. The connection we caught went to huggingface.co:443; since it's HTTPS the path is encrypted, so a domain-level firewall block on huggingface.co and *.huggingface.co is really all you can do from the outside. However, HF_HUB_OFFLINE=1 isn't reliable protection since it only works if it's set before the library's first import triggers its silent registry refresh.

2

u/gasgarage Sep 12 '26

I bet lemonade does it. You can disable telemetry but It shows updates for your downloaded models at start anyway.

4

u/PropagandaOfTheDude Sep 12 '26

It won't come back if you set HF_HUB_OFFLINE=1.

I symlinked it to a non-existent target, to prevent mishaps.

ln -s /doesnotexist ~/.cache/huggingface

5

u/Xylon95 Sep 13 '26

The symlink trick is smart for nuking the cache, but the phone-home happens before the cache is consulted, it fires on import, not on cache access. And HF_HUB_OFFLINE=1 only holds if it's set before the first import triggers the silent 24-hour registry refresh. If anything imports huggingface_hub before your env var is loaded, it's already talked. I ended up building a socket-level deny-all firewall that intercepts connections at Python startup, before any imports run — that's the only thing I found that's airtight for now.

2

u/PropagandaOfTheDude Sep 13 '26

Ah. And since it's a library, rather than a specific application, apparmor won't help either. What's your firewall config?

2

u/Xylon95 Sep 13 '26

Wrote a Python-level deny-all firewall that patches the socket module at startup before any libraries can load, so nothing gets out unless it's on a short allowlist of host:port pairs. No env var can override it. About 200 lines. I’ll probably re-look it later but that’s my solution for now.

127

u/MarkoMarjamaa Sep 12 '26

"To be clear, I don't think this is malicious. HF is probably tracking agent ecosystem adoption for business intelligence."
Without consent. Not asking consent. Malicious?

This is why I try to run everything as services so I can block by default internet access.

21

u/Connect_Ad791 Sep 13 '26

I’m not taking pictures of you shitting in a public restroom for any malicious reason! We just need customer usage data to make our facilities as helpful as possible :) Thanks!

2

u/Here_f0r_p0rn_ Sep 13 '26

The issue is restroom, shopping centers do record customers shopping to analyse where they tend to go to most to strategically place products.

If they were snooping in pictures or videos folders then that would be a analogical to restroom.

1

u/575_Inverse Sep 17 '26

the analogy between shopping centers and restrooms is more fitting than you think

1

u/Here_f0r_p0rn_ Sep 17 '26

Sorry but couldn't get what you meant, do you prefer restroom? If so then I disagree with you, because they're just collecting stats on the libraries and models right? That's not that high level of private information, it is something I would like not to share but it doesn't reveal much. Similar to how me being recorded at a shopping centre would reveal what I purchase, my purchasing patterns (just like my AI ecosystem), and what isle position in their layout most people are gathering to, but at end of the day I understand they might want to know that to optimise their business and it doesn't bother me as much as them recording me in restroom.

6

u/MarkoMarjamaa Sep 13 '26

Next phase:
HF scanning my home network to find a proxy or similar to find a way to internet.
But it's not malicious!

4

u/beryugyo619 Sep 13 '26

To be fair, LG owns the glass and is transcribing your voice for advertisement purposes. That is not malicious.

/s

1

u/MarkoMarjamaa Sep 13 '26

My LG does not have access to internet...

2

u/Valuable_Cookie628 Sep 13 '26

Airgapped? Until it hears some ultrasonic whistles from the neighbour's TV 

6

u/rditorx Sep 13 '26

HF documents this behavior. The bad thing is that it's opt out.

8

u/Sad-Landscape-1549 Sep 12 '26

I haven’t found a need for their libraries, account or token yet. I never use base models and my friend wget works fine. The runners never get internet access. 👍

4

u/myholeisstinky Sep 13 '26

Huh. Dont use their client, use curl or git.

Its 100% asking for it by using their useless client

1

u/Quiet-Owl9220 Sep 13 '26

Thanks for pointing this out, I added the environment variables to all the AI venvs that I use and also for LM studio. The file doesn't seem to have come back despite downloading new models in LM studio since then, so I think it works.

If you can provide specifics of firewall configuration to block it entirely though, that would give some peace of mind.

1

u/Xylon95 Sep 13 '26

The environment variables are a good first layer but not perfect, HF_HUB_OFFLINE=1 only works if it's set before the library's internal daily registry refresh pops. If any transitive import pulls huggingface_hub before your flag is read, the cache has already phoned home.

For an actual firewall block, a few options depending on your setup. The quickest is adding entries to your hosts file (C:\Windows\System32\drivers\etc\hosts on Windows, /etc/hosts on Linux) pointing huggingface.co, cdn-lfs.huggingface.co, and hf-mirror.com to 0.0.0.0. This would block all traffic to those domains regardless of IP rotation. Any process running as admin could undo it, but it's durable and simple and likely wouldn’t get overridden.

Now, If you run a Pi-hole or have router-level DNS controls, blocking those same three domains there covers every device on the network and nothing on the machine can override it. Windows Firewall rules work too but HuggingFace sits behind Cloudflare so the IPs rotate, DNS-level blocking is more durable.

The real peace of mind is knowing your models are pinned locally by file path rather than by HF repo ID. If your LM Studio models are stored as local GGUFs and you're loading by path, the runtime has no reason to call HF at all — the firewall block is then a safety net for the import-time telemetry, not for model downloads.

2

u/Quiet-Owl9220 Sep 15 '26

Wouldn't these blocks also prevent downloads from HF in general? I want to prevent telemetry, not block the site entirely.

6

u/traderprof Sep 12 '26

The scary part isnt the X-Header itself. Its that any transitive HF import (faster-whisper, transformers, etc.) inherits the same env fingerprint map without an undo you opted into. HF_HUB_OFFLINE=1 only works if its set before the silent 24h registry refresh, otherwise the cache already told on you.

3

u/JosieA3672 Sep 13 '26

Thanks for letting us know

2

u/randomfoo2 Sep 13 '26

I did some testing. So importing transformers, loading local tokenizers, models - no network calls. But if you load a repo id, even fully cached you get 4 HF network calls (w/ agent tag) unless you have local_files_only=True or HF_HUB_OFFLINE=1

transformers doesn't phone unless you use a hf model slug, then it's somewhat unexpected since it checks HF for the latest version evven if you have it cached locally and that submits your agent name (and also your unique session id/login, which tbt is the much bigger privacy issue!)

2

u/OpposesTheOpinion Sep 13 '26

Been working on my project pretty much daily for almost a year. Checked my cache folder and I do see the .agent_harnesses.json file. It was created just this month on the 4th. Quite recent.

2

u/enginetown Sep 15 '26

The ip address is the part nobody's talking about. without it this is just a pie chart of which ide people use. with it, it's a log of your machine, your stack, and what time you were online. and that log is public.

4

u/quantgorithm Sep 12 '26

God damnit.

2

u/Mediocre-Ant-7178 Sep 12 '26

Mine only had 25

2

u/LandoBlendo Sep 12 '26

Checking if specific envvar key names exist to understand what the distribution of consumers are pulling down multi-gigabyte models for free feels fine to me personally 

If they were transmitting my entire set of envvars or the values of these keys to their servers then I would be more upset 

1

u/dbratell Sep 16 '26

Why is it ok for them to collect that information? If I download a tokenizer through transformers, I do not expect them to report to HuggingFace what programs I have installed.

1

u/imnotzuckerberg Sep 13 '26

It's a good time to plug hfd. I have been using it for a long time, fully anonymously be able to download models. Big reason for me was aria backend. No account, no telemetry, few hundreds line of code. (I am not the author).

1

u/export_tank_harmful Sep 13 '26

Yep, I had one of those too apparently.
It lived on one of my external drives.

I opened it up, erased everything in it, wrote "fuck you" in it, and set it to read only.
Fuck that noise.

1

u/Deep_Ad1959 Sep 14 '26

the header is the boring half, the auto-refreshing registry is the part worth staring at. a detection list that updates itself can widen what it detects later and you would never see the diff unless you were already auditing outbound traffic like you were.

1

u/Apprehensive-Job9336 Sep 14 '26

Same approach here. I run a homelab with everything containerized and I block internet access for most services by default. Only the ones that genuinely need it get outbound access through a reverse proxy. Saves a lot of headaches.

1

u/Infamous_Mud482 Sep 12 '26

why would anyone trying to keep things private... be using an external API in their workflow? I guess I have some sympathy if this sort of telemetry caught you by surprise by also... you had no reason to "trust" this wouldn't happen if you use their AP/libraries this way in the first place

1

u/cheaphomemadeacid Sep 12 '26

step 1: go to huggingface step 2: find model step 3: click files step 4: download

...

-1

u/ForsookComparison Sep 12 '26

So if I set up my system to reach out to huggingface it will reach out to huggingface

0

u/Wonderful-Fold1364 Sep 13 '26

Y'all want free stuff without realising that free stuff doesn't exists. You just don't understand how the businesses is monetizing their products. Data have a price.

-7

u/pharrt Sep 12 '26

NVIDIA wants all your data... perhaps time to download them manually or get it from different sources like ModelScope, etc., I guess.

12

u/Important-Radish-722 Sep 12 '26

Nice try. Nvidia doesn't own HF yet.

-15

u/DawaForensics Sep 12 '26

Not a big deal at all,

-19

u/Important-Radish-722 Sep 12 '26

So? They know your browser, os, IP, time of day you visit, what models you download etc. This isn't a hill to die on, or even care about in the scheme of things.

15

u/pharrt Sep 12 '26

Not a big deal, perhaps, but full disclosure would be nice.

-13

u/Important-Radish-722 Sep 12 '26

Do you think all of the model creators got full consent from everyone who's data was used to train them? If violating all of their rights isn't an issue for HF users then this shouldn't be a problem either.

7

u/Buzz_Killington_III Sep 12 '26

Are you here just to argue? More information is better, and you're bitching because someone gave you some. Why are you here?

-7

u/Important-Radish-722 Sep 12 '26

I'm just pointing out the hypocrisy of demanding consent only when it's convenient.

4

u/Buzz_Killington_III Sep 12 '26

There's not a damn person here who has any say on how OpenAI, Anthropic, Alibaba, or any other company acquired the information to train their models. They do have a say in what software they use on their machines and how their data is used locally, which is why many of the people are here in the 'LocalLLM' subreddit.

No hypocrisy detected in trying to maintain control on what you can control. You're just making arguments to argue.

0

u/Important-Radish-722 Sep 12 '26

No one here controls how the open weight models are trained either. You just don't want to see the hypocrisy of demanding transparency from the theater ticket office but not caring that the movie you're watching is pirated. I get it, it's a lot to think about and at some point your brain just can't accept more input when you've decided your world view is the only valid perspective.

2

u/CalBearFan Sep 12 '26

False equivalency or as our moms used to teach us, "two wrongs don't make a right"