Zhipu製ZCode、Git全履歴を無断アップロード

Zhipu傘下のAIコーディングツール「ZCode」が、作業ディレクトリ全体をバックグラウンドで圧縮・アップロードしていると9月18日に開発者から指摘された。対象にはGitの全履歴、LFSの大容量ファイルキャッシュ、ローカル設定まで含まれていた。同日中にZCode側が謝罪文を出し、アップロードの事実を認めた上で、原因を「リポジトリインデックス」機能に帰し、問題は修正済みとした。

開発者が突き止めたこと

最初に詳細を明らかにしたのは技術ブロガーのFerstar氏。ブログでZCodeのローカルスナップショット機構を解析した。ログイン後、アプリ起動と同時に立ち上がるバックグラウンドプロセスが作業ディレクトリ全体をパッケージ化し、AES-256-CTRでファイル内容を暗号化。鍵はサーバー側から配布されたRSA公開鍵で包んだ上で、フォーム送信の形でAlibaba Cloud OSSに直接アップロードする。復号に必要な秘密鍵はサーバー側にしか存在せず、ユーザーの手元にある.encファイルは自分では開けない。

同氏が示したサンプルは具体的だった。未圧縮で345MBの作業ディレクトリが、暗号化後は313MB、ファイル数は42411。大半を占めるのは.gitディレクトリで、全体の86.6%。内訳はLFSキャッシュが196.1MB、Gitオブジェクトが102.2MB、ソースコードと設定ファイルは約46MBにすぎない。トリガーは2種類あり、1つはプロンプト送信のたび、もう1つはタスク終了後にRepo Wikiを更新するタイミング。1セッションで最大62回のスナップショットが記録されていた。

同日、Zhipuの公開フィードバックリポジトリにissueが立てられ、タイトルには「なぜ」が3回並んだ。なぜGitの全履歴を無断でアップロードするのか、なぜユーザー自身も開けない形で暗号化するのか、なぜオフにするスイッチすら用意しないのか、という内容だ。issueにはローカルでのアップロード失敗後にスナップショットが繰り返しリトライされ、564回に達した記録も添えられていた。別の開発者は自分の環境で再現し、あるプロジェクトのスナップショットは748MiB、.gitの比率は98.91%、バージョンはZCode 3.12.3だったという。

効かないスイッチが今回の論争で最も刺々しい論点だ。Ferstar氏によれば、画面上の「体験の最適化」と「リポジトリスナップショットインデックス」のスイッチが制御するのは、サーバー側がデータをモデル学習に使うかどうかだけで、ローカルでのパッケージ化とアップロードはスイッチの状態に関係なく実行されるという。Git履歴には、とっくに削除したはずの鍵、廃止した旧設定、プッシュされていないブランチの記録、社内ドメイン名などが残っている場合がある。現在のコードには見えなくても、.gitの中には残っている。

Zhipu側の説明

ZCodeの謝罪文は、アップロードの原因を「リポジトリインデックス」機能に帰した。Repo Wikiのページ生成時にリポジトリデータのアップロードが発生することがあり、データはクラウド側でWiki生成後、直ちに破棄・保存はしないとしている。この機能はリリース当初デフォルトでオンになっており、一部ユーザーが影響を受けたが、現在は修正済みだという。

対応策は3点。近くZCodeのコードベースをオープンソース化し、第三者による評価と公開レビューを依頼する。全ユーザーに対し、当日中に週次クォータの追加リセットを1回付与する。一方で説明されていない、現時点で検証不能な点も残る。影響を受けたユーザーとリポジトリの数、データがOSS上に実際に留まっていた期間、「破棄」に独立した監査が入っているか、修正後のバージョン番号は何か——いずれも不明のままだ。オープンソース化の時期も「近く」としか書かれていない。

同日、Zhipuは新モデル「GLM-5.3-FlashX」も発表し、毎秒200トークンの出力速度を売りにした。ある開発者はブログでこの2つの出来事を並べ、「ネット中がコードの行方を聞いているのに、Zhipuは新モデルの発表に忙しい」と皮肉った。

国内の開発者が今できること

ZCodeのユーザーには社内プロジェクトで試用している人も少なくなく、Git履歴の機密度は現在のコードより高いことが多い。旧バージョンを使い続けている場合、安全な対応は3つ。まず修正済みバージョンへのアップグレード。次にローカルの~/.zcode/v2/checkpoints以下にアップロード待ちのスナップショットが残っていないか確認。そして履歴に登場した鍵やトークンをすべてローテーションする——「破棄済み」がすでに送信済みの分をカバーしているとは期待しない方がいい。

Ferstar氏はより強い対策も示した。macOSではchflags uchg、Linuxではchattr +iでスナップショット用ディレクトリを書き込み不可にロックし、ファイルシステムのレベルでスナップショット生成自体を阻止する方法だ。代償として、チェックポイントのロールバックやタイムライン機能も使えなくなる。

この種のコーディングエージェントはリポジトリを読み取らなければ機能しないため、ローカルインデックス自体は珍しいことではない。争点は境界線にある。ローカルで読み取ることとクラウドへ送ることは別の話であり、現在のコードを送ることと履歴全体を送ることもまた別の話だ。Zhipuが約束したオープンソース化が実現すれば、外部の人間も少なくとも、スナップショットモジュールが実際にどのパスをパッケージ化し、スイッチがどこに繋がっているのかを自分の目で確認できるようになる。

参考資料:スナップショット機構とファイル構成を解析したFerstar氏の技術ブログ、zai-org/feedbackの公開issue、鳳凰網科技(Phoenix Tech)、CocoLoop、Elliot's Harness Lab/帰属・修正状況・補償措置はZCodeの謝罪文で確認。