AI Coding Agent に権限制御が必要な理由:JSON Tool Call から Shell、Git、ファイルシステムの権限モデル(2026)
安全の稿は攻撃面を書いた。本稿は権限モデルだけだ:ツール呼び出しは JSON であり、実行権は宿主にある。Shell、Git、ファイルシステムは三つの門。「許可」を押すことは、サンドボックスが閉じたことではない。
読む前に
| 門 | 何を鎖すか | 誰が実行するか |
|---|---|---|
| Shell | コマンド文字列、複合コマンド | allow / ask / deny。サンドボックスは別 |
| Git | status、diff、commit、push。hooks / config | 作業域の書き込み ≠ 倉庫メタの書き込み |
| ファイルシステム | src、.env、作業域の外 | ツール規則 + OS サンドボックス |
| ネットワーク | ドメイン、外向き | 既定は閉じる。名簿を別に開く |
方針は宿主が評する。モデルは JSON を埋める。門は動かさない。
権限制御が要るのは、実行権がモデルにないからだ
Coding Agent がツールを呼ぶとき、モデルが出すのは JSON だけだ。名前と引数。git status を走らせ、src/orders/A-1042.json を直すのは宿主だ。Schema は形を鎖す。権限方針は、形が通ったあと走ってよいかを鎖す。第二の門がなければ、第一は礼儀に過ぎない。
- Schema:引数を鎖す。コマンドは文字列。経路は決めた接頭辞の下。
- 権限方針:allow / ask / deny。公式の順は deny、ask、allow。狭い allow は広い deny を救わない。
- サンドボックス:OS の層。注入がモデルの判断をずらしても、過程は作業域を出られない。「許可」はサンドボックスを開くことではない。
ツール JSON の埋め方は AI Coding Agent と JSON ツール呼び出し。攻撃面の収め方は Agent の安全危機と JSON 検証。Schema が門である理由は AI に JSON Schema が必要な理由。本稿は三つの話を繰り返さない。Shell / Git / ファイルを対象として落とすだけだ。
権限オブジェクト:allow、ask、deny
Claude Code は規則を settings.json の permissions に書く。評するのは宿主であり、モデルではない。CLAUDE.md は試みを変えられる。許容は変えられない。架空の倉庫。本物の秘密は貼らない:
{
"permissions": {
"allow": [
"Bash(git status)",
"Bash(git diff *)",
"Bash(npm test *)",
"Read(./src/**)",
"Edit(./src/**)"
],
"ask": [
"Bash(git commit *)"
],
"deny": [
"Bash(git push *)",
"Read(./.env)",
"Edit(./.git/hooks/**)",
"Edit(./.git/config)"
]
}
}
裸のツール名(Bash)の deny は、ツールを文脈から外す。括弧つきは一致する呼び出しだけを止め、ツールは残る。複合コマンドは副コマンドごとに一致する。git status を許しても、その後ろの別コマンドは許さない。Codex は権限プロファイル(:workspace / :read-only)を使う。古い sandbox_mode と混ぜない。Cursor は permissions.json の接頭辞名簿と sandbox.json だ。
第一の門:Shell
モデルが渡すのはコマンド文字列だ。宿主は方針に当ててから走る。読み取りの照会は通ることが多い:
{
"type": "tool_use",
"id": "call_7f2a",
"name": "Bash",
"input": {
"command": "git status"
}
}
同じ方針では、遠隔への push は deny。対象の形は正しい。実行権は宿主のまま。Cursor の端末名簿は接頭辞一致。git は git status を覆う。公式も、Run Mode は最善の柵であり硬い境界ではないと書く。硬い境界にはサンドボックスを付ける。
{
"type": "tool_use",
"id": "call_8a01",
"name": "Bash",
"input": {
"command": "git push origin main"
}
}
第二の門:Git は普通の書き込みではない
作業域が書けることは、.git が書けることではない。Codex は書き込み根の下で .git、.agents、.codex を既定で読み取り専用にする。.git が gitdir: ポインタなら、解決先も守る。Claude Code のサンドボックスは worktree に共有 .git への commit 用書き込みを許し、hooks/ と config は拒む。Cursor も .git/hooks と .git/config を守る。拒まれた push は対象として残す:
{
"tool": "Bash",
"command": "git push origin main",
"eval_order": ["deny", "ask", "allow"],
"matched": "Bash(git push *)",
"rule": "deny",
"sandbox": "workspace-write",
"execute": false
}
失敗なら tool_result を返し、当たった規則を書く。遠隔を黙って触らない。commit は ask。人が diff を見てから通す。push は、このセッションが公開だと明示されない限り deny。
{
"type": "tool_result",
"tool_use_id": "call_8a01",
"is_error": true,
"content": "denied by policy: Bash(git push *)"
}
第三の門:ファイルシステムは二層
一層はツール規則。一層は OS サンドボックス。公式が分けるのは、止める呼び出しが違うからだ:
- ツール規則:Claude の Read / Edit deny は組み込みのファイルツールと、
cat/headなど認識したコマンドを覆う。言語スクリプトが自分でファイルを開く呼び出しは、この層の外。 - OS サンドボックス:過程の境界。既定の書き込みは作業域とセッション一時領域。外の経路は明示。ネットワークは既定で閉じる。
- 資格ファイル:
.envを deny へ。「秘密を読むな」という指示だけに頼らない。
MCP ツールは別の表だ。各ツールに門が要る。プロトコルの対比は MCP Tool Schema vs Function Calling。本稿は Coding Agent が MCP をどう呼ぶかは書かない。繋がったツールが権限オブジェクトに名前を持つことだけを求める。
権限を対象にする五手順
「慎重に実行して」から始めない。門を書く:
- まず deny を書く。push、hooks、config、.env、作業域の外を一度列ぶ。
- 読み取りコマンドを allow へ。status、diff、test。複合は副コマンドごとに一条。
- 書き込みと commit を ask へ。人が経路と diff を見る。編集の承認はセッションで終わり、永久規則にはならない。
- OS サンドボックスを付ける。Codex は
:workspace。不用意に:danger-full-accessにしない。Cursor の既定を Run Everything にしない。Claude のbypassPermissionsは隔離容器に残す。 - 方針を JSON として審る。allow と deny を並べる。共有規則は版管理へ。手元の緩和は local に残す。
Schema を門にする話は Agents API + JSON Schema。本稿が求めるのは、Coding Agent の門がすべて対象であり、宿主が評することだ。
権限の逸脱を見直すなら、二つの JSON を広げる
門を越えた多くは、規則が揃っていないことだ。モデルが野になったことではない。
- 方針とその
tool_useを 整形 し、deny が当たったか allow が漏れたかを見る。 - JSONPath 抽出 で
$.permissions.denyと$.input.commandを抜く。 - 通った呼び出しと拒まれた呼び出しを JSON Diff。規則を先に直し、指示は後。
- Git メタの規則と src の書き込みは分けて審る。
A-1042.jsonを直せることは、hooks を直せることではない。 - 方針ファイル、倉庫の経路、セッション記録を公開フォーマッタに貼らない。JSONSort はブラウザ内で動く。
二つの軌跡が規則で再建できて初めて、権限を集めている。「許可を押した」を集めているのではない。
よくある落とし穴
- Schema を権限だと思う。Schema は形を鎖す。形の正しい
git pushも deny が要る。 - allow だけ書く。公式の順は deny が先。deny がなければ、名簿は承認を速めるだけだ。
- 作業域の書き込みを Git の書き込みだと思う。hooks と config は別の門。公式の既定が守る。
- ツールの deny だけでサンドボックスを付けない。スクリプトが自分でファイルを開く呼び出しは、ツール規則の外。過程の境界が要る。
- ノートで bypass / full-access / Run Everything を開く。公式は隔離環境向けだ。日常は workspace + ask。
- Codex の新旧を混ぜる。
sandbox_modeがあると権限プロファイルは効かない。一つ選ぶ。
FAQ
「許可して再度尋ねない」は永久の授権か?
限らない。Claude Code では、Bash の永続承認は倉庫根の settings.local.json に落ち、ファイル編集の承認はセッションで終わる。Cursor の名簿は permissions.json。書かれた対象を見る。ボタンの文言を信じない。
サンドボックスがあれば deny は不要か?
要る。サンドボックスは過程が作業域を出るのを止める。deny は、その中で走ってはならないコマンド(push など)を止める。鎖す門が違う。
Git を別立てする理由は?
倉庫メタは普通のファイルではない。src を直せることは、hooks と config を直せることではない。push は外向きであり、書き込みではない。公式はこれらを「作業域が書ける」から外す。
読み取り専用で足りるか?
コードを見るには足りる。A-1042 を変えるには足りない。Codex の :read-only、Claude の plan、Cursor の読み取りサンドボックスは探索用であり、公開用ではない。
方針を Git に入れてよいか?
入れてよい。入れるべきだ。共有の deny / allow は版管理へ。手元の緩和は local に残し、コミットしない。bypass と auto を閉じるのは managed 設定。
結論
Coding Agent に権限制御が要るのは、モデルが JSON を埋めるだけだからだ。Shell、Git、ファイルシステムは三つの門。Schema を通ったあと、宿主がもう一度評する。
git push がどの deny に当たるかを先に書く。経路を指せれば、方針は検証できる。モデルは変わる。門を先に安定させる。
続きを読む
- AI Coding Agent は JSON でどうツールを呼ぶか Claude Code と GPT Agent のツール JSON
- Agent の安全危機と JSON 検証 攻撃面の収め方。権限オブジェクトではない
- Claude の安全事案とツール JSON 一事案で引数がどう逸れたか
- Agents API + JSON Schema 実践 安定、検証、実行の三つの門
- AI に JSON Schema が必要な理由 Schema / Function Calling / Structured Output
- JSONSort のローカル道具箱 整形、検証、Diff
- すべての記事 JSON と AI 開発のメモ
更新記録: 初回公開