🛡️ セキュリティ検査を全部AIに回す — Vercel + Neon + SvelteKit 個人運用の実装手順
第三者の脆弱性診断を受けられない個人・小規模運用で、「何でセキュリティをチェックしているか」を技術者に名前で答えられる状態を作る。使うツールの順位、無料枠の実数値、コピペできるCI設定、そして言ってはいけない主張までを一次情報だけで並べた。
🧱 入れる構成 — これが答え
このセクションの3点
① 無料で「AIが毎PRをセキュリティ観点で見る」を成立させる主役は Semgrep と Anthropic 公式 Action の2つ。CodeRabbit は手元(IDE・CLI)が無料で、PR自動レビューは月$24から
② 技術者が納得するのはツール名だけではない。「OWASP ASVS 5.0 Level 1 を物差しに」という一言が付いて初めて会話が終わる
③ 第三者による人手の脆弱性診断だけは、AIでは置き換えられない。そこは「未実施」と書く
「セキュリティはどうやってチェックしていますか」と技術者に聞かれたときに、固有名詞で答えられる状態を作る。それがこの記事の目的である。下の表がその答えそのもので、この表だけで導入判断ができるように書いた。
前提は、SvelteKit のアプリを Vercel に載せ、DB は Neon、リポジトリは非公開、開発者は実質1人という構成。有料の脆弱性診断は受けていない。
| 層 | 入れるもの | 何を見るか | この規模での費用 | 導入操作 | 顧客に名前を出せるか |
|---|---|---|---|---|---|
| 手元(書いている最中) | Claude Code の /security-review、CodeRabbit の IDE拡張・CLI | 書いた直後の差分 | 0円(CodeRabbit Free は IDE・CLI のみレビュー可) | 拡張を入れる | ○ |
| PR・脆弱性専門 | anthropics/claude-code-security-review | 差分の意味を読む脆弱性検査(SQLi・認可欠陥・秘密情報・暗号・RCE・XSS ほか10分類) | 0円(MIT)+ Anthropic API の従量課金 | workflow を1本置き、APIキーを Secrets に入れる | ◎ Anthropic 公式 |
| PR・機械的な網羅 | Semgrep AppSec Platform(AIトリアージ付き) | ルールベースの SAST とクロスファイル解析、依存(SCA)。AI が誤検知を判定して理由を書く | 0円(10コントリビュータ・10リポまで全機能) | GitHub でサインインしリポジトリを繋ぐ | ◎ |
| 秘密情報 | gitleaks | 作業ツリーと Git 履歴に混ざった鍵・トークン | 0円(OSS) | CI に1ジョブ(導入済み) | ○ |
| 依存パッケージ | npm audit + Dependabot alerts | 既知の脆弱性があるライブラリ | 0円 | CI に1ジョブ + alerts を有効化 | ○ |
| 認可の書き忘れ | 自作の検査スクリプト | 公開APIでスコープ照合を書き忘れていないか | 0円 | 既に導入済み | △ 自作なので名前では通らない。中身で説明する |
| 本番の外形 | securityheaders.com / Mozilla HTTP Observatory | 実際に配信されているレスポンスヘッダー | 0円 | URL を貼るだけ | ◎ 相手が自分で再現できる |
| 物差し | OWASP ASVS 5.0 Level 1 | 上の検査が何を覆っていて、何を覆っていないか | 0円 | 対応表を1枚作る | ◎ |
| (任意・有料)PR全般 | CodeRabbit Pro | 品質全般とセキュリティのインラインレビュー | $24/人・月(年払)、$30(月払) | GitHub App を承認する | ◎ 名前の通りは最上位 |
| (任意・有料)本番調査 | Vercel Agent | 異常アラート時の原因追跡と修正提案 | 1回 $0.30 +トークン実費。Pro/Enterprise の公開ベータ | ダッシュボードで有効化 | ○ |
費用の数字はすべて各社の公式価格表から取っている(2026-08-09 取得)。価格と無料枠は変わるので、引用するときは必ず取得日を添える。比較まとめサイトの数字は使っていない。実際に1件、まとめブログ由来の誤った数値で判断を誤りかけた。
「月額0円」と書いてはいけない
・固定の利用料は0円だが、Anthropic API の従量課金と GitHub Actions の実行時間は別途かかる。ここを混ぜて0円と言うと、確認票で実運用コストを聞かれたときに答えが崩れる
・Anthropic 公式 Action の既定モデルは opus 系でタイムアウトは20分。PR が多い月は無視できない額になる。上限額とアラートを先に設定する
・無料枠には人数条件がある。Semgrep は10コントリビュータまで。外注や一時的な協力者が1人入った瞬間に条件を割る可能性がある。数え方の定義を公式で確認しておく
0円
固定利用料の月額合計
従量
Anthropic API と Actions 実行時間は別途
8
自動で回る検査の数
4
人間が押す操作の数
📎 今日やる操作は3つだけ
1. Semgrep に GitHub でサインインし、リポジトリを1つ繋ぐ。10コントリビュータ・10リポまでは AI トリアージ込みで全機能が無料になる。
2. ワークフローを1本置き、Anthropic の API キーを GitHub Secrets に入れる。これで毎 PR に脆弱性レビューのコメントが付く。YAML は後の章にそのまま貼ってある。
3. ASVS 5.0 Level 1 の対応表を1枚作る。「どの項目を、どのツールで、どう確認しているか」を並べた表。これが無いと、ツールを何本入れても「で、何を見たんですか」で会話が止まる。
この構成で埋まらないものが1つある。人手による第三者の脆弱性診断である。AI を何本重ねても代わりにならない。顧客への回答では、ここは正直に「未実施」と書く。その書き方は最後の章にある。
→ 次のセクション:この中のどの名前が、実際に技術者や情シスに通じるのか。2つの軸で順位を出す
🏆 知名度ランキング(開発者軸 × 情シス軸)
このセクションの3点
① 「開発者に通る名前」と「情シス・購買に通る名前」は別物。Snyk は購買で最強、CodeRabbit は開発者で最強、順位が逆転する
② GitHub の star 数は「OSSとしての可視性」であって普及率ではない。CodeRabbit と Vercel Agent はクローズドソースなので star が 0 になる
③ 顧客に出すなら Snyk・OWASP・GitHub、開発者に出すなら Semgrep・CodeRabbit。両方に効くのは Semgrep
「○○でチェックしています」と言ったときの相手の反応は、相手の職種で変わる。開発者は使ったことがあるかどうかで判断し、情シス・購買は稟議に書ける名前かどうかで判断する。だから軸を2つに分けた。
数字の扱いを先に断っておく。開発者軸は GitHub の star 実測を根拠にしているが、情シス軸は筆者の判断であって計測値ではない。導入企業数やシェアの公開統計は存在しないため、ここを数字で装うのは嘘になる。
| 順 | 名前 | 開発者の中での通り | 情シス・購買での通り | AIの度合い | 無料枠(公式価格表) | 性格 |
|---|---|---|---|---|---|---|
| 1 | Snyk | ○ 知っている人は多い | ◎ 最強。AppSec 製品として稟議に通る | △ DeepCode AI を内蔵するが AI 前面ではない | Free で SAST 100テスト/月、SCA 200テスト/月 | 商用 AppSec の代表格 |
| 2 | GitHub(CodeQL / Dependabot / Secret scanning) | ◎ 全員が知っている | ◎ 「GitHub の標準機能」で話が済む | △ Copilot Autofix が AI | Dependabot alerts は無料。CodeQL は公開リポのみ無料、非公開は有料アドオン | プラットフォーム純正 |
| 3 | OWASP ZAP | ○ 定番として知られる | ◎ OWASP の名前が効く | × 非AI | 完全無料(OSS) | 動いているサイトを外から叩く |
| 4 | Semgrep | ◎ AppSec 界隈での評価が高い | ○ 説明は要るが通る | ◎ 検知・トリアージ・修正提案が AI | 10コントリビュータ・10リポまで全機能無料 | 両方の軸で戦える唯一の選択肢 |
| 5 | CodeRabbit | ◎ AIコードレビューの代名詞 | △ 新しく、セキュリティ専業ではない | ◎ ほぼ AI そのもの | Free は PR要約のみ。レビューは IDE・CLI のみ無料 | 品質レビュー全般 |
| 6 | Trivy | ◎ star 最多 | ○ コンテナ文脈なら通る | × 非AI | 完全無料(OSS) | コンテナ・IaC 寄り |
| 7 | gitleaks | ◎ 秘密情報検出の定番 | △ 単機能すぎて話が広がらない | × 非AI | 完全無料(OSS) | 鍵の混入だけを見る |
| 8 | anthropics/claude-code-security-review | ○ 公開から日が浅い | ○ Anthropic の名前で通る | ◎ Claude そのもの | 完全無料(MIT)+ API 従量 | 差分の意味を読む |
| 9 | Vercel Agent | △ 公開ベータ | △ まだ通らない | ◎ AI 前提 | 無料枠なし。1回 $0.30 +トークン実費 | プラットフォーム密着 |
GitHub star の実測(開発者軸の根拠)
コンテナ・IaC
秘密情報
SAST・AIトリアージ
DAST
クエリ集のみ
Anthropic 公式
本体はクローズド
クローズドソース=star なし
クローズドソース=star なし
star は「OSS としての可視性」であって導入企業数でも普及率でもない。CodeRabbit と Vercel Agent はクローズドソースのため star が存在せず 0 になるが、それは無名という意味ではない。また github/codeql はクエリ集のリポジトリであり、CodeQL 本体の利用者数を表さない。この2点を混同すると順位を読み違える。
| リポジトリ | star | 最終 push |
|---|---|---|
| aquasecurity/trivy | 37,312 | 2026-08-06 |
| gitleaks/gitleaks | 28,544 | 2026-07-29 |
| semgrep/semgrep | 16,158 | 2026-08-07 |
| zaproxy/zaproxy | 15,546 | 2026-08-06 |
| github/codeql | 9,921 | 2026-08-07 |
| anthropics/claude-code-security-review | 5,817 | 2026-02-11(約6か月更新なし) |
| snyk/cli | 5,633 | 2026-08-09 |
この表で一番重要なのは star ではなく右端の列である。Anthropic の公式 Action は 2026-02-11 を最後に約6か月 push が無い。動かないという意味ではないが、「公式が出しているから安心」で思考を止めてはいけない証拠になる。採用するなら、依存している Action のバージョンを自分で見ておく必要がある。
なぜ2軸で順位が逆転するのか
購買・情シスが見ているのはその会社が消えないか、責任を取れるかである。だから資金を持ち、監査に慣れ、営業窓口がある Snyk が強い。OWASP と GitHub が強いのも同じ理由で、個社に依存しないからである。
開発者が見ているのは自分の手が速くなるかである。だから CodeRabbit と Semgrep が強い。この2つの評価軸は交わらない。ひとつの名前で両方を満たそうとすると失敗する。
結論として、相手によって出す名前を変えるのが正しい。嘘ではない。全部実際に動かしているのだから、そのうちどれを先に言うかという話にすぎない。
順位と採用は別である。この表の1位は Snyk だが、無料枠が SAST 月100テストで足りないため、実際の構成では採用していない。順位は「名前を出したときに相手に通じるか」を表しているだけで、「上位から使え」という意味ではない。名前が通ることと、自分の規模で使えることは別の軸である。
📎 名前の出し分け
顧客・情シス・確認票に書くとき … OWASP ASVS(基準)→ Semgrep → GitHub の標準機能 → Anthropic。ここで CodeRabbit を先頭に出すと「それは何ですか」から始まってしまう。
技術者と雑談するとき … CodeRabbit → Semgrep → Claude Code の security-review。ここで ASVS から入ると硬い。
両方に効く唯一の名前は Semgrep。迷ったらこれを軸に話す。
→ 次のセクション:ツール名だけでは技術者は納得しない。「何に照らして見たか」という物差しの話
📏 物差しを決める — OWASP ASVS 5.0
このセクションの3点
① ISO27001 と SOC2 は組織の管理体制の証明であって、このアプリの実装は見ていない。だから技術者には効かない
② OWASP ASVS 5.0.0(2025-05-30 リリース)の Level 1 を、自己検証に使う基準の一つとして採用する。唯一の選択肢ではないが、領域ごとに満・未を示せる点で扱いやすい
③ ASVS 5.0 は「ブラックボックステストだけでは不十分、内部成果物へのアクセスが要る」と明言した。ソースを持っている自分たちが SAST を回す構成は、むしろこの要求に沿っている
ツールを何本入れても、技術者は「それで何がカバーされるんですか」と聞いてくる。この質問に答えられないと、入れた本数は評価されない。必要なのは何に照らして見たかという基準名である。
| 候補の物差し | 実際に言ったときの技術者の反応 | 採否 |
|---|---|---|
| ISO 27001 / SOC 2 | 「それは会社の管理体制の話で、このアプリの実装は見ていないですよね」→ 話が終わる | 不採用(そもそも取得していない) |
| OWASP Top 10 | 「10大脅威は啓発資料であってチェックリストではないですよ」→ 弱い | 不採用 |
| ツール名だけ(gitleaks を回しています 等) | 「それで何がカバーされるんですか」→ 範囲を説明できない | 不採用 |
| IPA「安全なウェブサイトの作り方」 | 日本の情シスには通りが良い。技術者には物足りない | 併記する |
| OWASP ASVS 5.0 Level 1 | 領域ごとに満・未を出せる。項目名で会話できる | 採用 |
ASVS 5.0 について確認した事実
| 項目 | 事実 | 出典 |
|---|---|---|
| 現行版 | 5.0.0 | OWASP ASVS プロジェクトページ |
| リリース日 | 2025-05-30(Global AppSec EU Barcelona 2025) | 同上 |
| Level 1 の位置づけ | Low assurance。自動的に検出しやすい脆弱性と統制が中心 | 同上 |
| 対象範囲 | アプリケーションと API。インフラとモバイルは範囲外 | 同上 |
| 5.0 での変更点 | 「ブラックボックステストだけでは意味のある検証にならず、内部成果物へのアクセスが必要」と明確化された。4.0.3 の「Level 1 はペネトレーションテストで網羅的に検査できる」という位置づけからの転換 | 同上 |
最後の行が、この構成にとって追い風になる。ASVS 5.0 は「外から叩くだけでは足りない」と言っている。つまり、ソースコードを持っている当事者が静的解析・依存解析・設定レビューを回すやり方は、この標準が求めている検証の形に近い。
逆に言えば、外形スキャンのサービスを1本契約して「診断しました」と言う構成のほうが、ASVS 5.0 の観点では弱い。ここは堂々と説明してよい部分である。
Level 1 対応表の作り方(これを1枚作る)
やることは単純で、領域ごとに「何で確認しているか」を1行ずつ書くだけである。下が実際の雛形。章番号は ASVS 5.0 の公式ドキュメントから引き写す(版によって番号が変わるため、本記事では領域名で示す)。
注意点が1つある。対応表を作ったことは、その要件を実装・検証したことを意味しない。対応表には必ず「対象外」「未対応」「代替統制で補っている」の行を残す。全部が埋まった表は、審査する側から見ると検証していない証拠に見える。
| ASVS の領域 | 何で確認しているか | 証拠の場所 |
|---|---|---|
| 認証 | JWT の署名検証、bcrypt コスト12、Claude / Semgrep の PR レビュー | CI のログとレビューコメント |
| セッション管理 | httpOnly・secure・sameSite の設定をコードレビューで確認 | PR レビューコメント |
| アクセス制御 | 自作の認可スコープ検査を CI の必須条件にしている(書き忘れると push できない) | CI のジョブ結果 |
| 入力検証・インジェクション | Semgrep のルールと Claude のセマンティック検査 | CI のログ |
| 暗号・秘密情報 | gitleaks を履歴込みで実行。1件でも検出したら失敗させる | CI のジョブ結果 |
| 設定・セキュリティヘッダー | 本番 URL に対する外形確認(第三者が同じ URL で再現できる) | 外形チェックのスコア |
| 依存関係 | npm audit を high 以上で失敗させる + Dependabot alerts | CI のジョブ結果 |
| ログと監査 | 業務監査ログを追記専用で保持(UPDATE・DELETE をトリガで拒否) | 管理画面のアクセス履歴 |
Level 2 以上を名乗らない
・Level 2・3 は人手による検証を前提にしている。自己検証で名乗ると、確認票の1行がそのまま虚偽記載になる
・「ASVS 準拠(compliant)」とも書かない。準拠は第三者が判定するもの。書くのは「ASVS Level 1 に照らして自己検証している」まで
・対応表に「未対応」の行が残っていても消さない。全部○が並んだ表は、逆に読み手の信用を落とす
→ 次のセクション:実際に置く YAML。コピーしてそのまま使える形で出す
🔧 導入手順 — コピペできるCI設定
このセクションの3点
① 置くファイルは2本だけ。Anthropic 公式 Action と Semgrep のワークフロー
② Action は @main ではなくコミット SHA で固定する。6か月更新が無いリポジトリを可変参照で使わない
③ API キーを使う AI レビューは、自リポジトリのブランチに限定する。フォーク由来の PR では動かさない。この Action はプロンプトインジェクション対策がされていないと公式が明記している
① 手で押す操作
| 操作 | 場所 | 所要 | 何が起きるか |
|---|---|---|---|
| Semgrep に GitHub でサインインし、リポジトリを繋ぐ | semgrep.dev | 5分 | SEMGREP_APP_TOKEN が発行され、結果がダッシュボードに集まる |
| Anthropic の API キーを Secrets に登録 | GitHub リポジトリ設定 → Secrets and variables → Actions | 2分 | CLAUDE_API_KEY として Action から使える |
| 外部コントリビュータのワークフロー承認を必須にする | GitHub リポジトリ設定 → Actions → Fork pull request workflows | 1分 | 知らない相手の PR で AI レビューが自動起動しなくなる |
| Dependabot alerts を有効化 | GitHub リポジトリ設定 → Code security | 1分 | 既知脆弱性のあるパッケージが通知される |
② Anthropic 公式 Action(.github/workflows/ai-security-review.yml)
anthropics/claude-code-security-review。MIT ライセンス・利用料は Anthropic API の従量課金のみ
name: AI セキュリティレビュー
on:
pull_request:
permissions:
contents: read
pull-requests: write
jobs:
security:
runs-on: ubuntu-latest
# フォーク由来の PR では実行しない。API キーを渡す処理を外部の差分に触れさせない
if: github.event.pull_request.head.repo.full_name == github.repository
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
fetch-depth: 2
# 必ずコミット SHA で固定する。下は placeholder なので、自分で確認した完全な SHA に置き換える
# (@main のままにすると、上流が書き換わった瞬間にそれが自分の CI で実行される)
- uses: anthropics/claude-code-security-review@<ここに検証済みのコミットSHAを貼る>
with:
claude-api-key: ${{ secrets.CLAUDE_API_KEY }}
comment-pr: true
upload-results: true
exclude-directories: node_modules,build,.svelte-kit,static
claudecode-timeout: 20| 入力 | 既定値 | 意味 |
|---|---|---|
| claude-api-key | (必須) | Anthropic の API キー。Claude API と Claude Code の両方で有効なキーが必要 |
| comment-pr | true | 見つけた内容を PR にコメントする |
| upload-results | true | 結果をアーティファクトとして保存する |
| exclude-directories | なし | 見なくてよいディレクトリ。ビルド生成物を外すと速くなる |
| claude-model | claude-opus-4-1-20250805 | 使うモデル |
| claudecode-timeout | 20 | タイムアウト(分) |
| run-every-commit | false | true にすると毎コミット走る(キャッシュを使わない) |
| false-positive-filtering-instructions | なし | 誤検知の除外ルールを自分で書いたファイルを渡せる |
| custom-security-scan-instructions | なし | 自分のアプリ固有の観点を追加できる |
この Action は既定で、サービス停止・レート制限・メモリ枯渇・影響が証明できない一般的な入力検証・オープンリダイレクトを「影響が小さい」として除外する。つまり可用性まわりは見ていない。ここは自分で見る領域だと理解しておく。
この Action の既知の制約(公式が明記)
・プロンプトインジェクション対策がされていない。信頼できる PR にだけ使うこと
・最終 push が 2026-02-11 で約6か月止まっている。@main での参照はやめ、確認したコミット SHA に固定する
・フォーク由来の PR には Secrets が渡らないため、そもそも動かない。「承認すれば動く」設定にすると、外部の差分に API キーを渡すことになり危険度が上がる。承認で解決しようとしない
📎 外部からの PR をどう扱うか
API キーを使う AI レビューは、自リポジトリのブランチだけで動かす。外部からの PR に対しては、Secrets を必要としない静的解析(Semgrep のルール実行や gitleaks)だけを走らせる。
そのうえで、取り込む判断をした後に、自リポジトリのブランチで AI レビューを回す。順序をこうすると、外部が書いた文字列が AI への指示として解釈される経路を作らずに済む。
③ Semgrep(.github/workflows/semgrep.yml)
無料枠は 10コントリビュータ・10リポジトリまで。AI によるトリアージと修正提案、クロスファイル解析、依存(SCA)まで含まれる
name: Semgrep
on:
pull_request:
push:
branches:
- main
jobs:
semgrep:
runs-on: ubuntu-latest
container:
image: semgrep/semgrep
steps:
- uses: actions/checkout@v4
- run: semgrep ci
env:
SEMGREP_APP_TOKEN: ${{ secrets.SEMGREP_APP_TOKEN }}無料枠には Secrets 検出(意味解析・エントロピー解析)は含まれない。ただしそこは gitleaks が既にカバーしているので、この構成では穴にならない。無料枠に含まれる AI クレジットは60。使い切ったあとも検知自体は止まらず、AI によるトリアージが止まる。
④ 既にあるゲートとの合流
| ゲート | 中身 | 失敗したらどうなるか | 追加か既存か |
|---|---|---|---|
| ビルド | npm run build | マージできない | 既存 |
| 型チェック | svelte-check | マージできない | 既存 |
| 秘密情報 | gitleaks(作業ツリー+履歴) | 1件で失敗 | 既存 |
| 依存 | npm audit(high 以上) | 失敗 | 既存 |
| 認可スコープ | 自作の検査スクリプト | 失敗 | 既存 |
| AI セキュリティレビュー | Anthropic 公式 Action | PR にコメントが付く(ブロックはしない) | 追加 |
| SAST | semgrep ci | 設定次第でブロックできる | 追加 |
⑤ ゲートを回避できないようにする(ここが抜けると全部無意味)
「すべての変更に検査が走る」と言うためには、検査を通さずに本番へ入れる経路が塞がっている必要がある。ここが抜けていると、CI を何本並べても「回避できる検査」にしかならない。
| 設定 | 何を防ぐか | 場所 |
|---|---|---|
| main への直接 push を禁止 | 検査を通さない変更が本番に出ること | ブランチ保護ルール |
| 必須チェックを指定する | 失敗した CI のままマージできてしまうこと | 同上 |
| マージ前に PR を必須にする | 履歴に残らない変更 | 同上 |
| 管理者にも保護を適用する | 自分自身が例外になること(1人開発では特に効く) | 同上 |
| 緊急変更の記録を残す | 「あのときだけ通した」が記憶に残らないこと | 運用ルールとして |
1人で開発していると、ブランチ保護は自分を縛るだけに見える。しかし確認票で問われるのは「検査を回避できる人がいるか」であって、回避する人がいるかではない。管理者にも適用しておかないと、この質問に「いいえ」と答えられない。
📎 ブロックするものと、しないもの
機械的に白黒が付くものだけをブロック条件にする。秘密情報・型・ビルド・認可の書き忘れがこれにあたる。ここは1件でも失敗させてよい。
AI の指摘はブロックしない。誤検知が混ざるものを必須条件にすると、必ず「とりあえず通す」運用になり、ゲート全体が形骸化する。AI はコメントを出すところまでにして、判断は人間が持つ。
→ 次のセクション:Vercel 側で無料のままできること、月$20 払うと何が解決するか
▲ Vercel 側 — 無料でできることとPro が要ること
このセクションの3点
① セキュリティヘッダーは無料・数十行で入り、第三者が URL を叩くだけで再現できる。費用対効果が最も高い一手
② レート制限・Log Drain・IP Bypass は Hobby では使えない。実際にコマンドを叩いてエラーで確認した
③ ログ保持が Hobby は1時間。「サーバーログを保全しています」と書いてしまうと事実と食い違う
| 項目 | Hobby(無料) | Pro($20/月) | 確認方法 |
|---|---|---|---|
| DDoS 緩和 | 自動で有効 | 同じ | プラットフォーム標準 |
| セキュリティヘッダー | アプリ側で自由に付けられる | 同じ | 本番 URL に curl を1回 |
| WAF カスタムルール | 作成できる | 同じ+高度な機能 | ダッシュボードまたは CLI |
| レート制限 | 使えない | 使える | CLI がエラーを返して判明 |
| IP バイパス | 使えない | 使える | 同上 |
| Log Drain(外部へのログ転送) | 使えない | 使える | 同上 |
| ログ保持期間 | 1時間 | 1日 | ダッシュボードの表示 |
| プレビュー環境のアクセス保護 | 有効(Vercel Authentication) | 同じ | プロジェクト設定 |
| AI コードレビュー(Vercel Agent) | 使えない | 公開ベータ。1回 $0.30 +トークン実費 | ダッシュボードの Agent 欄 |
表の中でいちばん効くのは2行目のセキュリティヘッダーである。無料で、数十行で入り、そして相手の技術者が自分で URL を叩いて10秒で確認できる。こちらの説明を信じてもらう必要がないという点で、他のどの対策とも性質が違う。
実際に踏んだ落とし穴 — ヘッダーが1つも付いていなかった
6種類のヘッダーを実装し、コードを読んでも正しく、レビューでも指摘は出なかった。ところが本番に curl を打つと1つも付いていなかった。
原因は、認証フックの末尾にヘッダー付与を書いていたこと。公開パスは途中で早期に return していたため、そこへ到達していなかった。同じ日に、同じ構造の欠陥を3件踏んでいる。
| 何が起きたか | 設計の形 | 実際の結果 |
|---|---|---|
| 共有リンクの職場スコープ | 各 API が自主的に照合する | 書き忘れて、認証不要で全社996人分の個人データが読めた |
| 管理画面のルート保護 | 保護するパスを許可リストで列挙する | 新しいページを足し忘れ、未認証で開けた |
| セキュリティヘッダー | フックの末尾に書く | 早期 return する経路で1つも付かなかった |
この3件はいずれも発見当日に修正し、本番へ反映済みである。そのうえで、記事にこう書くときは是正の情報を必ずセットにすること。「穴があった」だけを書くと、読み手には現在も未解決に見える。書くべきは、いつ塞いだか・どう再発を止めたか・影響をどう確認したか、の3つである。
そして、3つ目の「影響をどう確認したか」が書けなかった
・ログ保持が1時間のプランでは、塞いだ後に遡って外部からのアクセスがあったかを確認する手段が無い
・つまり「影響はありませんでした」と言うことができない。言えるのは「確認する手段が無かった」だけである
・これがログ保持を延ばす最大の理由になる。攻撃を防ぐためではなく、事故のあとに事実を述べられるようにするため
顧客に対して、健康情報のようなセンシティブなデータを扱う事業者が「影響は無かったと思われる」と答えるのは、審査する側から見ると最も弱い回答である。ログ保持は、平時には何の役にも立たず、事故が起きた日に初めて価値が出る。そのときには買い足せない。
📎 ここから引き出した原則
「明示しなければ守られない」設計を作らない。「明示しなければ通れない」形にする。
許可リストではなく既定拒否にする。各 API の善意ではなく型で強制する。フックの末尾ではなく全経路が通る場所に置く。3件とも、この一手で再発しなくなった。
そして重要なのは、3件ともコードを読んだだけでは分からず、実際に叩いて初めて分かったということである。AI に4つの視点でレビューさせても、認可の穴は確定できなかった。AI レビューは実測の代わりにならない。
Pro に上げる判断
月$20 で埋まるのはレート制限・外部ログ転送・ログ保持1日の3つ。ただし上で書いたとおり、ログ保持は「聞かれたら払う」ものではない。事故が起きた日に遡れないと、その後の説明が全部弱くなる。センシティブなデータを扱っているなら、ここは先に払う側に倒すのが妥当だと考えている。
先にやるべき順序が1つある。共有リンクのトークンが URL パスに露出している場合、外部ログ転送より先にそれを直す。順序を逆にすると、認証情報を外部のログサービスへ送り出すことになる。
→ 次のセクション:Neon の説明の作り方。保管地の話を隠さずに書く
🐘 Neon 側 — 顧客への説明の作り方
このセクションの3点
① 基盤(DB・ホスティング)は SOC2 と ISO27001 の監査を受けた事業者を使っている。ただし委託先評価・設定・契約の責任は自分に残る
② Neon は保存時 AES-256、通信時 TLS 1.2/1.3、年次監査を独立2社から受け、継続的なペネトレーションテストを実施していると公式に記載している
③ 一方でリージョンをシンガポールにした結果、「データは国内に留まる」とは言えなくなった。ここは隠さず訂正する
顧客への説明で失敗する最大の原因は、自分が担保する部分と、事業者が担保する部分をまぜて話すことである。まぜると、事業者の認証をあたかも自社の認証のように語ってしまう。分けて書けば、そのまま確認票の回答になる。
| 層 | 誰が担保するか | 証明の形 | 自分がすること |
|---|---|---|---|
| データセンター・物理 | クラウド事業者 | 第三者認証(SOC2・ISO27001) | 事業者を評価して選んだ記録を残す |
| DB の暗号化・可用性 | Neon | 公式ドキュメントの記載と年次監査 | リージョン・バックアップ・接続方式を選び、設定が意図どおりか確認する |
| ホスティング・DDoS 緩和 | Vercel | プラットフォーム標準機能 | 設定を有効にし、プランで使えない機能を把握しておく |
| アプリの認証・認可 | 自分 | コード・CI の検査結果・監査ログ | ここが本丸。全部自分の責任 |
| アプリの脆弱性 | 自分 | ASVS Level 1 の自己検証と AI レビューの記録 | 同上 |
| 第三者による脆弱性診断 | (未実施) | — | 未実施と書く |
Neon について公式ドキュメントで確認できること
| 項目 | 公式の記載 | 顧客説明での使い方 |
|---|---|---|
| 保存時の暗号化 | NVMe インスタンスストレージ上のデータをハードウェアモジュールで実装した AES-256 ブロック暗号で暗号化 | そのまま引用してよい |
| 通信時の暗号化 | TLS 1.2/1.3 で強制。PostgreSQL の verify-full にも対応 | そのまま引用してよい |
| 準拠している基準 | SOC2、ISO27001、ISO27701、GDPR、CCPA に沿った統制 | 「Neon が」と主語を明示して引用する |
| 監査 | 独立した2社による SOC2 と ISO の年次監査、および継続的なペネトレーションテスト | 基盤側は診断を受けていると言える |
| 削除データ | サーバーサイド暗号化のうえ30日間保持 | そのまま削除要求の回答に使わない。事業者側の保持期間であり、自社の削除手順を説明するものではない |
4行目が効く。「アプリ層は自己検証だが、基盤は第三者の監査と継続的なペネトレーションテストを受けた事業者を使っている」という言い方ができる。これは事実であり、かつ自分の未実施を隠さない。主語を必ず「Neon が」「Vercel が」にすること。ここを主語なしで書くと、自社が認証を取っているように読める。
事業者の認証は、自社の統制を1つも証明しない
・基盤事業者の SOC2 や ISO27001 は、その事業者の統制の証明であって、自社のアプリケーション・設定・アカウント管理・委託先管理を証明しない
・「認証を取った事業者を使っているので安全です」と書いた瞬間に、審査する側は「では御社の統制は何ですか」と聞いてくる。そこで詰まる
・正しい出し方は、事業者の証跡と自社の確認結果を<strong>別々の表で</strong>示すこと。混ぜて1つの表にしない
保管地の話は訂正して伝える
DB を移設した結果、保管地が東京からシンガポールに変わった。以前の資料に「データは国外に出ない」と書いていたなら、その記述は現在は事実ではない。訂正するかどうかは経営判断だが、放置すると「意図的に古い説明を残していた」という最悪の形になる。
| 保管地を国外にする前に確認すること | なぜ必要か |
|---|---|
| 委託にあたるのか、外国にある第三者への提供にあたるのかの整理 | 個人情報保護法上、必要な手続きが変わる |
| 顧客との契約にデータ保管地の定めがないか | 契約違反になる可能性がある |
| 顧客への事前通知・承認が必要か | 事後報告では済まない契約がある |
| 事業者の再委託先(サブプロセッサ)の一覧 | 保管地だけでなく、誰が触れるかが問われる |
| 変更時に通知を受け取れるか | リージョンやサブプロセッサは事業者側の都合で変わる |
「中国と関係のない企業」という要件に、リージョン一覧では答えられない
・提供リージョンに中国・香港が無いことは、事業者の資本関係を証明しない
・運用担当者がどの国からデータにアクセスするか、再委託先がどこにあるかも証明しない
・バックアップの保管先が本番と同じ地域とは限らない
・この要件が出たときに確認するのは、リージョン一覧ではなく、事業者の<strong>サブプロセッサ一覧・契約条件・アクセスに関する公式回答</strong>である。ここを取り違えると、要件を満たしたつもりで満たしていない状態になる
取り出せない DB を選ばない
移設のきっかけは、前の DB が認証方式の失効で到達不能になり、しかも通常のダンプが取れない設計だったため、データを退避できなかったことである。バックアップ以前に、そのDBは標準的な方法でデータを取り出せるかを選定時に確認する。これはセキュリティの話に見えないが、可用性と事業継続の話であり、確認票では必ず聞かれる。
📎 バックアップは「手順が書いてあること」まで含めて1セット
取得コマンドを1本用意しただけでは足りない。復元の手順が別ファイルに書いてあり、実際に一度復元してみた記録があるところまでが1セットである。確認票で問われるのは取得の有無ではなく、復元できるかどうかである。
→ 次のセクション:これが週にどう回るのか。人間の作業時間を分単位で出す
🔁 AIで回る運用サイクル — 人間の担当は週20分
このセクションの3点
① コード検査は全部自動で回す。ただしアカウント管理と実機での認可確認は、AI で置き換えられない別枠の仕事として残る
② 記録は予防・検知・修正の3種類に分けて残す。審査で問われる内容が違うため、まぜると使えない記録になる
③ 四半期に1回だけ、AI に任せない作業がある。バックアップからの復元と、本番への外形確認
- 1
コードを書いている最中
手元で AI が見る
Claude Code の security-review コマンド、または CodeRabbit の IDE 拡張・CLI。ここは無料で使える。この段階で直せば PR にすら出ない - 2
PR を出した瞬間
5つのゲートが自動起動
ビルド・型チェック・gitleaks・依存の既知脆弱性・認可スコープ検査。機械的に白黒が付くものだけをここでブロックする - 3
その数分後
AI 2種がコメントを付ける
Anthropic 公式 Action が差分の意味を読んで脆弱性を指摘し、Semgrep がルールベースで検出したうえで AI が誤検知かどうかを判定して理由を書く - 4
人間の出番(ここだけ)
コメントを採るか捨てるか決める
1 PR あたり数分。捨てる場合は理由を PR に一行書く。この一行が後から効く - 5
マージ後
本番へ自動デプロイ
デプロイ自体は自動。ここで人間が見るものは無い - 6
週に1回
外形を1回だけ確認する
本番 URL のセキュリティヘッダーを外部サービスで取り直す。スクリーンショットを1枚残しておく。ただしこれで分かるのはヘッダーだけで、認可は一切見ていない - 7
四半期に1回
AI に任せない4つ
バックアップから実際に復元する。権限別のテストアカウントで認可とテナント分離を実機確認する。全アカウントの権限を棚卸しする。ASVS Level 1 の対応表を見直し、未対応の行が減ったか増えたかを確認する
人間の作業時間(月あたりの見積り)
1 PR あたり数分×本数
Dependabot の PR
月1回の見直し
週1回×3分
四半期1回を月換算
これは実測値ではなく見積りである。PR の本数と指摘件数で大きく変わる。ここに実測を書いていないのは、この構成を回し始めた直後だからであり、数字を装わないためにあえて見積りと明記している。
| 作業 | 月あたりの分 | 自動化できるか |
|---|---|---|
| AI の指摘を採否判断する | 60 | できない。判断は人間が持つ |
| 依存更新をマージする | 30 | 一部できる。パッチ更新は自動マージにできる |
| ASVS 対応表を更新する | 20 | 半分できる。CI の結果から下書きは作れる |
| 外形チェックを取り直す | 12 | できる。ただし記録として残すため手動でも可 |
| バックアップ復元テスト | 10 | できない。ここは実際にやることに意味がある |
AI では埋まらない枠 ① アカウント管理
ここまでは全部コードの話である。しかし健康情報のようなセンシティブなデータを扱うとき、確認票で最初に聞かれるのはコードではなくアカウントの話である。AI レビューを何本入れても、この欄は1行も埋まらない。
| 統制 | 何を防ぐか | 頻度 | AI で自動化できるか |
|---|---|---|---|
| 管理者を含む全アカウントの多要素認証 | 認証情報が漏れたときの侵入 | 常時 | できない |
| 職務に応じた最小権限 | 1つのアカウントで全部見えてしまう状態 | 常時 | できない |
| 権限の定期棚卸し | 使われていない強い権限が残ること | 四半期 | 一覧の出力だけ可 |
| 退職・契約終了時の即時無効化 | 関係が切れた人のアクセスが残ること | 都度 | できない |
| 委託先・外注アカウントの管理 | 誰が触れるか把握できていない状態 | 都度 | できない |
| 特権操作の記録 | 「誰が本番データを見たか」に答えられない状態 | 常時 | 記録の実装は可 |
1人で開発していると、この表は全部「自分だけだから不要」に見える。しかし確認票が聞いているのは人数ではなく仕組みがあるかである。人数が1人であることは、多要素認証が無くてよい理由にならない。むしろ1人しかいないなら、そのアカウント1つが全部の入口になる。
AI では埋まらない枠 ② 実機での認可確認
外形チェックで分かるのはレスポンスヘッダーだけである。この記事の冒頭で挙げた「認証不要で全社分の個人データが読めた」という穴は、外形チェックでは1件も検出できない。検出するには、実際にアカウントを分けて叩くしかない。
| 確認する項目 | やり方 | 頻度 |
|---|---|---|
| 権限の違うアカウントで同じ画面・APIを叩く | テスト用アカウントを役割ごとに用意する | リリース前 |
| 他のテナント・他の職場のIDを指定して叩く | URL の ID 部分を他社のものに書き換える | リリース前 |
| 共有リンクの失効が効いているか | 期限切れのトークンで実際に開く | 四半期 |
| キャッシュに個人データが残らないか | ログアウト後に戻るボタンで開く | 四半期 |
| エラー応答が内部情報を出していないか | 壊れた入力を送る | 四半期 |
AI では埋まらない枠 ③ AI の指摘は毎回同じではない
これは運用上いちばん誤解されやすい点である。同じ差分を2回レビューさせても、同じ指摘が出るとは限らない。だから「AI レビューが通った」を「その差分は検査済み」と記録してはいけない。
記録に書けるのは「AI レビューを実行し、出た指摘に対応した」までである。「AI が見たので問題ない」と書いた瞬間に、その記録は検証に耐えなくなる。機械的なルールベースの検査(gitleaks・依存チェック・自作の認可検査)だけが、再現性のある「通った」を持つ。
記録は3種類に分けて残す
| 種類 | 何を書くか | 審査で問われること |
|---|---|---|
| 予防 | 入れた仕組みと、それを入れた日 | そもそも防ぐ設計になっているか |
| 検知 | 何によって見つけたか(CI・AI・実測のどれか) | 気づける仕組みがあるか |
| 修正 | いつ直し、いつ本番に出たか | 直すまでの時間はどれくらいか |
この3つをまぜて1本の履歴にすると、どの質問にも部分的にしか答えられない記録になる。分けて書けば、聞かれた種類の列をそのまま出せる。
📎 AI に任せてはいけない1つのこと
実際に叩いて確かめること。認可の穴も、ヘッダーが付いていなかった件も、コードを読んだだけでは分からず、AI に複数の視点でレビューさせても確定できなかった。本番または開発サーバーに対して実際にリクエストを投げて、初めて分かった。
AI は「見るべき場所」を大量に挙げるのは得意だが、「実際にどうなっているか」は実行しないと分からない。この1点だけは自動化の対象ではなく、手順として残す対象である。
→ 次のセクション:ここまでやっても、言ってはいけない主張がある
🚫 言ってはいけない主張
このセクションの3点
① 「診断済み」「準拠」「監査済み」の3語は使わない。いずれも第三者が判定する言葉である
② 確認票の「第三者による脆弱性診断を実施していますか」への答えは、現時点では「いいえ」。そのうえで代替統制を書く
③ 正直に「いいえ」と書くことで、他の項目の「はい」が信用される。全部「はい」の回答票は逆に疑われる
使ってはいけない3語
・「診断済み」… 診断は第三者が実施して報告書を出すもの。AI レビューは診断ではない
・「準拠(compliant)」… 準拠は第三者が判定するもの。自分で名乗れるのは「照らして自己検証した」まで
・「監査済み」… 監査は監査人が行うもの。CI が通っていることは監査ではない
| 書きたくなる表現 | なぜ危険か | 代わりに書く文 |
|---|---|---|
| セキュリティ診断を実施しています | 診断の定義と食い違う。1回突っ込まれると全体の信用が崩れる | OWASP ASVS Level 1 に照らして自己検証しています |
| OWASP に準拠しています | 準拠は第三者判定。ASVS 自体もレベルと検証者を要求している | OWASP ASVS 5.0 Level 1 を基準として使用しています |
| AI がセキュリティ監査をしています | 監査という語が誤解を生む。AI は指摘するが保証しない | マージされるすべての変更に対して AI によるセキュリティレビューを自動実行しています |
| 脆弱性はありません | 証明できない。1件出た時点で嘘になる | 検出された指摘は記録し、対応状況を残しています |
| AI レビューが通ったので問題ありません | AI は同じ差分でも毎回同じ指摘を出すとは限らない。「通った」を検査済みの意味に使えない | AI レビューを実行し、出た指摘への対応を記録しています |
| 認証取得済みの基盤を使っているので安全です | 事業者の認証は自社の統制を1つも証明しない | 基盤は SOC2 と ISO27001 の監査を受けた事業者を使用しています。自社アプリケーションの統制は別途こちらです |
| データは国内に保管されています | 実際の保管地と食い違う場合、最も重い虚偽になる | データベースは(実際のリージョン名)に配置しています |
確認票の書き方
| よくある設問 | 現時点の答え | 同じ欄に併記する内容 |
|---|---|---|
| 第三者による脆弱性診断を実施しているか | いいえ | 代替として、全変更に AI 2種と静的解析を自動適用し、記録を保持している |
| セキュリティ基準を採用しているか | はい | OWASP ASVS 5.0 Level 1 に照らした自己検証。対応表を提示可能 |
| 秘密情報の混入を検出する仕組みがあるか | はい | gitleaks を CI の必須条件にしている(履歴も走査) |
| 既知脆弱性のある依存を検出しているか | はい | npm audit を high 以上で失敗させ、Dependabot alerts も有効 |
| アクセス記録を保持しているか | はい | 業務監査ログを追記専用で保持。更新・削除を DB のトリガで拒否 |
| 管理者アカウントに多要素認証を設定しているか | (事実を書く) | 設定していないなら「いいえ」。ここを偽ると最も重い |
| 権限の棚卸しを定期的に行っているか | (事実を書く) | 頻度と直近の実施日を書く |
| 退職・契約終了時にアクセスを無効化する手順があるか | (事実を書く) | 手順書の有無を書く |
| 本番データへのアクセス記録を残しているか | はい | 誰がどの企業のデータを見たかを追記専用で記録している |
| ログの保持期間 | (実際の期間を書く) | プラットフォームの保持期間と、業務監査ログの保持期間を分けて書く |
| データの保管地 | (実際のリージョン名) | 事業者の第三者認証の有無を併記する |
📎 そのまま使える回答文
OWASP ASVS 5.0 Level 1 を基準に自己検証しています。main へマージされるすべての変更に対して(直接 push はブランチ保護で禁止しています)、AI によるセキュリティレビュー2種(Anthropic 公式のレビューと Semgrep の AI トリアージ)と、秘密情報検出・依存脆弱性検出・認可検査を CI で自動実行し、結果を日付付きで記録しています。基盤のデータベースとホスティングは、SOC2 および ISO27001 の第三者監査を受けた事業者を使用しています。自社アプリケーションに対する人手の第三者脆弱性診断は未実施です。
最後の一文を必ず付ける。付けるからこそ前半が信用される。
AI レビューを第三者診断の代わりだと説明しない理由は、精度の話ではない。診断とは「独立した立場の人間が責任を持って報告書を出す」という手続きの名前だからである。どれほど精度が上がっても、手続きが違うものを同じ名前で呼ぶことはできない。ここを混同しない限り、AI で回す構成は堂々と説明してよい。
→ 次のセクション:この記事自体を、2つの AI に専門家役でレビューさせた記録
📝 改訂ノート(v1 → v2)
このセクションの3点
① Codex(GPT)に大企業の情報セキュリティ責任者役を与えたところ、致命的2件・重大7件・中3件の計12件。うち11件を採用、1件を部分採用した
② 最大の抜けは「アカウント管理」だった。コードの検査を9本並べても、多要素認証・権限棚卸し・退職時の無効化には1行も触れていなかった
③ 2つの AI の指摘は重ならなかった。Codex は制度・契約・組織の統制を、Claude は自分が書いた文の内部矛盾と AI 自身の限界を指摘した
v1 を本番へ公開したあと、役割を分けた2つの AI にレビューさせた。同じ観点で2回見ても意味がないので、片方には審査する側の役を与えた。
| レビュアー | 与えた役割 | 指摘件数 | 指摘の傾向 |
|---|---|---|---|
| Codex(GPT-5.6) | 従業員1万人規模の情報セキュリティ責任者。年200社の確認票を審査する側 | 12件 | 制度・契約・組織統制。「この一文があると追加でエビデンス提出を求める」という審査側の反応つき |
| Claude(Opus 5) | この構成を実際に運用する実務担当 | 7件 | 記事内部の矛盾、価格前提が崩れる条件、AI 自身の限界の書き方 |
結果として2つの指摘はほとんど重ならなかった。Codex は「アカウント管理が丸ごと無い」「国外移転の法的整理が無い」といった、書いていないものを指摘した。Claude は「SHA で固定しろと書いておきながら掲載 YAML が @main のまま」といった、書いたものの矛盾を指摘した。見落としの種類が違う。1つの AI に2回聞くより、役を分けて別のモデルに聞くほうが効いた。
致命的・重大な指摘と、どう直したか
| # | 深刻度 | 指摘者 | 指摘 | v1 では | v2 で |
|---|---|---|---|---|---|
| 1 | 致命的 | Codex | 事故の記載に是正情報が無く、現在も未解決に見える | 「認証不要で全社996人分の個人データが読めた」とだけ書いていた | 当日修正・本番反映済みを明記。さらに「ログ保持1時間では影響の有無を後から確認できなかった」という事実を新しい警告として追加した |
| 2 | 致命的 | Codex | リージョン一覧は「中国と関係が無い」ことを証明しない | 「提供リージョンに中国・香港を含まないので説明できる」と書いていた | 全面削除。資本関係・運用アクセス国・再委託先を証明しないことを警告として明記し、確認すべきはサブプロセッサ一覧と契約条件だと書き換えた |
| 3 | 重大 | Codex | 月額0円の表示が API 従量課金を隠している | 統計カードに「0円/無料構成の月額合計」 | 「固定利用料の月額合計」に変更。API 従量・Actions 実行時間・人数条件が崩れる場合を警告として追加 |
| 4 | 重大 | Codex / Claude | SHA 固定を要求しながら掲載 YAML が @main のまま | コメントで「SHA に置き換える」と書きつつ、コードは @main | YAML 自体を placeholder に変更。貼っただけでは動かないので必ず置き換えることになる |
| 5 | 重大 | Codex | 「すべての変更に CI」と言うにはブランチ保護が要る | ブランチ保護に一言も触れていなかった | 「ゲートを回避できないようにする」節を新設。管理者にも保護を適用する理由を追加 |
| 6 | 重大 | Codex | 「自分で証明しなくてよい」は共有責任の誤認 | 基盤層の自分の作業を「なし」と書いていた | 「事業者の認証は自社の統制を1つも証明しない」という警告を新設。責任分界点の表も全行を書き換えた |
| 7 | 重大 | Codex | Neon の30日保持を削除要求の回答に流用すると誤回答になる | 「削除要求への回答に使う」と書いていた | 「そのまま回答に使わない」に訂正。自社の削除規程が別に要ることを明記 |
| 8 | 重大 | Codex | アカウント管理が丸ごと欠落している | 記述ゼロ | 「AI では埋まらない枠①」として節を新設。多要素認証・最小権限・四半期棚卸し・退職時の即時無効化・委託先アカウント・特権操作の記録を表にした |
| 9 | 重大 | Codex | 国外保管の法的整理が無い | 保管地の訂正だけ書いていた | 外国にある第三者への提供/委託の整理、契約上の定め、事前通知の要否、サブプロセッサ一覧を確認する表を新設 |
| 10 | 中 | Codex | 「唯一の物差し」は言い過ぎ | ASVS L1 を「自己検証で名乗れる唯一の物差し」と書いていた | 「基準の一つ」に変更。対応表を作ったことは実装・検証したことを意味しないという注意も追加 |
| 11 | 中 | Codex | fork PR では Secrets が渡らない。承認で解決しようとすると危険度が上がる | 「外部コントリビュータの承認を必須にする」とだけ書いていた | ワークフローに fork 除外の条件を追加。外部 PR には Secrets 不要の検査だけを走らせる運用を明記 |
| 12 | 中 | Codex | 外形確認では認可の穴を検出できない | 週1回の外形チェックだけ書いていた | 「AI では埋まらない枠②」を新設。権限別アカウント・他テナントID・共有リンク失効・キャッシュ・異常系の実機確認を表にした |
Claude 側の指摘(自分の書いたものへの点検)
| # | 指摘 | v1 では | v2 で |
|---|---|---|---|
| 13 | 価格の取得日が書かれていない | 価格表だけ載せていた | 取得日 2026-08-09 を明記し、引用時は取得日を添えるよう追記 |
| 14 | 無料枠の人数条件が崩れる場面がある | 「10コントリビュータまで無料」とだけ | 外注や一時的な協力者が入ると条件を割ること、数え方の定義を公式で確認することを追加 |
| 15 | 順位と採用が矛盾して見える | 1位が Snyk なのに構成では採用していない | 「順位と採用は別」という注意を追加。名前が通ることと自分の規模で使えることは別軸だと明記 |
| 16 | 対応表を作った=検証した、と読める | 雛形だけ載せていた | 「対象外」「未対応」の行を必ず残す、全部埋まった表は逆に疑われる、を追記 |
| 17 | AI の指摘は毎回同じではない | 触れていなかった | 「AI では埋まらない枠③」を新設。記録に書けるのは「実行し対応した」までで、「AI が見たので問題ない」は書けないと明記 |
| 18 | 禁句リストに漏れがある | 3語だけ挙げていた | 「AI レビューが通ったので問題ない」「認証取得済みの基盤なので安全」の2つを追加 |
| 19 | ログ保持を「聞かれたら払う」ものとして書いていた | Pro 判断を確認票の設問で決める書き方 | 事故の日に遡れないと以後の説明が全部弱くなる、という理由に書き換えた |
部分採用にしたもの
Codex の指摘1は、事故報告書・アクセスログ・影響評価・本人への通知判断までを記事に書くよう求めていた。ここは部分採用にした。この記事は運用手順であって事故報告書ではないため、個別の事案の詳細は載せない。代わりに「この種の事故を記事や資料に書くなら、いつ塞いだか・どう再発を止めたか・影響をどう確認したかの3点をセットにしないと逆効果になる」という一般則として書き直した。
そして、その3点目が自分たちには書けなかったという事実を隠さずに残した。指摘に従って書けないことが分かったなら、書けないことを書くのが正しい。
📎 v1 執筆中に、レビュー前に自分で潰した誤り
「CodeRabbit の無料枠は非公開リポジトリで月200レビュー」は誤りだった。比較まとめブログ由来の数字で、公式ドキュメントを当たると Free は PR の要約のみ、コードレビューは IDE 拡張と CLI でのみ無料である。
この1件で記事の結論が変わった。無料で PR 自動レビューを成立させる主役は CodeRabbit ではなく Semgrep と Anthropic 公式 Action になる。一次情報に当たらなければ、間違った構成を勧めていた。
📎 このレビュー工程から学んだこと
AI に「役」を与えると、指摘の種類が変わる。「レビューして」だけでは、書いてあるものの粗しか出てこない。「審査する側」「年200社を見ている」と与えたことで、書いていないものが12件出た。
そして、致命的2件・重大7件が出たという事実そのものが、この記事の結論を裏付けている。AI で検査を全部自動化しても、AI が見ていない領域は残る。だから最後に人間が「何を見ていないか」を問い直す工程が要る。その工程もまた AI にやらせられるが、役を変えないと同じ盲点を繰り返す。
→ v1 公開: 2026-08-09 / v2 公開: 2026-08-09(同日・レビュー反映)