← all posts
// security · security

Who made your GGUF? The supply chain nobody audits

Last autumn I caught myself doing something I would never sign off on in a code review. A 32B coder had just dropped, the official org hadn't published GGUFs yet, and a community account already had every K-quant lined up with a tidy README. I pulled 19 GB from a stranger and had it running inside a shell-capable agent the same evening.

We lock 40-line npm packages behind lockfiles and review. Then we do this.

there's more in the file than weights

A GGUF isn't just a tensor dump. It also carries tokenizer configuration, metadata, and the chat template: a chunk of Jinja-flavored text that wraps every prompt you will ever send through the model, and the part that rearranged my threat model once I actually thought about it. Whoever produces the file writes that template. Tampering with weights in a targeted way is genuinely hard. Editing a template is one line in a script before upload.

A template that quietly appends an extra instruction to the system region would pass every perplexity check and every eval you're likely to run. The model behaves, right up until it sits inside an agent loop with a fetch tool or shell access, which is precisely where coder models live in 2026. I know of no confirmed in-the-wild case. That comforts me not at all, because until last autumn I wasn't looking, and neither was anyone I asked.

A community quant is a stranger's build artifact with the build script thrown away.

provenance, cheap and boring

What I do now takes five minutes. Prefer quants published by the model's own org, or failing that by long-standing quantizers whose earlier uploads I've already cross-checked against official files. Verify the SHA256 that Hugging Face displays for every LFS file against what actually landed on disk. Read the template before trusting it:

sha256sum coder-32b-q4_k_m.gguf
ollama show my-coder --template

Then skim the repo the way you'd skim a PR from an unknown contributor: does it name the exact revision of the official weights it quantized from, does the file list contain anything besides model files and a README, does the account have a history older than this hype cycle. None of that is deep security work. It's hygiene, and hygiene catches the lazy majority of tampering.

the eleven days I ran the wrong template

Back to that autumn download. Eleven days in, the official GGUFs finally landed and I diffed the chat templates out of idle curiosity. They differed. Nothing sinister: the community version had reworked stop-token handling, probably a genuine fix. But I sat there realizing I had no way to enumerate what else differed, and the thing had been running with shell access since day one. I re-pulled from the official repo, re-hashed everything, and rewrote my personal policy that night.

Nobody attacked me, as far as I can tell. The point is I couldn't have told you either way.

quantize it yourself, for anything serious

The policy: anything that runs unattended, touches credentials, or sits inside an agent gets quantized by me, from official safetensors, with llama.cpp's conversion tooling. A 32B takes well under an hour on the closet box, and it removes the entire class of question. I also get exactly the quant I want instead of whatever someone uploaded. Community quants still have a place (weekend toys and quick evals, mostly), and even there I check that the license actually permits my use before anything goes near client work.

It's the same posture I argued for when vetting open agent harnesses: trust follows provenance, not popularity, and download counts measure hype. If you want to feel the difference in your gut, spend an afternoon red-teaming your own stack with a deliberately doctored template and watch how little anything downstream notices.

#security#gguf#local