TL;DR
- GitHub Copilot CLI v1.0.79(2026-08-10)で、ワークスペース内の PATH 上のツールディレクトリ(
.venv/bin・node_modules/.bin・リポジトリ内 GOPATH)がワークスペースの一部を read-only にしてしまう挙動が修正されました - Linux のサンドボックスは bubblewrap(
bwrap)0.5.0 以上が前提です。素の Ubuntu コンテナには入っておらず、無いまま有効化すると サンドボックス対象のシェルコマンドとサーバーが全部失敗 します - サンドボックスの認証設定キーが
sandbox.gitAuth/sandbox.ghAuthからsandbox.auth.git/sandbox.auth.ghにリネームされました - 「ネストした read-only パスが書き込み可能を継承してしまう/しない」は bind の適用順で決まります。bubblewrap で同じ構図を再現したところ、順序を入れ替えるだけで
node_modules/.binへの書き込み可否が反転しました
はじめに
対象読者は、GitHub Copilot CLI を Linux 上で使っていて、実験的機能のコマンドサンドボックスを有効にしたい(あるいは有効にしたら動かなくなった)開発者です。
Copilot CLI v1.0.79 の変更点として「サンドボックスでツールディレクトリを書き込み可能に保てるようになった」が挙がっています。一見すると細かいバグ修正ですが、実際に踏むと npm install や cargo build がサンドボックス内だけ失敗するという分かりにくい形で表面化します。
今回は v1.0.79 を実際に入れて、ヘルプに出てくるポリシー面を確認し、Linux 側のホスト要件を確かめ、read-only の入れ子がどう効くのかを bubblewrap で再現しました。
v1.0.79 で変わったこと
公式の changelog(github/copilot-cli の changelog.md)には、1.0.79(2026-08-10)として次の記述があります。
A tool directory inside your workspace that is on PATH (.venv/bin, node_modules/.bin, an in-repo GOPATH) no longer turns that part of the workspace read-only
あわせて macOS 側では「書き込み可能なパスの内側にネストした read-only パスが、広い方の書き込み権限を継承せず read-only のままになる」修正が入っています。
つまり 「ワークスペースは書けるが、その内側のツールディレクトリは読み取り専用」という入れ子の扱い をまとめて整理したリリースです。
同じリリースには、設定キーの破壊的変更が 2 つ含まれています。どちらも 移行処理が無い ので、既存の settings.json を持ち込むときに効いてきます。
| 旧キー | 新キー | 旧キーの扱い |
|---|---|---|
sandbox.gitAuth / sandbox.ghAuth
|
sandbox.auth.git / sandbox.auth.gh
|
設定ファイル内では無視される。SDK リクエストが送った場合は invalid として拒否される |
sandbox.allowDevToolCaches |
sandbox.allowDevToolAccess |
読まれず、黙って無視される |
changelog は前者について「There is no migration」と明記し、後者を BREAKING として扱っています。
BREAKING: the sandbox setting
allowDevToolCachesis renamedallowDevToolAccess(...) The old key is no longer read and is ignored silently, so an existingfalseopt-out reverts to the default (on).
後者はとくに注意が必要です。「開発ツールの場所への自動許可を切る」ために allowDevToolCaches: false を書いていた場合、v1.0.79 に上げると その opt-out が消えて既定のオンに戻ります。切っていたつもりの許可が復活する方向の変更なので、設定ファイルを配布している環境では上げる前に置換しておく必要があります。
実際に入れて確かめる
まず npm でインストールします。
$ npm install -g @github/copilot@1.0.79
added 3 packages in 15s
$ copilot --version
GitHub Copilot CLI 1.0.79.
Run 'copilot update' to check for updates.
サンドボックスはトップレベルのサブコマンドではなく、ヘルプトピックとして提供されています。copilot --help の Help Topics 側に並んでいます。
$ copilot --help | sed -n '/Help Topics/,/^$/p'
Help Topics:
billing AI credit usage
commands Interactive Mode Commands
config Configuration Settings
environment Environment Variables
limits Session Limits Controls
logging Logging
monitoring Monitoring with OpenTelemetry
permissions Permissions
providers Custom Model Providers (BYOK)
sandbox Command Sandboxing
copilot sandbox --help と打ってもトップレベルヘルプが返ってくるだけなので、copilot help sandbox で開くのが正解でした。ここで実装の前提がはっきり書かれています。
前提1: Linux は bwrap が必須
ヘルプの Supported hosts 節に、バックエンドとホスト要件が明記されています。
macOS Uses the MXC Seatbelt backend (`sandbox-exec`).
Linux Uses the MXC bubblewrap backend; requires `bwrap` 0.5.0+ on PATH.
Windows Uses the MXC ProcessContainer backend, which targets Windows 11.
サンドボックスは Microsoft Execution Containers(MXC)という抽象レイヤ越しに、OS ごとのネイティブな隔離機構を使う設計です。Linux では bubblewrap がそのバックエンドになります。
検証に使った Ubuntu ベースのコンテナには入っていませんでした。
$ bwrap --version
bash: bwrap: command not found
この状態でサンドボックスが有効になっていると、ヘルプにはこう書かれています。
every sandboxed shell command and every sandboxed MCP/LSP server fails
起動時に警告は出るものの、失敗するのはコマンド実行時です。CI コンテナや開発用イメージで sandbox.enabled: true を設定ファイルごと配って回ると、この踏み方をします。導入は 1 行で済みます。
$ apt-get install -y bubblewrap
Setting up bubblewrap (0.9.0-1ubuntu0.1) ...
$ bwrap --version
bubblewrap 0.9.0
要件は 0.5.0 以上なので、Ubuntu 24.04 系の 0.9.0 で満たせます。
前提2: experimental を有効にしないとコマンドが生えない
もう一点、ヘルプの冒頭に書かれている制約があります。
The
/sandboxcommand (and itsenable/disablesubcommands) is only registered when experimental features are on; otherwise it returns "Unknown command".
つまり /sandbox が「Unknown command」で返ってきたときに疑うべきはタイポではなく、experimental が off であることです。--experimental フラグか /settings experimental on で有効化します。
前提3: classic PAT では認証できない
非対話モードで動作確認しようとしたところ、認証ではじかれました。
$ copilot -p "Reply with exactly: OK" --allow-all-tools --silent
Error: Classic Personal Access Tokens (ghp_) are not supported by Copilot.
The GH_TOKEN environment variable contains a classic PAT.
Please use a Fine-Grained Personal Access Token or another authentication method.
環境に GH_TOKEN が入っている CI やクラウド実行環境では、それが classic PAT だと Copilot CLI 側で即エラーになります。fine-grained PAT に差し替えるか、GH_TOKEN を unset して /login を使う必要があります。
なお GitHub Docs のトラブルシューティングでは、classic PAT は「silently ignored(黙って無視され、トークン未設定として振る舞う)」と説明されています。今回の v1.0.79・非対話モード(-p)では上記のとおり明示的なエラーが返りました。黙って無視される挙動を想定していると原因究明が長引くので、エラーで止まってくれる方はむしろ親切です。この都合で、今回はエージェントループを回した実測までは到達できていません(後述の再現実験はバックエンドの bubblewrap 単体で行っています)。
ポリシーの構造を読む
copilot help sandbox の Configuration 節には、settings.json の sandbox キー配下の設定が 11 項目載っています。
| 設定キー | 役割 |
|---|---|
enabled |
コマンドサンドボックスの有効・無効 |
addCurrentWorkingDirectory |
カレントディレクトリに読み書きを付与(有効化時は既定でオン) |
allowDevToolAccess |
ビルドが必要とする開発ツールの場所を自動許可(既定オン) |
allowBypass |
コマンド単位でサンドボックスを外す逃げ道を許可 |
auth.git / auth.gh
|
git・gh の認証情報をサンドボックス内へ注入 |
sandboxMcpServers / sandboxLspServers
|
ローカル(stdio)の MCP・LSP サーバーもサンドボックス内で起動するか |
userPolicy.filesystem.readwritePaths / readonlyPaths / deniedPaths
|
追加で読み書き・読み取り専用・拒否するパス |
userPolicy.filesystem.clearPolicyOnExit |
セッション終了時にファイルシステムポリシーを破棄 |
userPolicy.network.allowOutbound |
外向きネットワーク接続の可否 |
userPolicy.network.allowLocalNetwork |
ローカルネットワークへの接続可否 |
userPolicy.seatbelt.keychainAccess |
macOS のキーチェーンへのアクセス可否 |
旧キー名の gitAuth / ghAuth はヘルプ本文から消えており、grep してもヒットしません。
$ copilot help sandbox | grep -c "gitAuth\|ghAuth"
0
既存の settings.json を持ち込む場合、リネーム前のキーを書いたままだと認証情報の注入設定が意図どおりに効かない可能性があります。v1.0.79 に上げるタイミングで書き換えておくのが安全です。
なぜ PATH のツールディレクトリが問題になるのか
今回の修正を理解する鍵は、ファイルシステムの既定ポリシーにあります。ヘルプにはこう書かれています。
By default access is limited to your working directory, PATH directories, the temp directory, and your user profile.
ワークスペース と PATH に入っているディレクトリ が、それぞれ別々に許可対象として並びます。Node.js プロジェクトで node_modules/.bin を PATH に足していると、この 2 つが入れ子になります。
ワークスペース全体に read/write を与え、そのサブディレクトリに read-only を与える。この 2 つの規則が衝突したとき、どちらが勝つかは実装(と適用順)次第です。v1.0.79 は、この衝突を「ワークスペース内の PATH ツールディレクトリはワークスペースの書き込み権を潰さない」方向に、macOS では「明示した read-only は書き込み権を継承しない」方向に揃えました。
bubblewrap で入れ子の挙動を再現する
Linux バックエンドの bubblewrap 単体でも、同じ構図を再現できます。ワークスペースを用意します。
WS=/tmp/copilot-sandbox-demo/work
mkdir -p "$WS/node_modules/.bin" "$WS/src"
echo "console.log('hi')" > "$WS/src/index.js"
printf '#!/bin/sh\necho tool\n' > "$WS/node_modules/.bin/mytool"
chmod +x "$WS/node_modules/.bin/mytool"
サンドボックス内で 3 箇所に書き込みを試すプローブを用意します。
#!/bin/sh
WS=/tmp/copilot-sandbox-demo/work
for p in "$WS/src/new.txt" "$WS/node_modules/pkg.txt" "$WS/node_modules/.bin/new-bin"; do
if echo x > "$p" 2>/dev/null; then echo "WRITE OK ${p#$WS}"; else echo "WRITE DENY ${p#$WS}"; fi
done
ケースA として、ワークスペースを read/write でバインドした あと に .bin を read-only でバインドします。
$ bwrap --ro-bind / / \
--bind $WS $WS \
--ro-bind $WS/node_modules/.bin $WS/node_modules/.bin \
--proc /proc --dev /dev --chdir $WS /bin/sh probe.sh
WRITE OK /src/new.txt
WRITE OK /node_modules/pkg.txt
WRITE DENY /node_modules/.bin/new-bin
ケースB として、順序だけを入れ替えます。.bin を read-only でバインドした あと にワークスペースを read/write でバインドします。
$ bwrap --ro-bind / / \
--ro-bind $WS/node_modules/.bin $WS/node_modules/.bin \
--bind $WS $WS \
--proc /proc --dev /dev --chdir $WS /bin/sh probe.sh
WRITE OK /src/new.txt
WRITE OK /node_modules/pkg.txt
WRITE OK /node_modules/.bin/new-bin
同じ 2 つの規則で、順序を入れ替えただけで node_modules/.bin への書き込み可否が反転しました。ケースAでは read-only の指定が後から被さって .bin だけが書けなくなり、ケースBでは後から張った read/write のマウントが read-only 指定を覆い隠します。
なお、この実験は Copilot CLI 内部の MXC が発行するポリシーそのものではなく、Linux バックエンドとして使われている bubblewrap の入れ子マウントの挙動を確かめたものです。「入れ子の順序で結果が反転する」という性質が、changelog の 2 つの修正(ツールディレクトリが workspace を read-only にする/ネストした read-only が write を継承する)が同時に出てきた背景にあると読めます。
一次所見: 運用に落とすときの注意
実際に v1.0.79 を触って感じたのは、サンドボックスの難所が「ポリシーの表現力」ではなく ホスト側の前提と、ポリシーの重なり方 に寄っている点です。
-
ホスト要件は起動時に落ちない: bwrap が無くても Copilot CLI 自体は起動します。失敗するのはサンドボックス対象のコマンドを実行した瞬間なので、原因がサンドボックスだと気づくまでに時間を取られます。イメージのビルド時点で
bwrap --versionを通しておくのが確実です -
allowDevToolAccessは既定オン:~/.npmrcや~/.m2/settings.xmlのようなレジストリ設定は既定で読めます。そこにトークンを書いているなら、サンドボックス内のコマンドから読めるという前提で運用する必要があります。嫌なら明示的に切ってreadonlyPaths/readwritePathsで組み立て直す設計になっています -
設定キーのリネームは静かに効く:
gitAuth→auth.git、allowDevToolCaches→allowDevToolAccessのどちらも移行処理がありません。動かなくなるというより「注入されているつもりが注入されていない」「切ったつもりの許可が既定のオンに戻っている」形で表面化します。バージョンを上げるときはsettings.jsonを必ず見直します -
実効ポリシーを見るコマンドが増えた: v1.0.79 では
/sandbox policyで、実際に効いているパス・拒否・ネットワーク許可を確認できるようになりました。設定を書き換えたら、意図どおりのポリシーになっているかをここで突き合わせるのが早道です
参考
- github/copilot-cli changelog.md(v1.0.79 / v1.0.78 の変更点)
- GitHub Docs: About cloud and local sandboxes
- microsoft/mxc(サンドボックスのバックエンド抽象)