Ana içeriğe geç
友田 陽大
Application-layer security
Next.js
セキュリティ
アーキテクチャ設計
TypeScript

セキュリティをCIで止める — GitHub Actions・SARIF・『高確度のみブロック』の設計

セキュリティ検査をCIに組み込み、高確度の検出だけでビルドを止める設計。GitHub ActionsでのSAST実行、SARIFによるコードスキャニング連携、誤検知でCIを壊さない(静的×動的の相関で確証のみブロック)運用を、実際のYAMLとコマンドで解説します。

Published
Reading time
23 min read
Author
友田 陽大
Paylaş

最初に結論を述べます。セキュリティ検査は「人が思い出したときに手元で走らせるもの」である限り、いつか必ず忘れられます。 価値を生むのは、PRを開いた瞬間にCIが自動で走り、高確度の脆弱性だけがマージをブロックする仕組みにしたときだけです。本記事は、その仕組みを GitHub Actions と SARIF で組む方法を、実際のYAMLとコマンドで示します。

ただし、もう一つ最初に正直に言っておきます。CIゲートはセキュリティの"仕組み化"であって、設計レビューや手動監査の代わりにはなりません。 ツールは「よくある罠を踏んでいないか」を機械的に番をするだけで、あなたの認可ロジックが「正しいか」は証明しません。本記事が扱うのは、その境界を踏まえたうえで——自動化できる検査を、誤検知でCIを壊さずに、継続運用の歯車として組み込む設計です。


1. なぜ「PRで止める」のか——シフトレフトの経済学

脆弱性は、見つかるのが遅いほど直すコストが跳ね上がります。

見つかるタイミング状態直すコスト
コーディング中(手元)まだコミットしていないほぼゼロ。書き直すだけ
PRレビュー(CI)マージ前。差分が小さい低い。文脈が新鮮なうちに直せる
本番リリース後デプロイ済み・データに影響高い。調査・パッチ・場合により事故対応
インシデントとして発覚漏洩・悪用が進行最悪。信頼の損失まで含む

「シフトレフト(shift left)」とは、この表の上の方——できるだけ**左(=開発の早い段階)**で問題を潰す思想です。CIにセキュリティ検査を入れる本質は、ここにあります。本番に出た脆弱性を後から探すのではなく、PRの時点で「そもそもマージさせない」。

重要なのは、これが人間の規律に依存しない点です。「コミット前にスキャンを忘れずに」という運用は、忙しい日に必ず破られます。一方、CIゲートは忘れようがない——PRを開けば自動で走り、赤ければマージボタンが押せない。セキュリティを「気をつける」から「構造で強制する」へ移すのが、CIゲートの第一の価値です。

この発想は、セキュリティに限らずAI生成コード全般の品質統制と地続きです。型・テスト・セキュリティをCIで束ねる考え方はAI駆動開発の品質ゲート設計に整理しました。本記事はその「セキュリティ検査の歯車」を、SARIFとGitHub Actionsで具体化したものです。

なお、何を自動化で潰し、何を設計で守るのか——という全体地図はNext.js × Supabase アプリケーションセキュリティ完全ガイドにまとめています。本記事はそこで言う「水平統制・注入クラスの検出をCIに常設する」部分の実装編です。


2. SARIFとは何か——「検査結果」の共通言語

CIでセキュリティ検査を回すとき、最初にぶつかる問題があります。ツールごとに出力フォーマットがバラバラだということです。あるツールはJSON、別のツールはテキスト、また別のはJUnit XML——これではGitHubのUIに統一して表示できず、ツールを乗り換えるたびに連携を書き直すことになります。

ここで効くのが SARIF(Static Analysis Results Interchange Format) です。SARIFは、OASISが標準化した静的解析結果を表現するためのJSONベースの標準フォーマットです(OASIS SARIF v2.1.0)。どんなSASTツールでも、結果をSARIFで吐けば、それを受け取る側(GitHub等)は中身を統一的に扱えます。

SARIFの最小構造は、ざっくりこうです。

