- What happened: Z.ai’s coding agent ZCode was caught silently packaging entire local project directories—including full
.githistories, reflogs, and staged credentials—and uploading them to Alibaba Cloud Object Storage (Aliyun OSS) without user consent. - The encryption lock-out: Archives were encrypted using envelope encryption—AES-256-CTR on the archive, the key then wrapped with an RSA-OAEP-SHA256 public key supplied by ZCode’s servers—leaving developers unable to inspect their own outbound data even with full packet capture.
- Scale of exposure: In one documented instance, a single encrypted archive was 313MB. Of that, 86.6% was Git history alone.
- The opt-out that did nothing: UI toggles described as privacy controls—including the “Optimization Plan” setting—did not actually disable the background upload workflow.
- Remediation: Version 3.14.0 (September 19, 2026) removed Repo Wiki entirely. Third-party auditors CAICT and NSFOCUS confirmed the Aliyun OSS buckets were cleared. Z.ai has now open-sourced the complete harness at github.com/zai-org/ZCode.
Most security incidents begin at the edge—a misconfigured S3 bucket, a leaked token in a public repo, a third-party SDK doing something it shouldn’t. The ZCode incident was different. The data was leaving through the front door, packaged by the tool you were using to write the code, encrypted so you couldn’t see what was inside, and uploaded directly to Chinese cloud infrastructure from your workstation.
ZCode is Z.ai’s flagship coding agent—an Agentic Development Environment purpose-built for the GLM-5 model family. Launched initially with GLM-5.2 in July 2026 and updated for GLM-5.3, it pitches itself as an “agent-first” alternative to traditional AI-assisted IDEs: you give it a goal, and it plans, writes, runs terminal commands, and manages Git autonomously.
The person who first pulled on the thread was Ferstar, a developer and open-source contributor who noticed ZCode making unexpected outbound network calls during a routine session. What followed was a detailed reverse-engineering disclosure that laid out, step by step, exactly how the upload pipeline worked and why users couldn’t see what was being sent.
What Repo Wiki Actually Did to Your Codebase
The mechanism behind the uploads was ZCode’s Repo Wiki feature—marketed as a session-recovery and documentation tool that built contextual snapshots of your project for the GLM-5 model to reference. It was enabled by default, ran in the background without any explicit trigger from the user, and collected far more than architectural context.
When ZCode opened a project directory, a background worker recursively traversed the entire workspace, ignoring standard .gitignore rules. It then compressed the result into a single encrypted archive and shipped it to Aliyun OSS via a direct PUT request—bypassing ZCode’s own application servers entirely.
The upload flow was mechanically direct: ZCode’s client first called POST /api/v1/snapshot/upload-credential to obtain temporary OSS credentials from ZCode’s backend. It then performed a direct upload to the Aliyun OSS bucket. ZCode’s backend received an OSS callback confirming the transfer. The actual file content never passed through ZCode’s API—it went straight from the developer’s machine to Alibaba Cloud.
What One Archive Contained
In the most forensically documented instance, a 313MB encrypted archive consisted of Git objects, packed refs, and reflogs. Years of commit history, internal hostnames, and deleted files—all preserved inside .git/objects.
API keys and database connection strings accidentally committed at any point in a repo’s history live on in .git/logs/HEAD, even after a subsequent commit that “removed” them from the working tree.
Local .git/config files expose remote URLs (including private GitHub org paths, internal GitLab instances, and corporate SSH hosts), committer identities, and signing keys.
Staged changes, local .env files, and draft code sitting in the working tree were swept up alongside tracked files—none of it gated by any user action.
The opt-out question is critical because Z.ai’s initial response leaned heavily on it. The company pointed to a setting labelled “Optimization Plan” as the mechanism for users to disable data collection. Investigators found this toggle did not actually disable the background Repo Wiki upload workflow. The UI control and the upload process were completely decoupled.
Why Developers Couldn’t See What They Were Sending
When a developer suspects an application is sending data somewhere it shouldn’t, the standard diagnostic procedure is to route traffic through an intercepting proxy such as mitmproxy or Wireshark, decrypt TLS termination via local root certificates, and inspect the raw payloads. That didn’t work here.
ZCode implemented envelope encryption on the outbound archive in two distinct stages. The workspace archive was first encrypted locally with an ephemeral AES-256-CTR symmetric key. That symmetric key was then wrapped using an RSA-OAEP-SHA256 public key—one supplied by ZCode’s servers during the credential negotiation call, not hardcoded in the binary.
The RSA private key capable of unwrapping the AES key existed only on Z.ai’s ingestion servers. Even with root permissions on their own workstation and an intercepted TLS stream, developers could confirm a 313MB payload was heading to Aliyun OSS, but could not confirm what was inside it. The data was generated by their code on their hardware, yet they were mathematically barred from inspecting it.
This structural information asymmetry is what separated the ZCode incident from standard telemetry bugs. A misconfigured endpoint sends readable JSON—an embarrassment, but easily verified and remediated. Envelope encryption on outbound user data creates a dynamic where the vendor can always read the payload, but the client author never can. Similar boundary issues were evaluated in our breakdown of the Claude Code token compromise security audit and the control-plane auth bypass at the center of the DeepSeek CVE-2026-82533 sandbox escape.
What the GLM Fallout Looked Like in Practice
The fallout extended immediately beyond the desktop client. Because ZCode is Z.ai’s official harness for GLM-5.2 and GLM-5.3, the discovery pulled the underlying models into the blast radius. Engineering teams routing enterprise coding pipelines through GLM-5 APIs—often selected for aggressive pricing against Western frontier models—had to act immediately.
| Layer | Before Disclosure | After Disclosure |
|---|---|---|
| ZCode desktop client | Installed natively on developer workstations | Purged. EDR policies blocking reinstallation. |
| GLM-5 API access | Active in CI/CD pipelines and IDE integrations | API keys revoked pending review. Workloads migrated to self-hosted weights. |
| Aliyun OSS / Z.ai egress | Open HTTPS outbound unrestricted | Blocked at enterprise perimeter firewalls. |
Z.ai’s official response arrived in stages: first an apology attributing the behavior to the default-enabled Repo Wiki; second, client version 3.14.0 on September 19, 2026, which removed Repo Wiki completely; third, an audit by independent state and commercial cybersecurity entities—CAICT (China Academy of Information and Communications Technology) and NSFOCUS—confirming the Aliyun OSS buckets were scrubbed; and finally, a commitment to open-source the codebase. Version 3.14.1 has since followed with minor stability fixes.
The github.com/zai-org/ZCode Repository: What’s in It
The public repository, live at github.com/zai-org/ZCode, contains the client execution harness, the agent orchestration loop, the tool invocation registry, and the codebase indexing pipeline that replaced Repo Wiki.
- Aliyun OSS integrations removed: The credential fetch endpoint (
POST /api/v1/snapshot/upload-credential) and direct OSS upload calls have been excised from the codebase. There are no remaining references toaliyuncs.comstorage endpoints in the harness source. - Repo Wiki deleted: The feature has been removed entirely, not toggled or gated—the code path no longer exists. The replacement codebase indexing runs locally.
- Envelope encryption removed: The RSA-OAEP-SHA256 key wrapping and AES-256-CTR archive encryption pipeline is no longer present in the client source.
- Centralised outbound transport: All HTTP request construction has been consolidated into a single auditable network layer, which means developers building from source can verify every outgoing call with a local proxy without hitting cryptographic dead ends.
- Additional repositories: The
zai-orgGitHub organization also hostszcode-plugins(the marketplace integration layer), GLM-5 and GLM-5.3-Flash model repositories, and supporting tooling.
Four Controls Security Teams Should Enforce Right Now
The ZCode incident did not introduce a new category of risk. It demonstrated one that has been sitting under the surface of every closed-source coding agent. Teams running Cursor, GitHub Copilot Workspace, Gemini in Cloud Workstations, or any agentic tool with local filesystem access are operating under the same trust assumptions that ZCode violated.
Whether your organization runs ZCode’s newly open-sourced build or a different agent harness—including managed architectures like the Google Antigravity managed agents framework—these four controls belong in every agentic development policy:
Bind agent processes to isolated Linux network namespaces controlled by eBPF socket filters. Allowlist only verified model inference endpoints. Every upload to an object storage service—even a legitimate one—requires an explicit approval rule, not a default-open outbound posture.
When mounting project directories into agent sandboxes, exclude the .git directory entirely. An agent needs source files to write code. It does not need commit history, reflogs, or the remote configuration. Mount only what the agent needs to complete the task.
.env files and hardcoded credentials in configuration files are the highest-value target inside a captured archive. Agents that need API access should request scoped, time-bounded credentials through a host-level broker rather than reading from the filesystem.
Agent sessions running inside disposable environments—Firecracker microVMs, rootless Podman containers, or similar—limit blast radius. When the session ends, the environment is destroyed. Nothing persists that shouldn’t.
These controls are documented in detail in our Agent Permissions & Sandbox Security Lab, which tracks containment architectures across commercial agentic tools. For teams evaluating coding agent spend in the context of ZCode’s reopened trust questions, our Cursor pricing and data handling breakdown offers a useful structural comparison of how indexing features are handled across the market.
Where This Leaves ZCode
The harness is now open. The auditors signed off on the data deletion. The patch is shipping. By the formal checklist of incident response, Z.ai has done what it was supposed to do.
The harder problem is that ZCode launched on the premise that tight model-harness co-design—Z.ai controls both GLM-5 and the execution environment—produces a better agentic coding experience. That premise may still be true. But the incident demonstrated that co-design also means co-incident: when the harness fails, the model family it serves takes the credibility hit alongside it.
GLM-5.3 is a capable model. Developers who separated the model from the tooling and chose to keep running GLM via self-hosted weights or BYOK configurations were making a reasonable call. The question now is whether the open-sourced ZCode repository—with community auditing, independent forks, and transparent network transport—can rebuild the confidence that the closed binary spent nine months accumulating and a single Ferstar disclosure dissolving in less than a week. That answer won’t come from a press release or a third-party audit confirmation. It will come from the commit history.
