ZCode silently uploads full Git history – privacy breach analysis
ZCode uploads your entire Git history without consent
Takeaway: The ZCode desktop application encrypts the full .git directory of every logged‑in user, wraps the encryption key with a server‑only RSA public key, and uploads the archive to Alibaba Cloud’s OSS service. The user cannot decrypt the payload, and no UI toggle stops the exfiltration.
How the exfiltration works
Conclusion: ZCode’s client packs a tar.gz of the workspace, encrypts it with AES‑256‑CTR, wraps the symmetric key with a server‑provided RSA‑OAEP public key, and POSTs the ciphertext directly to an Aliyun OSS bucket.
- The client contacts
zcode.z.aito obtain a signed OSS form, an object key, a size cap, and a per‑upload RSA public key. - The payload includes the entire
.gitdirectory (objects, LFS cache, reflogs, config) and the working tree. - The encrypted archive is stored locally (e.g.,
~/.zcode/v2/checkpoints) but cannot be decrypted because the private RSA key resides only in Z.ai’s cloud. - After the upload, OSS calls back to Z.ai’s backend to register the snapshot.
The reconstructed flow diagram (see image in the source) shows a credential negotiation → local packing → encryption → direct OSS POST → backend callback sequence.
What is actually uploaded
Conclusion: Over 86 % of the uploaded data is the Git object store, which contains the full lineage of the repository, including deleted secrets, unreleased feature branches, and internal configuration.
| Content | Size (example) | Share of payload |
|---|---|---|
.git/lfs/ |
196.1 MB | 56.8 % |
.git/objects/ |
102.2 MB | 29.6 % |
.git/logs/ |
0.6 MB | 0.2 % |
| Source code & docs | 46.2 MB | 13.4 % |
A single 42 k‑file snapshot produced a 313 MB encrypted archive from a 345 MB workspace.
UI toggles do not block the upload
Conclusion: The two visible settings – Optimize Experience and Repo Snapshot Indexing – only affect downstream server‑side training or indexing; they do not prevent the client from packing and uploading the snapshot.
- The side‑car responsible for capture is instantiated unconditionally at startup, gated only by a valid JWT token.
- Session logs recorded 62 capture events in a single session, triggered before each prompt and on task completion.
- The agent’s tool surface (31 tools) contains no snapshot or telemetry commands; the exfiltration runs outside the tool loop.
Encryption key design confirms server‑only access
Conclusion: Envelope encryption uses a server‑only RSA key, meaning only Z.ai can decrypt the uploaded archive.
- The public key is delivered during the credential negotiation.
- Ferstar’s attempts to unwrap the archive with any local private key failed.
- The ciphertext stored on the user’s disk is therefore unreadable by the user or the client itself.
Privacy policy omission
Conclusion: ZCode’s official privacy policy mentions collection of “text, files, and code submitted during conversations” but makes no reference to full‑workspace or Git‑history uploads.
- No FAQ entry, changelog note, or policy amendment addresses the snapshot feature.
- The only related statement is a generic opt‑out for an “optimization program,” which does not cover the described behavior.
Community reaction and verification
Conclusion: The discovery quickly gained traction, with over 276 k views on Ferstar’s X thread and a parallel Chinese‑language alert reaching 63.8 k views.
- Petri Kuittinen, author of an open‑source AI agent, warned: “do NOT trust closed source AI harnesses.”
- Multiple independent analyses (e.g., OrcaPromptVault) corroborated the presence of a hidden checkpoint/revert feature that triggers the upload pipeline.
- Some users reported not seeing the
~/.zcode/v2/checkpointsdirectory, suggesting the mechanism may have been altered in later releases, but no official statement has been issued.
Mitigation steps
Conclusion: The only reliable mitigation is to block the client from writing the checkpoint directory at the filesystem level.
# Linux
rm -rf ~/.zcode/v2/checkpoints
mkdir -p ~/.zcode/v2/checkpoints
sudo chattr +i ~/.zcode/v2/checkpoints
# macOS
rm -rf ~/.zcode/v2/checkpoints
mkdir -p ~/.zcode/v2/checkpoints
chflags uchg ~/.zcode/v2/checkpoints
- This disables the checkpoint‑rollback UI but leaves chat, autocomplete, and tool calls functional.
- Re‑enable by removing the immutable flag (
chattr -iorchflags nouchg).
Broader implications for locally‑run models
Conclusion: Running open‑weight models locally does not guarantee privacy; the surrounding harness (desktop app, update service, telemetry layer) can still exfiltrate data.
- Trust must be extended to the entire runtime stack, not just the model weights.
- Two critical questions for any AI coding harness:
- What data is transmitted while the user is logged in?
- Who holds the decryption keys for any stored snapshots?
- Tokenstead (the source of this analysis) will continue to monitor Z.ai’s response and update the findings accordingly.
Key takeaways for developers
- Never assume open‑weight models imply a fully open stack. The harness may be closed and perform undisclosed telemetry.
- Inspect network traffic of any AI‑assisted IDE; look for outbound POSTs to cloud storage services.
- Prefer open‑source harnesses that publish their telemetry contracts and allow users to audit the code.
- Apply filesystem hardening (immutable directories) if you must use a closed‑source tool that you cannot audit.
References
- Ferstar, Inside ZCode: Silently Uploading Your Entire Git History to the Cloud, Sep 18 2026 – full forensic report.
- X threads by Ferstar (276 k views) and FeiZ (63.8 k views).
- ZCode changelog and privacy policy (official Z.ai site).
- OrcaPromptVault snapshot of ZCode system prompts.
- V2EX discussion (Chinese community response).
- Lookonchain coverage of the incident.
Sources
Related
- Dispatch
- Dispatch
- Dispatch
- Dispatch