// SARIF v2.1.0 の骨格(型のイメージ)。実際のファイルはツールが生成する
type Sarif = {
  version: "2.1.0";
  runs: Array<{
    tool: { driver: { name: string; rules: Array<{ id: string }> } };
    results: Array<{
      ruleId: string;                 // どの検査ルールに当たったか
      level: "error" | "warning" | "note"; // 深刻度 → CIの赤/黄を決める
      message: { text: string };      // 人間が読む説明
      locations: Array<{              // どのファイルの何行目か
        physicalLocation: {
          artifactLocation: { uri: string };
          region: { startLine: number };
        };
      }>;
    }>;
  }>;
};

ポイントは3つです。

  1. ruleId — どの検査に引っかかったか。GitHub上でルール単位の集計・抑制ができます。
  2. levelerror / warning / note。これがCIで何を赤にし、何を黄色(警告)に留めるかの根拠になります。後述の「高確度のみブロック」は、ここをどう割り当てるかの設計です。
  3. locations — ファイルと行番号。これがあるから、GitHubはPRの差分に行単位の注釈を打てます。

つまりSARIFは「検査結果の共通言語」です。ツールを乗り換えてもCI連携はそのまま、UIへの表示もそのまま。検査ロジックと表示・運用を疎結合にできるのが、標準フォーマットを使う最大の利点です。


3. GitHub コードスキャニングに載せる——差分注釈とSecurityタブ

SARIFを吐けたら、次はそれをGitHubに食わせます。GitHubには コードスキャニング(code scanning) という機能があり、SARIFをアップロードすると2つの場所に結果が現れます(GitHub code scanning docs)。

  • Security タブ — リポジトリの全アラートが一覧化され、ルール別・深刻度別に管理できる。既知の指摘を「無視(dismiss)」したり、再発を追跡したりできる。
  • PRの差分(Files changed) — 検出された行にインラインの注釈が付く。レビュアーは「この変更がこの脆弱性を入れた」を、コードを読みながらその場で見られる。

この「PRの差分に注釈が出る」体験が決定的です。セキュリティの指摘が、別のダッシュボードや週次レポートではなく、まさにレビューしているコードの横に出る。直す文脈が新鮮なうちに、最小の差分で直せます。第1節のシフトレフトを、UIのレベルで実現するのがコードスキャニングです。

GitHubが受け取るのはあくまでSARIFなので、ここでも特定ツールへのロックインはありません。SARIFさえ吐ければ、自作ツールでもOSSでも、同じレールに載ります。


4. 実YAML——GitHub ActionsでSASTを走らせ、SARIFを上げる

ここからが実装の中心です。私が公開しているOSSセキュリティスキャナ Aegis には GitHub Action が同梱されており、uses 一行でCIに組み込めます。Aegisは Next.js × Supabase の注入クラス(汚染入力→危険シンク)やRLS/認可の弱点を検出し、結果をSARIFで出力します。

以下を .github/workflows/security.yml に置くだけで、push と PR のたびにスキャンが走り、結果がコードスキャニングに載ります。

# .github/workflows/security.yml
name: Security
on: [push, pull_request]

jobs:
  aegis:
    runs-on: ubuntu-latest
    permissions:
      contents: read          # コードを読むためだけの最小権限
      security-events: write  # SARIF を Security タブへアップロードするのに必須
    steps:
      - uses: actions/checkout@v4

      - uses: tomodahinata/aegis@main
        with:
          severity: HIGH       # HIGH 以上だけを「赤(ブロック)」に昇格させる

      - uses: github/codeql-action/upload-sarif@v3
        if: always()           # スキャンが失敗しても結果は必ずアップロードする
        with:
          sarif_file: aegis.sarif

短いですが、設計上の判断が4つ詰まっています。順に解きます。

4-1. permissions は最小権限で固定する

ワークフローに与える権限は、必要なものだけに絞ります。

  • contents: read — リポジトリのコードを読むため。書き込みは不要なので read
  • security-events: write — SARIFをアップロードしてコードスキャニングのアラートを作るのに必須の権限です。これが無いと upload-sarif が失敗します。

