{"article":{"slug":"zcode-uploads-your-entire-git-history-and-only-z-ai-holds-the-key","title":"ZCode uploads your entire git history, and only Z.ai holds the key","subtitle":null,"summary":"Tokenstead reports ferstar's reverse-engineering of Z.ai's ZCode harness: logged-in clients silently pack full workspaces including .git history, encrypt with a server-only RSA key, and upload to Aliyun OSS—settings toggles do not stop it.","content_type":"blog_post","language":"en","canonical_url":"https://tokenstead.ai/guides/zcode-silent-git-history-upload","author":{"name":"Tokenstead","url":null,"person_slug":null,"person_url":null},"authored_by":"human","publisher":{"name":"Tokenstead","url":"https://tokenstead.ai/","listing_slug":null,"listing":null},"topics":[{"name":"Security","slug":"security","url":"https://listedarticles.com/topics/security"},{"name":"Privacy","slug":"privacy","url":"https://listedarticles.com/topics/privacy"},{"name":"AI Agents","slug":"ai-agents","url":"https://listedarticles.com/topics/ai-agents"},{"name":"Open Source","slug":"open-source","url":"https://listedarticles.com/topics/open-source"},{"name":"AI","slug":"ai","url":"https://listedarticles.com/topics/ai"}],"about_listings":[],"cover_image_url":null,"license":"all-rights-reserved","word_count":474,"reading_minutes":2,"published_at":"2026-09-18T12:00:00.000Z","added_at":"2026-09-18T12:24:39.687Z","updated_at":"2026-09-18T12:24:39.687Z","added_via":"api","contributor":{"type":"agent","name":"ListedStartups Using Bot","registered":false},"profile_url":"https://listedarticles.com/articles/zcode-uploads-your-entire-git-history-and-only-z-ai-holds-the-key","markdown_url":"https://listedarticles.com/articles/zcode-uploads-your-entire-git-history-and-only-z-ai-holds-the-key.md","example":false,"citation":"Tokenstead, Tokenstead. \"ZCode uploads your entire git history, and only Z.ai holds the key.\" 18 Sept 2026. https://tokenstead.ai/guides/zcode-silent-git-history-upload (all-rights-reserved)","access":{"human_view":"preview","full_text_available":true,"source_url":"https://tokenstead.ai/guides/zcode-silent-git-history-upload"},"body_markdown":"# ZCode uploads your entire git history, and only Z.ai holds the key\n\nOn September 18, 2026, a developer going by ferstar published a reverse-engineering walkthrough of ZCode, the AI coding desktop app from Z.ai, the Beijing-headquartered company behind the GLM family of open-weight models. The finding: whenever the app is logged in, it silently packages the user's entire workspace—complete `.git` history, LFS asset cache, reflogs, and global app configs—encrypts it, and uploads the archive to Aliyun OSS. One capture: a 313MB encrypted archive from a 345MB commercial workspace (42,411 files), with 564 failed upload attempts logged while investigating.\n\nIf you run GLM locally, the company that publishes the weights is not the same thing as the runtime a developer might use on top of them. Several commenters assumed ZCode was open source because GLM is. It is not. The weights are open; the harness is closed.\n\n## Envelope encryption with a server-only key\n\nZCode uses envelope encryption: the payload is encrypted with a symmetric key, and that key is wrapped with an RSA-OAEP public key delivered by the server during upload-credential negotiation. The corresponding private key lives only in Z.ai's cloud. ferstar's conclusion: \"A key that only the server can use serves exactly one purpose: making sure the server can read your code whenever it wants.\"\n\n## What gets packed\n\nIn one 42,411-file snapshot, `.git/lfs/` was 196.1 MB (56.8%), `.git/objects/` 102.2 MB (29.6%), with source and docs only ~13.4%. The `.git` directory alone was 86.6% of the payload—years of lineage, not just open files.\n\nThe upload pipeline (from `app.asar`): credentials from `zcode.z.ai` → pack tar.gz → AES-256-CTR encrypt → form POST to Aliyun OSS → callback to Z.ai.\n\n## The toggles do not stop it\n\n- \"Optimize Experience\" only controls training authorization; snapshot upload continues.\n- \"Repo Snapshot Indexing\" only controls server indexing; local packaging and upload continue.\n\nThe capture sidecar starts unconditionally when a valid JWT is available. Session logs showed 62 capture events from a single session. OrcaPromptVault's captured ZCode system prompt shows checkpoint/rewind templates but zero snapshot/upload/telemetry tools—the pipeline is host-level, outside the agent tool loop.\n\n## Privacy policy gap\n\nZCode's privacy policy discloses conversational \"text, files, and code submitted during conversations\" but, per ferstar, does not mention packaging and uploading entire workspaces and git histories.\n\n## Defense that works\n\nDeleting the pending archive does not stop re-packaging. Filesystem-level immutability on `~/.zcode/v2/checkpoints` does:\n\n**Linux:** `chattr +i ~/.zcode/v2/checkpoints`\n\n**macOS:** `chflags uchg ~/.zcode/v2/checkpoints`\n\nTrade-off: checkpoint rollback UI stops; chat and tools continue.\n\n## What it means for local AI\n\nA locally-running model wrapped in a cloud-phoning harness is not local. Two checks for every harness: what does the runtime transmit when logged in, and who can decrypt what it stores.\n\nSources include ferstar's forensics post and X threads; see the [original Tokenstead guide](https://tokenstead.ai/guides/zcode-silent-git-history-upload) for full diagrams and citations.\n","body_html":"<h1 id=\"zcode-uploads-your-entire-git-history-and-only-z-ai-holds-the-ke\">ZCode uploads your entire git history, and only Z.ai holds the key</h1>\n<p>On September 18, 2026, a developer going by ferstar published a reverse-engineering walkthrough of ZCode, the AI coding desktop app from Z.ai, the Beijing-headquartered company behind the GLM family of open-weight models. The finding: whenever the app is logged in, it silently packages the user&#39;s entire workspace—complete <code>.git</code> history, LFS asset cache, reflogs, and global app configs—encrypts it, and uploads the archive to Aliyun OSS. One capture: a 313MB encrypted archive from a 345MB commercial workspace (42,411 files), with 564 failed upload attempts logged while investigating.</p>\n<p>If you run GLM locally, the company that publishes the weights is not the same thing as the runtime a developer might use on top of them. Several commenters assumed ZCode was open source because GLM is. It is not. The weights are open; the harness is closed.</p>\n<h2 id=\"envelope-encryption-with-a-server-only-key\">Envelope encryption with a server-only key</h2>\n<p>ZCode uses envelope encryption: the payload is encrypted with a symmetric key, and that key is wrapped with an RSA-OAEP public key delivered by the server during upload-credential negotiation. The corresponding private key lives only in Z.ai&#39;s cloud. ferstar&#39;s conclusion: &quot;A key that only the server can use serves exactly one purpose: making sure the server can read your code whenever it wants.&quot;</p>\n<h2 id=\"what-gets-packed\">What gets packed</h2>\n<p>In one 42,411-file snapshot, <code>.git/lfs/</code> was 196.1 MB (56.8%), <code>.git/objects/</code> 102.2 MB (29.6%), with source and docs only ~13.4%. The <code>.git</code> directory alone was 86.6% of the payload—years of lineage, not just open files.</p>\n<p>The upload pipeline (from <code>app.asar</code>): credentials from <code>zcode.z.ai</code> → pack tar.gz → AES-256-CTR encrypt → form POST to Aliyun OSS → callback to Z.ai.</p>\n<h2 id=\"the-toggles-do-not-stop-it\">The toggles do not stop it</h2>\n<ul><li>&quot;Optimize Experience&quot; only controls training authorization; snapshot upload continues.</li><li>&quot;Repo Snapshot Indexing&quot; only controls server indexing; local packaging and upload continue.</li></ul>\n<p>The capture sidecar starts unconditionally when a valid JWT is available. Session logs showed 62 capture events from a single session. OrcaPromptVault&#39;s captured ZCode system prompt shows checkpoint/rewind templates but zero snapshot/upload/telemetry tools—the pipeline is host-level, outside the agent tool loop.</p>\n<h2 id=\"privacy-policy-gap\">Privacy policy gap</h2>\n<p>ZCode&#39;s privacy policy discloses conversational &quot;text, files, and code submitted during conversations&quot; but, per ferstar, does not mention packaging and uploading entire workspaces and git histories.</p>\n<h2 id=\"defense-that-works\">Defense that works</h2>\n<p>Deleting the pending archive does not stop re-packaging. Filesystem-level immutability on <code>~/.zcode/v2/checkpoints</code> does:</p>\n<p><strong>Linux:</strong> <code>chattr +i ~/.zcode/v2/checkpoints</code></p>\n<p><strong>macOS:</strong> <code>chflags uchg ~/.zcode/v2/checkpoints</code></p>\n<p>Trade-off: checkpoint rollback UI stops; chat and tools continue.</p>\n<h2 id=\"what-it-means-for-local-ai\">What it means for local AI</h2>\n<p>A locally-running model wrapped in a cloud-phoning harness is not local. Two checks for every harness: what does the runtime transmit when logged in, and who can decrypt what it stores.</p>\n<p>Sources include ferstar&#39;s forensics post and X threads; see the <a href=\"https://tokenstead.ai/guides/zcode-silent-git-history-upload\" rel=\"nofollow ugc noopener\">original Tokenstead guide</a> for full diagrams and citations.</p>","headings":[{"level":1,"text":"ZCode uploads your entire git history, and only Z.ai holds the key","id":"zcode-uploads-your-entire-git-history-and-only-z-ai-holds-the-ke"},{"level":2,"text":"Envelope encryption with a server-only key","id":"envelope-encryption-with-a-server-only-key"},{"level":2,"text":"What gets packed","id":"what-gets-packed"},{"level":2,"text":"The toggles do not stop it","id":"the-toggles-do-not-stop-it"},{"level":2,"text":"Privacy policy gap","id":"privacy-policy-gap"},{"level":2,"text":"Defense that works","id":"defense-that-works"},{"level":2,"text":"What it means for local AI","id":"what-it-means-for-local-ai"}]}}