Claude Code の auto mode `hard_deny` 実用設計 — 自然言語ルール 4 階層で『自動承認・自動拒否』の境界を引く

Claude Code v2.1.136(2026-05-08)で autoMode.hard_deny が追加されました。自然言語で「ユーザー意図に関わらず拒否」ルールを宣言できる新仕組みで、environment / allow / soft_deny / hard_deny の 4 階層構成です。本記事では Tool(pattern) 形式の permissions.deny との違い、$defaults による継承、本番 DB・credentials・破壊コマンドへの実用テンプレ、auto mode を CI / Routines で安心して回すための運用設計までを解説します。

Claude Code v2.1.136(2026-05-08)で settings.autoMode.hard_deny が追加されました。autoModeauto mode の classifier に向けた自然言語ルール4 階層で書く仕組みで、hard_deny はそのうち 「ユーザー意図に関わらず無条件で拒否」 を担当します。CI / Routines / --dangerously-skip-permissions 系の自動運用が現実的になる過程で最も重要なガードレール部品として整備された機能なので、本記事では仕組み・既存の permissions.deny との違い・実用テンプレを実装目線で整理します。

到達点

  • autoMode の 4 階層(environment / allow / soft_deny / hard_deny)を理解
  • 自然言語ルール(autoMode)と Tool(pattern) 形式(permissions.deny)の住み分け
  • $defaults で組み込みルールを継承する書き方
  • 本番 DB / .env / 破壊コマンドへの実用ルールテンプレ
  • auto mode を CI / Routines で安心して回すための運用設計

まず position から

Claude Code には権限制御の系統が 2 つあります。

仕組み形式主にどこで使うか値の例
permissions.allow / permissions.denyTool(pattern) syntax普段の interactive モードと auto mode 両方"Bash(curl *)""Read(./.env)""Edit(src/**)"
autoMode.{environment, allow, soft_deny, hard_deny}自然言語(prose)auto mode の classifier に対するヒント"Never run terraform destroy""This is a sandboxed VM"

permissions.deny「決まったツール呼び出しパターンを止める」 ための機械可読ルール。autoMode「人間が読み下す日本語的なポリシー」 を classifier に渡す仕組みです。

hard_deny はこの後者の中でプロンプトを出さずに silently block する category です。

autoMode の 4 階層

{
  "autoMode": {
    "environment": ["..."],  // この環境はどんな場所か(コンテキスト)
    "allow":       ["..."],  // 自動承認していいルール
    "soft_deny":   ["..."],  // 自動承認しない。ユーザーに聞く
    "hard_deny":   ["..."]   // 無条件で拒否。プロンプトもしない
  }
}

それぞれの役割:

配列classifier への伝え方プロンプト挙動
environment「今いる環境はこういう場所」というコンテキスト(判定材料)
allow「これは安全」と classifier に渡す自動承認
soft_deny「これは慎重に」と渡すユーザーに確認(interactive のみ)
hard_deny「絶対に踏ませない」silently block、プロンプトしない

permissions.denyhard_deny の決定的な違い

両者は**同じ「禁止」**でも、設計意図が違います。

観点permissions.denyautoMode.hard_deny
文法Tool(pattern)自然言語
評価パターンマッチclassifier(モデル)が解釈
表現できること機械的にマッチする具体形意図ベース(「破壊的な〜は禁止」)
interactive モードでの overrideユーザー確認で override 可能(auto mode 固有)
auto mode での挙動該当ツール呼び出しを止めるsilent block、確認しない
用途知ってる悪手の固定パターン未知形の悪手にも備えるポリシー