ここで write を広げすぎない(例えば contents: write を付けない)のは、CIワークフロー自体が攻撃面だからです。サプライチェーン攻撃では、過剰な権限を持つワークフローが踏み台にされます。最小権限の原則(OWASPのApplication Security Verification Standardが一貫して説く思想)は、アプリのコードだけでなくCIの設定そのものにも適用します。

4-2. if: always() で「結果は必ず上げる」

upload-sarif のステップに if: always() を付けています。これは、前のスキャンステップが「脆弱性あり」で失敗(exit 1)しても、SARIFのアップロードは実行するためです。

これが無いと、こういう最悪の挙動になります——「HIGHの脆弱性が見つかってスキャンが赤くなった」→「ジョブが止まってアップロードがスキップされる」→「一番見たい指摘がコードスキャニングに載らない」。ブロックすることと、指摘を可視化することは別の関心事です。always() で後者を必ず保証します。

4-3. severity: HIGH が「ブロックの閾値」

with: severity: HIGH が、本記事の核心である**「高確度のみブロック」の入口**です。これは「HIGH以上の確度・深刻度を持つ検出だけを、CIを赤にする(マージをブロックする)対象にする」という指定です。MEDIUM以下は——後述しますが——SARIFには載せてコードスキャニングで見えるようにしつつ、ビルドは止めない(警告に留める)運用が基本になります。

なぜこの閾値設計が決定的なのかは、次節で詳述します。

4-4. Action 参照は tomodahinata/aegis@main

uses: tomodahinata/aegis@main は Aegis Action の正しい参照です。v1 のようなタグはまだありませんので、@main を使ってください。本番運用でバージョンを固定したい場合は、@main の代わりにコミットSHAでピン留めする(tomodahinata/aegis@<commit-sha>)のが、サプライチェーン的には最も安全です(タグやブランチは動きうるが、SHAは不変)。


5. ノイズ問題——「誤検知でCIを壊す」と、ゲートは無視される

ここが、CIセキュリティで最も多くのチームが失敗するポイントです。技術的な難しさではなく、運用の力学の問題です。

セキュリティゲートを入れた直後、ツールが大量の指摘を吐いたとします。その多くが誤検知(false positive)——実際には悪用できない、文脈的に問題ない指摘だったとします。すると何が起きるか。

  1. PRが毎回赤くなる。しかも理由の大半が「直す必要のない指摘」。
  2. 開発者は「またノイズか」と赤を信用しなくなる
  3. やがて誰かが「とりあえず通すために」ゲートを continue-on-error にするか、ジョブごと無効化する。
  4. セキュリティゲートが死ぬ。 本物の脆弱性も一緒にすり抜けるようになる。

これは仮想の話ではなく、CIセキュリティ導入の典型的な失敗曲線です。「厳しすぎるゲートは、必ず迂回される」。狼少年と同じで、嘘の警報が続けば、本物の警報も無視されます。

ここから導かれる原則は一つです。

CIをブロックする検出は、誤検知率が極めて低いものに限定する。 残りは「警告として見せる」に留め、ビルドは止めない。ゲートの信頼は「赤が出たら本当にヤバい」という体験でしか育たない。

問題は、「どうやって誤検知率の低い検出だけを選り分けるか」です。深刻度(severity)が高い=確度が高い、ではありません。「これはSQLインジェクションかもしれない」という静的解析の"疑い"は、深刻だが不確実です。この不確実性をどう潰すか——それが次節のSAST×DAST相関です。


6. 高確度のみブロック——静的の"疑い"を動的で"確証"に格上げする

「高確度だけをブロックする」を実現する鍵は、確度の出どころを二重化することです。一つの静的解析だけで「これは確実」と断ずるのは難しい。だから、静的解析(SAST)の疑いを、動的プローブ(DAST)で実際に再現できたかで格上げします。

6-1. 二段階の確度モデル

SAST(静的解析)        :コードのデータフローを追い、「汚染入力→危険シンク」を疑う
   ↓ 疑い(potential)
