金色の配線パターンが広がる基板の接写
設計と運用

危険なシェルコマンド対策、LLM判定とルールエンジンどちらを選ぶか

目次を見る

CI/CDのパイプラインやオンボーディング手順で、インターネット上からコピーしたコマンドをそのまま実行する場面は珍しくありません。Stack Overflowの回答やGitHubのREADMEに載っていたワンライナーを、中身を精査せずに貼り付けて実行した経験がある方もいるのではないでしょうか。

開発者向けのコマンド安全性チェックツール「Terminal Poltergeist」は、この問題に対してAIによる解析と決定的なルールエンジンを組み合わせる設計を採っています。これは個人のCLIツール選定だけでなく、社内の開発者プラットフォームに安全装置を組み込む際のアーキテクチャ判断としても参考になる事例です。この記事では、危険コマンド検知の仕組みをどう設計するか、判断軸を整理します。

どんな場面でこの判断が必要になるか

新人エンジニアのオンボーディング用Runbook、社内Wikiのトラブルシュート手順、CIのシェルスクリプトステップ。これらはすべて「コピペされたコマンドがそのまま実行される」経路です。

rm -rfの誤用やフォークボム(プロセスを無限増殖させDoS状態を起こすコマンド)、curl | bashのようにリモートスクリプトを検証なしにシェルへ流し込むパターンは、典型的な事故の入り口です。こうした経路に安全装置を挟むかどうかを考えるタイミングが、この判断が必要になる場面です。

判断軸1: 決定論的ルールか、AI推論か

Terminal Poltergeistのアーキテクチャで最も重要なのは、JavaScriptベースのルールエンジンとオープンウェイトLLM(重みが公開されているため自前でホストや検証ができる言語モデル)による解析を併用している点です。

ルールエンジンは既知の危険パターン(フォークボム、ディスクへの直接書き込み、危険なパーミッション変更など)を検出し、最低限守るべき深刻度(severity)を強制します。AIがどれだけ「これは安全です」と説明しても、ルールエンジンが危険と判定していればその結果を上書きできない仕組みです。

これは非機能要件の観点で言うと、可用性より安全性を優先するフェイルセーフ設計です。LLMは文脈に応じた柔軟な説明ができる反面、ハルシネーション(事実と異なる内容をもっともらしく生成する現象)のリスクがあります。既知の危険パターンについてはAIの判断に委ねず、決定論的なルールで下限を固定するという設計判断は、セキュリティ機構を設計する上で押さえておきたい基本です。

判断軸2: 静的解析のみか、実行を伴うサンドボックスか

Terminal Poltergeistは「送信されたコマンドは絶対に実行しない」ことを明言しています。字句解析(レキサー・パーサー)でコマンドをフラグ・引数・パイプ演算子などの構成要素に分解し、静的にリスクを判定する方式です。

これに対して、Dockerコンテナなどで実際にコマンドを動かして挙動を観測するサンドボックス実行という選択肢もあります。静的解析は安全性が高く実装も比較的軽量ですが、実行時にしか現れない副作用(環境変数依存の挙動など)は検出できません。サンドボックス実行は精度が上がる一方、隔離環境の構築・破棄コストや、サンドボックスからの脱出リスクという新たな攻撃対象を抱え込みます。

社内ツールとして導入するなら、まず静的解析から始めて、必要に応じてコンテナベースの検証ステップを追加する段階的な拡張が現実的です。

判断軸3: 外部AI APIへの依存をどこまで許容するか

Terminal PoltergeistはGroqのホスティング型推論API経由でopenai/gpt-oss-20bというオープンウェイトモデルを呼び出しています。これは実装コストを下げる一方、外部APIのレイテンシ・可用性・レート制限に解析機能全体が引きずられる構成でもあります。

オープンウェイトモデルを選んでいる理由は、将来的に自前インフラへ移行する選択肢を残せる点にあります。クローズドなAPIモデルのみに依存すると、ベンダーロックインと障害時の単一障害点(SPOF)という技術的負債を抱えることになります。

社内CIパイプラインに組み込む場合、外部API呼び出しがタイムアウトした際にコマンド実行をブロックするか、警告のみで通すかというフェイルオープン/フェイルクローズの選択も合わせて決めておく必要があります。

判断軸4: どこにチェックポイントを置くか

コマンド安全性チェックは「個人の端末」「CI/CDのステップ」「社内ドキュメント生成時」のどこに置くかで役割が変わります。

配置場所主な効果運用コスト
個人端末のシェルフック実行直前の最終防衛線低(個人設定で完結)
CIパイプラインのlintステップマージ前に機械的に弾ける中(パイプライン改修が必要)
社内Wiki/Runbook生成時の検証そもそも危険な手順を公開しない中〜高(レビュー運用の変更)
専用の解析Webツール任意のタイミングで人が確認低(既存フローに影響なし)
安全装置は「実行を止める場所」ではなく「理解を助ける場所」に置くほうが、開発者の抵抗感なく定着しやすい設計です。

ケース別の推奨

  • オンボーディング資料やトラブルシュートWikiを整備しているなら、Terminal Poltergeistのような解析専用Webツール型を併用し、手順作成者自身がコマンドを検証する運用が合います
  • CI/CDでシェルスクリプトを多用しているなら、shellcheckのような既存の静的解析linterに加え、危険パターン検出ルールをCIステップに組み込む方式が現実的です
  • 社内に複数チームがあり、危険コマンドの判断基準を統一したいなら、ルールエンジンを共通ライブラリ化し、各チームのCIから呼び出す構成が技術的負債を抑えられます
  • 外部ネットワークに依存できない閉域環境なら、外部AI APIを前提にせず、ルールベースのみで運用する選択も十分成立します

あえて見送るべき条件

危険コマンドの検出をLLMの判定結果だけに頼る設計は避けたほうがよい選択です。モデルの出力は確率的であり、同じ入力でも表現が揺れることがあります。

また、コマンドを実際に実行して挙動を確認するサンドボックス方式を、隔離構成を十分検討せずに導入するのも避けるべきです。隔離が甘いサンドボックスは、検証のつもりが本番環境への攻撃経路になりかねません。

小規模なチームで、かつコマンドの出どころがほぼ信頼できる内部ドキュメントに限られる場合は、専用ツールを新規導入するコストに見合わないこともあります。その場合はshellcheckの導入やコードレビューのチェックリスト強化で十分なことも多いです。

導入前に確認すること

危険コマンド対策を検討するなら、まず自分たちの開発フローのどこにコピペ実行の経路があるかを洗い出すところから始められます。

  • CIスクリプト・Runbook・Wikiのうち、外部コマンドが検証なしに貼られている箇所を確認する
  • 既存のlinter(shellcheckなど)でカバーできる範囲と、カバーできないパターンを切り分ける
  • AI解析を使う場合は、既知の危険パターンに対する最低深刻度をルールで固定できるか設計段階で確認する
  • 外部AI APIを使うなら、障害時にフェイルオープンかフェイルクローズかを決めておく

どの方式を選ぶにしても、「AIの説明をそのまま信用して実行判断する」構成だけは避け、決定論的な下限チェックを必ず併設する設計にしておくことが、事故を未然に防ぐ土台になります。

参考

My Friend Copy-Pasted Random Commands From the Internet, So I Built an AI Ghost to Save His System

この記事について: 本記事は AI を活用して作成し、forva AI 編集部が内容を確認・監修しています。

AI 駆動開発のご相談は forva AI へ。まずはお気軽にどうぞ。