要するに permissions.deny は「Bash(rm -rf /*)」、hard_deny は「Never destroy production data」のような抽象意図を書く場所です。両者は重ねがけすることが推奨です。

最小構成

// .claude/settings.json
{
  "autoMode": {
    "environment": [
      "$defaults",
      "This is a dev sandbox, NOT production. Real prod is gated behind a separate org."
    ],
    "allow": [
      "$defaults",
      "Run unit tests and lint freely.",
      "Restart the local dev server as needed."
    ],
    "soft_deny": [
      "$defaults",
      "Confirm before running `terraform apply` even with a plan file."
    ],
    "hard_deny": [
      "$defaults",
      "Never run `terraform destroy` or other infrastructure-destroying commands.",
      "Never delete or truncate any database, even in development.",
      "Never write or modify files inside the .env, .env.local, or any `secrets/` directory."
    ]
  }
}

ポイント:

  • $defaults を含めると、Anthropic が定義する組み込みルール群を継承して、その上に積めます
  • **環境(environment)**は「今いる場所の説明」として最初に書く。classifier が判断の前提に置きます
  • hard_deny短く・意図がはっきりした命題にする(「Never X」「Block Y」のような形)

実用テンプレ

開発環境の hard_deny(最低限)

"hard_deny": [
  "$defaults",
  "Never delete production databases or run `DROP DATABASE` against any host containing `prod`, `production`, or `live`.",
  "Never run `terraform destroy`, `pulumi destroy`, or `cdk destroy`.",
  "Never modify files under .env, .env.production, or paths containing `/secrets/`.",
  "Never run `git push --force` to `main`, `master`, or `release/*` branches.",
  "Never commit files containing API keys, private keys, or OAuth refresh tokens.",
  "Never run commands that send outbound network requests to non-allowlisted hosts (allowlist: api.anthropic.com, registry.npmjs.org, github.com)."
]

CI / Routines 向け追加

非対話で動かす CI / Routines / --dangerously-skip-permissions 環境では、追加で:

"hard_deny": [
  "$defaults",
  // 上記の開発環境ルール...
  "Never edit or delete files under .github/workflows/ unless the PR explicitly says 'CI change'.",
  "Never write to ~/.ssh, ~/.aws, or any credential-bearing directory.",
  "Never modify the package lockfile (package-lock.json, bun.lock, pnpm-lock.yaml) in fix-only PRs."
]

エンタープライズ向け environment

"environment": [
  "$defaults",
  "This is an internal repository at $COMPANY. All operations are audited.",
  "Production deployments must go through ArgoCD; never push directly to production endpoints.",
  "PII handling: never log, print, or include user emails or names in test data."
]

environmentclassifier の判断の前提になるので、「ここで作業しているのは誰で、ここから先は何」を明示すると allow / deny の判定精度が上がります。

soft_deny vs hard_deny の使い分け

状況推奨
ユーザーに確認させれば実行 OKsoft_deny
ユーザーが OK と言ってもやってほしくないhard_deny
CI / 非対話で確実に止めたいhard_deny(soft_deny はプロンプトが出ないので意味が薄い)
普段は確認、CI でも止めたいpermissions.deny に同じものを書いて重ねがけ

例えば「terraform apply は人間が確認すれば OK だが、terraform destroy は絶対 NG」だとすれば:

"soft_deny": ["Confirm before `terraform apply` and require the plan output to be reviewed."],
"hard_deny": ["Never run `terraform destroy` under any circumstances."]

自然言語ルールの書き方のコツ

  1. 短く、命題で書く。「Never X」「Always Y」「Block Z」の形が classifier に伝わりやすい
  2. 具体形(コマンド名、パス、フラグ)を1 つは入れる。「terraform destroy」と書く方が「破壊コマンド」より動く
  3. 理由は別に。environment で前提を、hard_deny で結果を分けて書く
  4. 重複を恐れないpermissions.denyBash(rm -rf /*) と書きつつ、hard_deny で「Never run rm -rf against system directories」も書いておく。ベルト+サスペンダー

auto mode を「CI / Routines で安心して回す」の設計

Code with Claude 2026 で発表された Routines / CI auto-fix を実運用に乗せる場合、ガードレール設計の 典型ステップ はこうなります:

  1. environment に **「これは CI / Routines の自動実行コンテキスト」**を明示
  2. hard_deny破壊系・credentials 系・本番系を 5〜10 個書く
  3. permissions.deny機械的に止めたい具体パターンTool(...) 形式で重ねる
  4. allow はあえて狭く書く($defaults + 必要なツールだけ)
  5. ローカルで dry-run + --debug で classifier の判定をチェック
  6. 配布後しばらく、OTel メトリクス(claude_code.policy_blocks 系)で実際にブロックされた件数を観測

狭く allow、広めに hard_deny+機械的なものは permissions.deny、意図的なものは hard_deny」が基本姿勢です。

ハマりやすいポイント

1. $defaults を入れ忘れる

$defaults 無しで hard_deny を上書きすると、Anthropic 組み込みの安全策まで外れます。慎重に。

2. soft_deny を CI で頼る

CI / --dangerously-skip-permissions 環境で soft_denyprompt が出ない → 結局通る、になります。CI で確実に止めたいものは hard_deny に書く

3. classifier が判断できない曖昧表現

  • 悪い: 「危険な操作は止める」(主観すぎる)
  • 良い: 「Never modify files under /etc/, /var/, or /usr/」(具体)

4. environment をスキップする

hard_deny を効かせるには、「ここは本番ではない、本番はあちら」「ここでは production という単語を含む host は触らない」といった前提が classifier に必要。environment を雑にすると判定が緩みます。

既存記事との関係

  • 本機能の存在は v2.1.132-138 roundup でも紹介しました
  • --dangerously-skip-permissions の拡張(v2.1.126)、Code with Claude 2026 の Routines / CI auto-fix / Remote Agents(keynote 記事)は、hard_deny で守る前提で初めて運用できる機能群です

まとめ

hard_deny「コードを書く Claude」を CI / 自動化に乗せるための要石です。permissions.deny(パターン)+ autoMode.hard_deny(意図)+ environment(前提)を重ねがけして、狭い allow から始める——これだけで、CI auto-fix や Routines のような自動運用を事故無く回しやすくなります。

「無条件で踏ませない」を自然言語で書ける、というのは未知形の悪手にも備えられる手段が一つ増えた、ということ。これまで permissions.deny で個別に潰していた悪手リストの大半は、hard_deny に意図ベースで集約するほうが運用が楽になります。

参考