DAST(動的プローブ)     :自分のアプリを実際に叩き、その疑いが再現するか確かめる
   ↓ 再現できた
confirmed(確証)       :静的×動的が一致 → これだけを CI でブロックする
  • SASTは「疑う」。第2のガイドで詳述した「params.id が所有権チェックなしでDBクエリに届く」ようなパターンを、関数内のtaint解析で機械的に拾います。これは速くて網羅的ですが、文脈次第で誤検知も出る(例:別の場所で実は絞り込まれている)。
  • DASTは「再現する」。自分が所有するアプリに対して、2つのアイデンティティ(A・B)を用意し、Aのセッションのまま Bのリソースを叩く——といった安全・非破壊なプローブを実行します。200が返って他人のデータが見えたら、その疑いは実行時に確証されます。

そして、SASTの疑いとDASTの再現が一致したものだけconfirmed-exploitable(確証済み)として、SARIFの level: "error" = CIブロック対象に昇格させます。再現できなかった静的の疑いは warningnote に留め、コードスキャニングには出すがビルドは止めない

これが「高確度のみブロック」の実体です。深刻度の高さではなく、"動的に再現できた"という事実を、ブロックの根拠にする。

6-2. ローカルでの相関——CIに入れる前に手で確かめる

CIに組み込む前に、まず手元でこの相関を体感しておくとよいです。Aegisはスキャンとプローブを別コマンドで提供しています。

# 1. 静的解析:汚染入力→危険シンク/所有権なしクエリを「疑う」
npx @aegiskit/cli scan

# 2. 動的プローブ:自分のアプリを実際に叩き、疑いが「再現するか」確かめる
#    --correlate で静的の結果と突き合わせ、再現したものを confirmed に格上げ
npx @aegiskit/cli probe http://localhost:3000 --correlate

--correlate を付けると、scan の疑いのうち probe で再現したものが確証済みとしてマークされます。この「確証済みだけが赤」という体験を手元で作っておくと、CIに severity: HIGH で入れたときの赤の意味が腑に落ちます。

プローブの倫理的境界。 DASTは自分が所有・管理するアプリに対してのみ実行してください。他人のサービスへの無許可のプローブは攻撃と区別がつかず、法的にも問題になります。Aegisのprobeは非破壊(読み取り中心、データを壊さない)設計ですが、対象は必ず自分のステージング/ローカルに限ります。


7. 段階導入——いきなりブロックしない(warn → block)

「高確度のみブロック」を設計しても、初日からブロックを有効にするのは悪手です。既存のコードベースには、まず確実に**過去分の指摘(ベースライン)**が溜まっています。それを全部ブロックにすると、関係ない人のPRまで赤くなり、第5節の「ゲートが死ぬ」曲線に乗ります。

正しい順序は、warn から始めて、信頼が育ってから block に上げるです。

段階1:警告のみ(ビルドは止めない)

まずは「結果を可視化するが、ブロックはしない」状態から始めます。スキャンステップに continue-on-error: true を付け、SARIFのアップロードだけ確実に行います。

# 段階1:warn のみ。指摘は Security タブと差分注釈に出すが、CI は赤にしない
- uses: tomodahinata/aegis@main
  with:
    severity: HIGH
  continue-on-error: true   # ← 検出があってもジョブを失敗させない(観察期間)

- uses: github/codeql-action/upload-sarif@v3
  if: always()
  with:
    sarif_file: aegis.sarif

この期間に、チームは「どんな指摘が出るか」「どれが本物でどれがノイズか」を学びます。既存の確証済み指摘は、この間にPRで潰すか、後述の抑制で正式に「無視」を記録します。

段階2:高確度だけブロックに昇格

ベースラインが片付き、ノイズの傾向が掴めたら、continue-on-error を外してブロックを有効化します。

# 段階2:confirmed(HIGH かつ動的再現済み)だけがビルドを止める
- uses: tomodahinata/aegis@main
  with:
    severity: HIGH
  # continue-on-error を外す → HIGH 検出でジョブが失敗=マージ不可になる

