ccgate
July 31, 2026 · View on GitHub
AI コーディングツール向けの PermissionRequest フックです。ツール実行の許可判定を LLM (Claude Haiku) に委任し、jsonnet 設定に書いたルールに基づいて allow / deny / fallthrough を返します。
ccgate は組み込みのデフォルトルールを持っているので、設定ファイルなしでも動きます。

対応ターゲット:
インストール
mise (推奨)
mise 2026.4.20 以降が必要です。
mise use -g aqua:tak848/ccgate
ccgate をグローバルに登録せず一度だけ試したい場合 (npx / uvx 相当):
mise exec aqua:tak848/ccgate -- ccgate --version
aqua
aqua 標準 registry 経由 (registry v4.498.0 以降が必要)。aqua 管理下のプロジェクトで (aqua.yaml がない場合は aqua init を先に走らせる):
aqua g -i tak848/ccgate
aqua i
グローバル aqua 設定 に入れる場合は aqua 公式チュートリアルに従ってください。
go install
go install github.com/tak848/ccgate@latest
GitHub Releases
Releases からバイナリをダウンロードし、PATH の通った場所に配置してください。
Homebrew
brew install tak848/tap/ccgate
クイックスタート — Claude Code
1. Claude Code の hooks に登録
~/.claude/settings.json:
{
"hooks": {
"PermissionRequest": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "ccgate claude"
}
]
}
]
}
}
"command": "ccgate" (subcommand なし) が Claude Code hook の正規呼び出し方法です。 ccgate claude はその明示形。
ccgate が PATH に通っていない場合は、hook の command を等価な呼び出し (例: mise exec aqua:tak848/ccgate -- ccgate claude) または絶対パスに書き換えてください。
2. API キー
ccgate は default で Anthropic の Claude Haiku を呼びます。 CCGATE_ANTHROPIC_API_KEY (ANTHROPIC_API_KEY でも可) を export してください。 OpenAI / Gemini に切り替える場合や、 各 provider の発行ページと環境変数の解決順は docs/ja/providers.md#api-キー を参照。
Provider の切り替え に OpenAI の gpt-5.6-luna の設定ブロックがあります。
ここまでで ccgate は組み込みデフォルトで動き始めます。allow / deny を自分で書きたい場合は docs/ja/rule-tuning.md を、ルールの仕組みを先に押さえたい場合は コンセプト を参照してください。
クイックスタート — Codex CLI
Note
Codex hooks は ~/.codex/config.toml に [features] hooks = true の設定が必要です。詳細は docs/codex-cli.md を参照。
1. Codex hook として登録
Codex は ~/.codex/hooks.json と ~/.codex/config.toml から hook を読み込みます (project が trusted なら <repo>/.codex/{hooks.json,config.toml} も overlay)。好きな方で登録してください。
~/.codex/hooks.json:
{
"hooks": {
"PermissionRequest": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "ccgate codex",
"statusMessage": "ccgate evaluating request"
}
]
}
]
}
}
~/.codex/config.toml:
[features]
hooks = true # Codex hooks はこの feature flag 配下にある
[[hooks.PermissionRequest]]
matcher = ""
[[hooks.PermissionRequest.hooks]]
type = "command"
command = "ccgate codex"
statusMessage = "ccgate evaluating request"
lookup 順序、 project-local overlay、 in-tree dev build 用の go run レシピは docs/codex-cli.md を参照。
2. API キー
provider の API キーを export してください — docs/ja/providers.md#api-キー を参照。 default は Anthropic の Claude Haiku で、 Provider の切り替え に OpenAI の gpt-5.6-luna の設定ブロックがあります。
ここまでで ccgate は組み込みデフォルトで動き始めます。allow / deny を自分で書きたい場合は docs/ja/rule-tuning.md を、ルールの仕組みを先に押さえたい場合は コンセプト を参照してください。
コンセプト
ccgate の allow / deny / environment はいずれも 自然言語の文字列リストです。これらが system prompt に埋め込まれて LLM に送られ、LLM が allow / deny / fallthrough のいずれかを返します。jsonnet 側で deterministic にマッチする engine ではなく、すべての PermissionRequest が LLM を経由する設計です。
評価フロー:
flowchart TD
A["Claude Code / Codex CLI"] --> B{"上流側の静的ルールで解決できる?"}
B -->|Yes| C["そのまま実行 / 拒否"]
B -->|No| D["PermissionRequest hook<br/>(stdin: HookInput JSON)"]
D --> E["ccgate"]
E --> F1["jsonnet config を読み込む<br/>embedded defaults + global + project-local"]
E --> F2["context を組み立てる<br/>git context, referenced_paths,<br/>recent_transcript (Claude のみ)"]
F1 --> G{"LLM (default: Haiku) が<br/>structured output で判定"}
F2 --> G
G -->|allow| H["実行"]
G -->|deny| I["deny_message 付きで拒否"]
G -->|fallthrough| J["上流の確認 prompt に戻す"]
ccgate が LLM に渡す情報 (代表項目):
tool_name,tool_input,tool_input_raw(元の JSON payload をそのまま渡す)。cwd,repo_root,branch_name, worktree info (gitutil.Contextから)。working tree の dirty/clean は 渡していない。referenced_paths—tool_inputから best-effort で抽出した path リスト。対象 tool はRead/Write/Edit/MultiEdit/Glob/Grep/Bashのみ。apply_patch(Codex) や MCP tool では空で、LLM はtool_input_rawの hunk / args を直接読む。- Claude のみ:
permission_mode("plan"で system prompt が plan mode rule に切替),permission_suggestions,recent_transcript,settings_permissionshint (whitelist ではなく hint 扱い)。
target ごとの完全な入力一覧は docs/claude-code.md / docs/codex-cli.md を参照してください。
設定
設定ファイルの読み込み順序
| 順序 | Claude Code | Codex CLI |
|---|---|---|
| 1 | 組み込みデフォルト (常にベースとして適用) | 同じ |
| 2 | ~/.claude/ccgate.jsonnet (グローバル) | ~/.codex/ccgate.jsonnet |
| 3 | {main_worktree}/.claude/ccgate.local.jsonnet (linked worktree のときのみ、Git 未追跡のみ) | {main_worktree}/.codex/ccgate.local.jsonnet |
| 4 | {repo_root}/.claude/ccgate.local.jsonnet (Git 未追跡のみ) | {repo_root}/.codex/ccgate.local.jsonnet |
合成ルール (要点):
- list (
allow/deny/environment): 設定した layer が引き継ぎを 置換。append_*は 末尾追加。 - スカラー (
log_*/metrics_*/fallthrough_strategy): per-field 上書き。 providerblock: ブロック全体を atomic に置換 (フィールド単位 merge なし)。
プロジェクトローカル設定は Git に追跡されていないファイルのみ 読み込む。 disable_load_main_worktree_local_config: true を (1) / (2) に書けば (3) をスキップ ((3) / (4) に書いても無視)。 詳細・全フィールドリファレンスは docs/configuration.md を参照。
ルールチューニング
provider と hook の登録が済んでから、自分の allow / deny / append_* を書きたくなったらここから。
- defaults を確認:
ccgate claude init | less/ccgate codex init | less(-p付きで.local.jsonnetの雛形も出せる)。 - どこに書く: グローバル
~/.<target>/ccgate.jsonnet、プロジェクトローカル<repo>/.<target>/ccgate.local.jsonnet(Git 未追跡のみ)。 - 置換 vs 追加: 基本は
append_allow/append_deny/append_environment(embedded defaults を残して自分のエントリを追加)。allow:/deny:は完全置換 (defaults を捨てて自分の list だけが有効)。
書き方の典型例 (Claude / Codex 別の append_allow / append_deny / 完全置換)、deny_message: ヒントの形式、std.native('env') / must_env で env を埋め込む方法、ccgate <target> metrics --details N を使った iteration workflow、fallthrough_strategy を含むその他の細部は docs/rule-tuning.md に集約してあります。
Provider と credential
provider.name (+ 必要なら model) を任意の layer で書き換えると provider を切り替えられます:
{
provider: {
name: 'openai',
model: '<openai model name>', // model 選定は docs/ja/providers.md 参照
},
}
対応する API キーは docs/ja/providers.md#api-キー を参照して export してください。 キーが見つからない場合 ccgate は上流ツールの確認画面に fallthrough するので、 provider 切替で hook が壊れることはありません。
provider の切替手順、 モデル選定時の確認事項、 API キーの解決順、 互換 proxy 経由での利用は docs/ja/providers.md にまとめてあります。
Refresh される credential (AWS STS / Vertex ADC / OpenAI 互換 gateway の virtual key / 社内 key broker など、 静的 env では追従できないケース) を扱いたいときは provider.auth を設定します。 3 形式から選びます:
type=exec— ccgate が credential helper コマンドを実行し、 stdout を credential として使う (expires_atを keyed cache)。type=file— 外部 rotator が書いた credential file を ccgate が読む。type=profile— Anthropic 専用。ant auth loginの profile を SDK に渡し、 SDK の refresh-token loop が credential を保有する。
helper 契約・キャッシュ・401/403 挙動・復旧手順を含む完全な仕様は docs/ja/api-key-helper.md を参照。
Fallthrough strategy
LLM が判定に自信を持てないと fallthrough を返し、上流ツールの確認画面にフォールバックします。これは対話セッションでは妥当ですが、スケジューラ / ボット等の無人実行では処理が止まります。 fallthrough_strategy を設定すれば LLM の迷いを allow / deny に強制変換できます (default は ask):
{ fallthrough_strategy: 'deny' } // 安全側: 迷ったら拒否。無人実行ではこちらを推奨
allow は LLM が迷った操作を無条件に通すので使う場面は限定されます。値の意味、対象外となるケース (API 応答打ち切り、API キー欠損、bypassPermissions / dontAsk、ユーザー対話 tool 等)、 metrics による監査は docs/ja/configuration.md を参照。
ログとメトリクス
- ログ:
$XDG_STATE_HOME/ccgate/<target>/ccgate.log(未設定なら~/.local/state/ccgate/<target>/) - メトリクス:
$XDG_STATE_HOME/ccgate/<target>/metrics.jsonl - 両ファイルとも
_max_size閾値でローテーション。
ccgate claude metrics # 直近 7 日、TTY テーブル
ccgate claude metrics --details 5 # fallthrough / deny の上位 5 コマンドをドリルダウン
ccgate codex metrics --json # JSON 出力 (機械可読)
列の意味、JSON エントリ schema、credential 障害集計は docs/ja/configuration.md#メトリクス出力 を参照。
既知の制約
- Plan mode の正しさはプロンプトのみに依存 (Claude のみ):
permission_mode == "plan"では、(a) 実装系 write の拒絶と (b) allow guidance に載っていない read-only クエリの許可、両方を LLM とシステムプロンプトに委ねている。どちらにも誤判定の余地あり。 - embedded default の特定ルールだけの部分削除は不可: layer は list を 完全置換 (
allow: [...]) するか 末尾追加 (append_allow: [...]) するかのどちらかで、1 件除外したい場合は残りをallow:/deny:に書き直す。 - jsonnet 側に runtime conditional logic なし: jsonnet 評価は hook 発火ごとの config load 時に、 ccgate が
tool_inputを見る前に実行される。tool_input/ git working tree state に基づく runtime 分岐は書けない (分類は LLM の仕事)。 config 評価時の env 読み込みのみstd.native('env')(name)/std.native('must_env')(name)で可能。
ドキュメント
- providers.md — Provider 切替、 API キー、 base_url、 互換 proxy
- rule-tuning.md — ルールチューニングの入り口 (defaults 確認、 append vs 置換、 3 パターン例、 iteration workflow)
- configuration.md — 設定 layering、 全フィールド reference、 fallthrough_strategy 詳細、 メトリクス出力
- api-key-helper.md —
provider.authリファレンス (helper の契約、 キャッシュ、 401/403 挙動、 復旧手順) - claude-code.md — Claude Code 固有の HookInput
- codex-cli.md — Codex CLI 固有の HookInput
- English README
CLI リファレンス
ccgate stdin から HookInput JSON を読み込む (Claude Code hook)。`ccgate claude` と等価。
ccgate claude bare ccgate と等価 (新規ユーザー向け推奨表記)
ccgate claude init [-p] [-o FILE] [-f] Claude Code 用の埋込デフォルトを出力
ccgate claude metrics [...] Claude Code のメトリクス集計
ccgate codex stdin から HookInput JSON を読み込む (Codex CLI hook)
ccgate codex init [-p] [-o FILE] [-f] Codex CLI 用の埋込デフォルトを出力
ccgate codex metrics [...] Codex CLI のメトリクス集計
top-level の ccgate init / ccgate metrics は実 subcommand ではなく、 per-target 形式への 1 行案内を出して exit 2 します。
開発
mise run build # バイナリビルド
mise run test # テスト実行
mise run vet # go vet
mise run schema # schemas/{claude,codex}.schema.json を再生成
Nix (flakes)
mise の代わりに flake.nix でも開発環境を立ち上げられます。Go 1.25 / golangci-lint / gopls / goimports / staticcheck / delve を dev shell にピン留めしています。
nix develop # dev shell に入る
nix develop -c go test ./... # シェルに入らず単発でコマンドを流す
flakes が有効な Nix が必要です (experimental-features = nix-command flakes)。
macOS では path_helper がシステム PATH を Nix より優先することがあります。which go で確認してください。
関連記事
- 日本語 (Zenn): https://zenn.dev/layerx/articles/20260428-ccgate
- English (dev.to): https://dev.to/tak848/ccgate-delegate-claude-code-codex-cli-permission-prompts-to-an-llm-274c
ライセンス
MIT