入口の機械ゲート — 使い方と思想
AIで作ったコードの漏洩や脆弱性を「起きてから直す」のではなく「入る前に機械で止める」ための3つのゲートです。監査(事後の説明)の対になる「防止(事前の停止)」を担います。ただしこれらは既知パターンを止めるもので、網羅ではありません(「安全になる」ではなく「既知の事故を減らす」)。
このページは使い方だけでなく、なぜこの設計にしたのか(思想)も残します。設計は Claude・OpenAI Codex・xAI Grok の3つのAIによる独立レビューで方向づけし、活用するオープンソースは一次情報でライセンス・オフライン可否・保守を確認して選びました。
貫いている4つの原則
- AIの能力を落とさない。 ゲートが止めるのは「漏洩」と「危険」であって、AIの作る力ではありません。特に外部AIへコードを渡すときは、文脈を削るのではなく「全部渡すが秘密だけ隠す」を既定にしています。
- 止める判定は機械が、決定論で行う。 AIは分析の補助であって、停止の可否は決定論的なゲートが握ります。曖昧さで素通りさせません。
- 未検証を「安全」と偽らない。 専用ツールが入っていなければ「未検証(NOT-TESTED)」と正直に返し、「問題なし」とは扱いません。網羅を主張しません。
- 外部にコードを出さない。 漏洩対策の道具が漏洩源になっては本末転倒です。オフラインで動くツールだけを選び、外部送信するツール(クラウド必須のスキャナ等)は採用しませんでした。
ゲート1:コミット前に秘密を止める(gate-commit)
秘密(APIキー・トークン等)は、いったんGit履歴に入ると除去が高くつきます。コミットする前に止めるのが最も安上がりです。
python3 scripts/security_gate.py gate-commit .
- 多層防御:公開OSSの
gitleaksと、本体同梱のパターン検出を両方走らせ、どちらかが秘密を見つけたら止めます(終了コード非ゼロ)。実測で、あるトークンを gitleaks が見逃してパターンが捕捉した例があり、片方に委ねない方が安全だと確認しています。 - 個人情報(PII)は警告のみ:PIIのパターン検出は誤検知が起きやすいため、ブロックはせず警告にとどめます(誤検知で開発が止まる「オオカミ少年化」を避けるため)。
- 毎コミット自動化:同梱の
templates/pre-commit-config-template.yamlを対象プロジェクトへ.pre-commit-config.yamlとして置き、pre-commit installすれば、以後git commitのたびに自動で走ります。
思想:秘密検出を単一ツールに委ねない。ツールごとに取りこぼす対象が違うため、複数の検出器の「和(union)」で止めるのが安全側です。
ゲート2:外部AIへ渡す前に秘密・PIIを隠す(build-prompt-bundle)
別のAI(レビュー用のCodexやGrok等)へコードを渡す瞬間、それ自体が「外に出したくないコード」の外部送信になります。ここを手順の心得でなく機械で処理します。
# 既定=redactモード:全文脈を送りつつ、秘密とPIIだけをマスクする
python3 scripts/security_gate.py build-prompt-bundle <repo> --output <外部一時ディレクトリ>
# 機密性が極端に高いとき=allowlistモード:許可したパスだけ送る(文脈は減る)
python3 scripts/security_gate.py build-prompt-bundle <repo> \
--output <外部一時ディレクトリ> --mode allowlist --allow <許可リスト>
- 能力を落とさないのが既定:redactモードは、実装コードの文脈はそのまま渡し、APIキーやメールアドレスなどの秘密・PIIだけを伏せ字にします。だから外部AIは全体像を理解でき、レビューの質が落ちません。
- fail-close(安全側で失敗):万一、秘密がマスクを生き延びた場合は、束(bundle)を作らずに失敗します。「隠しきれていないのに送る」を機械的に防ぎます。
- 送信台帳:出力先には
transmission-ledger.json(何を・どのモデルへ送るか、各ファイルのハッシュ)が残り、記録として保存できます。バイナリは送らず一覧化されます。
思想:プライバシーと能力はトレードオフに見えて、両立できる。「渡すファイルを絞る」より「渡すが秘密を隠す」方が、漏洩を防ぎつつAIの理解を保てます。
ゲート3:依存の脆弱性を止め、部品表を残す(scan-deps / gen-sbom)
自分のコードが綺麗でも、取り込んだ依存パッケージに既知の脆弱性があれば穴になります。ここは依存の読み取り検査だけで、実装能力は一切制限しません。
# 依存の既知脆弱性(SCA):Critical/Highがあれば停止
python3 scripts/security_gate.py scan-deps <repo>
# ソフトウェア部品表(SBOM)をCycloneDX形式で生成
python3 scripts/security_gate.py gen-sbom <repo> --output sbom.cdx.json
- scan-deps は
osv-scanner(Google製・Apache-2.0・オフラインDB対応)で lockfile を検査し、Critical/High の脆弱性があれば停止します。 - gen-sbom は
syft(Anchore製・Apache-2.0)で、監査成果物に「何が入っているか」の機械可読な部品表を残します。 - 未導入なら「未検証」:これらのツールが入っていなければ「NOT-TESTED」を返し、cleanとは扱いません。導入は
brew install osv-scanner syft。 - コードは送らない:osv-scannerが外部に問い合わせるのは公開パッケージの名前とバージョンだけで、あなたのソースコードは送信されません。
思想:個人開発者には「少数の強いゲート」が現実的。常時稼働のSOC級監視やAIの自動修復・自動デプロイは、偽陽性と運用負担で無視されるようになり逆効果になり得るため、あえて載せていません。
全体の位置づけ
- これらのゲートは、事後の説明である監査(ai-audit)と、非エンジニアが急所を読むcritical-reviewの対になる「事前の防止」です。3つ揃えて「見せるだけ・止めるだけ」のどちらにも偏らない形にしています。
- 能力は強い。ただし保証ではない。 レビュアーのいない個人開発で、長いコードを一貫して検査し、複数の独立したAIで裏を取れることは、人手だけでは現実的に届きにくい強みです。実際、本プロジェクトの開発でも、実装したAI自身が見落とした不具合を別系統のAIが繰り返し見つけました。——それでも、未知の攻撃やツール自身の盲点は防げません。「何を検査し、何を検査していないか」を隠さないことを、このゲート群の誠実さの根拠にしています。
導入手順の全体像はスタートガイド、監査本体の詳細は監査内容の詳しい備考を参照してください。ソースと変更履歴はGitHubにあります。