- uses: github/codeql-action/upload-sarif@v3
  if: always()
  with:
    sarif_file: aegis.sarif

仕上げに、GitHubのブランチ保護ルールSecurity チェックを「マージ必須」に指定します。これで「赤いPRは構造的にマージできない」状態が完成します。警告から始め、確証だけをブロックに昇格させる——この順序が、迂回されないゲートを作る唯一の現実的な道です。


8. 鍵レス運用(OIDC)——CIに長期シークレットを置かない

CIセキュリティを語るうえで、CI自身のシークレット管理に触れないわけにはいきません。ゲートを守るワークフローが、鍵の漏洩経路になっては本末転倒です。

ここまでのAegis Actionの例は、外部サービスへの認証を必要としません(コードを読んでSARIFを出すだけ)。security-events: writeGITHUB_TOKEN の自動権限で賄われ、長期シークレットは不要です。これ自体が良い設計です。

一方で、CIから外部(クラウドやコンテナレジストリ等)にアクセスする必要が出たときは、長期のアクセスキーをリポジトリのSecretsに置かないのが鉄則です。代わりに OIDC(OpenID Connect) を使い、ジョブ実行時にだけ有効な短命のトークンを発行して認証します。

# OIDC で短命トークンを取得する例(クラウド連携が必要な場合)
permissions:
  contents: read
  id-token: write   # ← OIDC トークンの発行に必要。長期キーは Secrets に置かない

id-token: write は、ワークフローが自身のIDを証明する短命トークンを取得する権限です。これをクラウド側の信頼設定(特定リポジトリ・特定ブランチからのみ受け付ける)と組み合わせると、漏れて困る長期鍵がそもそも存在しない状態になります。これも最小権限・最小有効期間の徹底です。

環境変数とシークレットの境界設計そのもの——どこまでをコードに出し、何を秘匿し、いつ起動時検証するか——は、本記事の主題から外れるため別途まとめています(Next.js × Supabase アプリケーションセキュリティ完全ガイドの「型付きenv境界」を参照)。


9. RLS/認可の回帰もCIで——SQL検証を相関に足す

注入クラスの検出(SAST)と動的プローブ(DAST)に加えて、SupabaseのRLS/認可の設計そのものもCIで検証できます。これは「相関」の第3の軸です。

