RC RANDOM CHAOS

ZCode ships your deleted secrets offsite

AI coding agents like ZCode read your entire Git history and can upload deleted secrets to remote servers. What leaks, why it is silent, and how to stop it.

· 7 min read
ZCode ships your deleted secrets offsite

A secret you deleted from your code three years ago is still sitting in your Git history. It is in the pack files under .git/objects, one git log -p away from anyone - or anything - that can read the folder. Point an AI coding agent at that repository and the deleted secret becomes eligible to leave your machine, bundled into the context the agent ships to a remote model. You will not get a prompt. You will not see a progress bar. The upload is a side effect of the agent doing exactly what it was built to do.

ZCode, a coding agent built on the GLM model family, is a useful case to reason about because it makes the general problem concrete. GLM’s inference runs on servers operated by a third party. For the agent to answer questions about your code, your code has to reach those servers. The question is never whether data leaves - that is the design. The question is how much, which parts, and whether you had any idea it included your history.

How an agent ends up holding your whole repository

An AI coding agent is a context-gathering machine. To answer “why is this test failing,” it reads the failing file, the files it imports, the config, and often the recent commit log to understand what changed. Many agents run shell commands to do this. git log, git diff, git show, and git blame are standard tools in that kit. The moment an agent runs git log -p, it is reading the full text of past changes, not the current state of your files.

That distinction matters more than it sounds. Your working directory is the code as it exists today. Your Git history is every version of every file that was ever committed, including the ones you thought you removed. A commit that added an .env file and a later commit that deleted it both live in history forever. The delete does not erase anything; it records that the file is gone going forward. The original blob stays in the object database.

So when an agent gathers “context,” the surface area is not your current code. It is the entire recorded life of the project.

Why history is the worst place to have made a mistake

Secrets end up in Git history constantly, and almost always by accident. Someone hardcodes an API key to test something on a Friday, commits it, and swaps it for an environment variable on Monday. The Monday commit looks clean. The repository is not. The key is preserved in the Friday commit, retrievable by anyone who runs git log -p or git show on that hash.

The reason this is dangerous with AI agents specifically is that history is a place nobody looks. You can scan your working tree with a secret scanner and get a clean result while a dozen live credentials sit three hundred commits back. GitGuardian has reported millions of secrets leaked through public commits every year - and those are only the public ones. Private repositories have the same problem with none of the outside scanning.

Feed that history to a remote model and you have taken a mistake that was buried and quiet and turned it into data in transit, stored and processed on infrastructure you do not control.

”Silent” describes the architecture, not a motive

It is tempting to frame this as a coding agent sneaking your data out. That framing is wrong, and it makes the problem harder to fix. Nothing is sneaking. The agent uploads context because uploading context is how a cloud model works. The silence is structural: there is no natural point in the workflow where the tool stops and says “I am about to send commit 4a3f9c, which contains a file called secrets.py.”

Three design choices produce that silence. First, cloud inference means code has to leave the machine to be useful - that is the baseline, not an add-on. Second, telemetry and diagnostics are often on by default, so usage data and error reports flow out on top of the code itself. Third, the agent, not you, decides what counts as relevant context, so you never approve the specific files or commits that go into a given request.

None of those require bad intent. All three together mean sensitive data can leave without a single explicit decision from you. When you evaluate any coding agent, that is what “silent” should mean to you - not that someone is lying, but that the system has no seam where you would have caught it.

Where the data actually goes

When your code reaches a remote model, two things change that you should track. It is now on hardware owned by another company, and it is subject to that company’s retention policy and legal jurisdiction. GLM is developed and operated by a company based in China, which means data sent to it may be processed under a legal framework different from your own and outside the reach of, say, GDPR or your own contracts.

This is not a claim about any one country being uniquely risky. The same reasoning applies to a US-hosted model for a European company, or any SaaS agent for a regulated business. The plain fact is that once your commit history is on someone else’s servers, you are trusting their storage, their access controls, their staff, and their government’s subpoena power. Read the data-handling terms before you decide that trust is warranted. “We do not train on your data” and “we do not retain your data” are different promises, and many services make only the first.

Assume it already happened, then check

If you have already run a cloud coding agent against a repository with history you never scanned, the useful posture is to assume the exposure occurred and verify rather than hope. There is rarely a clean log entry that says “your secret was uploaded,” so you work backward. Pull the vendor’s data or activity dashboard if one exists and look at what was sent. Check your own outbound network logs for the time windows the agent ran. Most importantly, inventory every credential that has ever lived in that repository’s history - using a gitleaks or trufflehog scan - and rotate all of them. Rotation is the one action that does not depend on knowing exactly what left; it makes the exposed copy worthless regardless.

This is also the honest answer to “how bad is it.” You usually cannot prove a specific secret was read. You can prove which secrets were exposed to the tool, and you can neutralize each one. Certainty about the leak is expensive and often impossible; rotation is cheap and final.

What to check before you point an agent at a repository

Treat every repository you open in an AI coding agent as if its entire history is about to be read out loud. That assumption is close enough to true to be useful.

Scan the history, not just the working tree. gitleaks detect and trufflehog git file://. both walk every commit and flag credentials. Run them across the full log before you connect any agent, not just against the current files. If either finds something, the fix is not to delete the file now - it is already too late for that - but to rotate the credential so the exposed version stops working.

Read the agent’s data settings before the first run. Look specifically for what it sends by default: does it transmit telemetry, does it include Git metadata, can you disable diagnostic uploads, and does it offer a local or self-hosted model option for sensitive work. If the documentation does not answer those questions plainly, treat the answer as “yes, it sends more than you want.”

Control the network, not just the config. An agent can only upload what it can reach. Running it in a sandbox with no network access, or with an egress allowlist that blocks unknown endpoints, turns “trust the vendor” into “verify the traffic.” For a genuinely sensitive codebase, a locally hosted model keeps the code on your machine and removes the question entirely.

The purge almost nobody runs

Rotating a leaked credential stops it from working, but the string is still in your history. If you need the history itself clean - before open-sourcing, before handing a repo to a contractor, before pointing a cloud agent at it - you have to rewrite it. git filter-repo is the current tool for this; the older BFG Repo-Cleaner does the same job for large repositories. Both remove the offending blobs from every commit and force you to re-push a rewritten history, which every collaborator then has to re-clone.

It is disruptive, which is exactly why it is rare. Most teams rotate the key, tell themselves the repo is private, and move on. That was a defensible bet when the only readers of your history were people with clone access. It is a weaker bet once a tool whose job is to read everything and forward context to a remote model is running inside that clone.

The shift with AI coding agents is not that they introduced a new vulnerability. Secrets have been rotting in Git history since Git existed. The shift is the reach. A tool that reads your whole repository and sends the relevant parts to a server you do not control turns a dormant, private mistake into live, transmitted data - quietly, as designed, every time it decides your history is relevant.

Share

Keep Reading

Latest on the Wire

Full wire →

New signal daily · RSS

Stay in the loop

New writing delivered when it's ready. No schedule, no spam.