Aegisのスキャンは supabase/migrations/**.sql を読み、RLS無効のテーブル、using (true) の無条件許可、WITH CHECK 欠落、search_path 未固定の SECURITY DEFINER 関数、anonロールへの過剰GRANTといった構造的な弱点を検出し、これもSARIFに含めます。RLSの設定ミスの体系的な検出観点はRLS設定ミスの検出と監査に詳しくまとめています。

さらに退行を防ぐなら、pgTAPでRLSの回帰テストを書き、CIで「他人の行が見えないこと」を継続的に証明します。これはSARIFとは別系統(テストの赤/緑)ですが、同じCIパイプラインで束ねる価値があります。

-- pgTAP:別ユーザーのJWTで他人の行が見えないことを回帰テストにする
begin;
select plan(1);
set local role authenticated;
set local request.jwt.claims to '{"sub":"user-b-uuid"}';
select is_empty(
  $$ select * from invoices where user_id = 'user-a-uuid' $$,
  'user B cannot read user A invoices'
);
select * from finish();
rollback;

こうして**SAST(コード)・SQL検証(RLS設計)・DAST(実行時再現)・pgTAP(回帰)**の4つを同じCIで回し、確証が取れたものだけをブロックに昇格させる——これがCIセキュリティの完成形です。注入や認可がOWASPのOWASP Top 10で繰り返し上位に並ぶのは、これらが最も普通に混入するからこそ。だからこそ「人が気をつける」ではなく「CIが番をする」価値があります。


10. 正直なスコープ——CIゲートは監査の"代わり"ではない

ここは本記事で最も強調したい点です。CIゲートは、設計レビューや手動監査を置き換えません。

CIに常設できるのは、本質的に**「機械的に判定できるパターン」です——汚染入力が危険シンクに届いているか、RLSが無効になっていないか、所有権チェックが構文的に抜けていないか。これらは価値ある検査ですが、見ているのはあくまでコードとSQLの"形"**です。

一方、「この認可ロジックは事業ルールとして正しいか」「このテナント帰属の根拠(app_metadatauser_metadata か)は妥当か」「この状態遷移はありえない順序を許していないか」——こうした判断は、あなたのデータモデルと事業の意味を理解した人間にしか下せません。CIゲートがどれだけ緑でも、それは「よくある罠は踏んでいない」を意味するだけで、「認可が正しい」を意味しません。

いかなるツールも、認可の"正しさ"は証明しない。 データフロー解析は関数内(intraprocedural)が基本で、モジュールやフレームワークを跨ぐ流れは見逃します。動的プローブも「試した経路で再現しなかった」だけで「安全」ではありません。CIゲートは継続運用の"仕組み化"であり、人間のレビューと脅威モデリングを補完するもの——置き換えるものではありません。

この線引きを踏まえると、CIゲートの正しい役割が見えます。人間の貴重なレビュー時間を、機械が潰せる退屈な穴の指摘ではなく、本当に難しい設計判断に集中させること。ノイズを消し、確証だけを赤にするのは、まさにそのためです。

なお、ここで扱った「PRごとのスキャン」を超えて、継続的なCI認可チェック(チームのリポジトリに対する常時監視や、認可設計の継続的な検証)まで踏み込む領域は、提供準備中の上位プラン「Aegis Team」で扱う構想です。関心があれば先行登録(ウェイトリスト)から。現時点のOSS版(npx @aegiskit/cli scan)でも、本記事のCIゲートは今日から組めます。


11. CI導入チェックリスト

CIセキュリティゲートを「死なないゲート」として組むための最小確認項目です。

  • PRとpushの両方でスキャンが走る(on: [push, pull_request]
  • permissionscontents: read + security-events: write の最小権限
  • SARIFアップロードに if: always() を付け、赤でも指摘が必ず載る
  • 結果が コードスキャニングのSecurityタブPR差分の注釈に出ている
  • 段階1(warn)から開始し、ベースラインを片付けてから block に昇格
  • ブロックするのは confirmed(高確度・動的再現済み)だけ——ノイズは warning に留める
  • block 昇格後、ブランチ保護Security チェックをマージ必須に指定
  • CIから外部認証が要るなら OIDC(短命トークン)——長期キーをSecretsに置かない
  • Action参照は tomodahinata/aegis@main(必要ならコミットSHAでピン留め
  • RLSの退行を pgTAP回帰テストで同じCIに束ねている
  • CIが緑=安全ではないことをチームが理解している(設計レビューは別途)

発注者・チームリードの視点で最も効く問いは、**「セキュリティチェックはCIに入っていますか?」「赤が出たとき、それは"本当にヤバい"と信用されていますか?」**の2つです。後者に「いや、ノイズが多くて…」と返ってくるなら、ゲートは事実上死んでいます。


まとめ:仕組みで止め、確証だけを赤にする

要点を整理します。

  • セキュリティ検査はPRの時点でCIに入れて初めて意味を持つ。本番後に探すのではなく、マージ前に止める(シフトレフト)。価値の源泉は「人の規律」ではなく「構造での強制」。
  • SARIFは静的解析結果の標準フォーマット。これに統一すれば、GitHubコードスキャニングのSecurityタブと、PR差分の行単位注釈に結果が載り、ツールを乗り換えてもCI連携は不変。
  • GitHub Actionsでの実装は短い。permissions: security-events: write + contents: read の最小権限、if: always() でのSARIFアップロード、severity での閾値指定が骨格。Action参照は tomodahinata/aegis@main
  • CIゲートの最大の敵は誤検知。ノイズだらけのゲートは必ず迂回される。だから**「高確度のみブロック」——静的の疑いを動的プローブで再現できたもの(SAST×DAST相関)**だけを赤にする。
  • 導入はwarn から始め、確証だけを block に昇格。CIから外部認証が要るなら**OIDC(鍵レス)**で長期シークレットを排除。
  • 正直に言えば、CIゲートは設計レビュー・手動監査の代わりにはならない。ツールは認可の"正しさ"を証明しない。これは継続運用の"仕組み化"であり、人間の判断を補完するもの。

AIで速く作ること自体は正しい。速く作ったものを、漏らさず安全に固める仕組み——その第一歩として、まずはAegis(無料OSS、npx @aegiskit/cli scan)でCIゲートを組んでみてください。確証だけが赤になる体験を作れば、セキュリティは「気をつけるもの」から「構造で守られるもの」に変わります。

それでも、認可・RLSの設計そのものの正しさや、既存アプリの継続的な堅牢化が必要であれば、機械では塞げない領域です。私自身、サーバーレス決済プラットフォームでフルスタック開発と決済信頼性レイヤーを主導し、CI/CDと検証ゲートを実運用で設計してきました。どこまで自動化で固め、どこから人手のレビューが要るか——その線引きを含め、セキュリティ監査で承ります。


よくある質問(FAQ)

Q. まず何から始めればいいですか? A. 第4節のYAMLを .github/workflows/security.yml に置き、continue-on-error: true(段階1)で警告のみから始めてください。これでPRに指摘が出るようになります。ノイズの傾向が掴めたら continue-on-error を外し、ブランチ保護でマージ必須にします。

Q. SARIFは自分で書く必要がありますか? A. いいえ。SARIFはツールが自動生成します。あなたが書くのは upload-sarifsarif_file を渡すYAMLだけです。SARIFの構造を理解しておく価値はありますが、手書きはしません。

Q. なぜ全部の検出でブロックしないのですか? A. 第5節のとおり、誤検知でCIが頻繁に赤くなると、ゲートが信用されず必ず迂回されるからです。確証(高確度・動的再現済み)だけをブロックに限定し、残りは警告として可視化する——これがゲートを「生かす」唯一の現実的な設計です。

Q. CIが緑なら、もう安全ですか? A. いいえ。CIゲートが見ているのはコードとSQLの"形"であって、認可の"正しさ"ではありません。緑は「よくある罠は踏んでいない」を意味するだけです。事業ルールやテナント帰属の妥当性は、人間の設計レビューでしか判断できません。CIゲートは監査を補完するもので、置き換えるものではありません。

Q. 個人開発や小規模でもやるべきですか? A. むしろ小規模ほどコスパが高いです。YAMLは10数行、OSSなので費用ゼロ。continue-on-error で警告から始めれば、既存PRを止めずに導入できます。AIで素早く作ったアプリこそ、CIに番をさせる価値が大きいというのが実情です。


参考資料

友田

友田 陽大

Bakanlık (METI) Ödülü kazanan bir ürünün geliştiricisi. TypeScript + Python + AWS ile SaaS, endüstriyel dijital dönüşüm ve üretime hazır üretken yapay zekâyı (RAG) gereksinimlerden altyapıya ve işletmeye kadar tek başıma uçtan uca sunuyorum.

The measures in this article can be automated with a tool

Automate your Next.js / Supabase security controls with the OSS Aegis

Many of the measures here can be mechanically detected and hardened with a single middleware file and static analysis. With the free, MIT-licensed Aegis, you can scan your current project from one command. The vertical risks that need design, I also take on as an audit.

Hem proje bazlı işler hem de teknik danışmanlık için uygunum. 30 dakikalık ücretsiz bir görüşmeyle başlayın.

最短ルート:カレンダーから直接予約

相談内容が固まっている方は、フォーム送信よりその場で日程を確定する方がスムーズです。下記から空き時間をお選びください。

  • 30分のオンライン無料相談
  • Google Meet / Zoom / Microsoft Teams
  • NDA 商談前締結可・無理な営業はいたしません
無料相談の空き枠を予約する

Bunlar da ilginizi çekebilir