ci-sentinel について
7種類のCIシステムのワークフローファイルを分析し、侵害されたコンポーネントのホスト型脅威情報フィードも利用するセキュリティアナライザーです。MCPサーバーとHTTP APIで提供され、検出事項、修正案、コンプライアンス評価、SARIF結果を出力します。
主な機能
- 017種類のCIシステムのワークフローを分析
- 02インジェクションとサプライチェーンのリスクを追跡
- 03ライブ脅威フィードでコンポーネントを確認
- 04修正案と統一差分を生成
- 05評価とSARIFレポートを生成
活用シーン
- 01プルリクエスト実行前のCIワークフロー監査
- 02侵害済みまたは可変のCIコンポーネントの発見
- 03コードスキャン用のセキュリティ検出事項の準備
MCP 対応
MCPサーバーは、ワークフローファイル群または単一ソースを受け取る`audit_ci_security`ツールを公開します。無料枠では判定と問題種別ごとの件数を返し、詳細監査では検出事項と修正案を提供します。
設定
リモートサーバーはインストール不要です。クライアントを選んで設定をコピーするか、ワンクリックで導入できます。
https://ci-sentinel.vercel.app/mcpclaude mcp add --transport http ci-sentinel https://ci-sentinel.vercel.app/mcp{"mcpServers":{"ci-sentinel":{"type":"http","url":"https://ci-sentinel.vercel.app/mcp"}}}Cursor で開く{"servers":{"ci-sentinel":{"type":"http","url":"https://ci-sentinel.vercel.app/mcp"}}}VS Code で開く{"mcpServers":{"ci-sentinel":{"type":"http","url":"https://ci-sentinel.vercel.app/mcp"}}}{"mcpServers":{"ci-sentinel":{"serverUrl":"https://ci-sentinel.vercel.app/mcp"}}}コマンドはターミナルで実行し、JSON は各クライアントの MCP 設定に貼り付けて再起動します。認可が必要なサーバーは初回接続時にログインを求めます。
ツール
詳細
ci-sentinel 🛡️
7 つの CI エコシステム(GitHub Actions、GitLab CI/CD、 Jenkins、CircleCI、Azure Pipelines、Bitbucket Pipelines、Travis CI)に対応したセキュリティ監査ツールです。YAML リンターでは検出できないサプライチェーンやインジェクションの欠陥を、攻撃者のプル/マージリクエストがリポジトリのシークレットを使ってコードを実行する前に検出します。
MCP サーバー(Claude/Cursor/任意のエージェント向け)と、 従量課金制の HTTP API(x402 USDC またはプリペイドカードキー)として利用できます。
.github/workflows/*.yml、.gitlab-ci.yml、Jenkinsfile、
.circleci/config.yml、azure-pipelines.yml、bitbucket-pipelines.yml、および/または
.travis.yml を渡すと(各ファイルは適切なアナライザーに自動で振り分けられます)、具体的な欠陥とともに
CRITICAL / VULNERABLE / RISKY / HARDENED の判定が得られます。
リンターでは検出できない問題を検出
| クラス | ci-sentinel の機能 |
|---|---|
| 💉 式インジェクション(ステップ間/ジョブ間の汚染) | 信頼できない ${{ github.event.* }}(issue/PR のタイトル、本文、コメント、レビュー、ブランチ名、コミットメッセージ、ラベル名、フォークリポジトリの識別情報、編集元の値)から、run: シェル または actions/github-script シンクへの汚染を追跡します。また、steps.<id>.outputs.*、needs.<job>.outputs.*、env: 変数、matrix 値、再利用可能なワークフローの inputs.* を経由する場合も追跡します。攻撃者が中間出力の背後に信頼できない値を隠しても検出できます。ファイル単位の grep では検出できません。 |
| 🎭 Pwn requests | pull_request_target/workflow_run が、特権を持ちシークレットを含むコンテキストで 信頼できないフォークのコードをチェックアウトすると、シークレットを使った任意コード実行につながります。 |
| 🔑 トークンの権限 | 過剰な GITHUB_TOKEN スコープ(write-all、contents:write、id-token:write)、permissions: ブロックの欠如、信頼できないトリガーに公開されるシークレットを検出します。 |
| 🔁 再利用可能なワークフロー | workflow_call の呼び出し元が境界を越えて信頼できないデータを inputs.* として渡すケース、および secrets: inherit によって信頼できないトリガーで再利用可能なワークフローにすべてのシークレットが渡されるケースを検出します。 |
| 📌 アクションのピン留め | サードパーティ製アクション(および 再利用可能なワークフローの uses:)が、コミット SHA ではなく 変更可能なタグ/ブランチを使用しているケース(tj-actions/changed-files 型の乗っ取り)を、推移的なアクショングラフをたどって解決します。 |
| 🖥️ セルフホスト環境での RCE | 公開リポジトリの PR からアクセス可能なセルフホストランナー(自社インフラでの RCE)と、OIDC id-token の信頼設定の悪用を検出します。 |
…GitLab CI/CD(.gitlab-ci.yml)でも同じ深さで分析
| クラス | ci-sentinel の機能 |
|---|---|
| 💉 CI 変数インジェクション | 信頼できない GitLab 変数(CI_COMMIT_REF_NAME/BRANCH/TAG、CI_MERGE_REQUEST_TITLE/DESCRIPTION/SOURCE_BRANCH_NAME、コミットメッセージ/作成者、トリガーしたユーザーのフィールド)が script: に展開されるときの汚染を追跡します。variables: および extends: テンプレートを経由した汚染も追跡します。安全な変数(CI_COMMIT_SHA、CI_MERGE_REQUEST_IID、CI_PROJECT_ID、…)を認識するため、すべての $CI_ を検出対象にすることはありません。 |
| 🎭 フォークのマージリクエストを介した乗っ取り | フォークの MR パイプライン(merge_request_event、only: merge_requests)から到達でき、**シークレット/広範な CI_JOB_TOKEN 権限/id_tokens(OIDC)**を持つジョブ、または when: manual によるゲートなしで特権操作(デプロイ/公開/kubectl/terraform)を実行するジョブを検出します。 |
📦 include: によるサプライチェーンリスク | リモート URL、または変更可能な(SHA ではない)参照を使う別のプロジェクト/コンポーネントからの include: を検出します。これらは外部のパイプラインコードを自分のパイプラインに取り込みます。 |
| ☣️ アーティファクト/キャッシュ汚染 | 信頼できないジョブがアーティファクト/キャッシュを書き込み、特権を持つ下流ジョブがそれを取り込んで実行するケース(needs:/dependencies: または共有キャッシュパス)を検出します。ジョブ間およびパイプライン間の権限昇格につながります。 |
…さらに5つの CI システムにも、同じ汚染モデルを適用
| エコシステム | ci-sentinel が検出するもの |
|---|---|
🔧 Jenkins(Jenkinsfile) | params.*/env.CHANGE_*/ghprb*/SCM データから sh/bat/powershell へのコマンドインジェクション(environment{} バインディング経由);認証情報の漏えい(credentials()/withCredentials の値が出力されたり、GString に埋め込まれたりするケース);Groovy の evaluate()/load による RCE;input() 承認ゲートの欠如;安全でない agent any。 |
⭕ CircleCI(.circleci/config.yml) | << pipeline.git.branch/tag >>/パイプラインパラメーターから run: へのシェルインジェクション;ピン留めされていない orbs(@volatile/メジャーバージョンのみ);type: approval ゲートがない場合のフォーク PR による コンテキストシークレットの露出;承認のない特権デプロイ。 |
🟦 Azure Pipelines(azure-pipelines.yml) | $(Build.SourceBranch)/$(System.PullRequest.SourceBranch)/コミットメッセージから script:/bash:/pwsh: へのマクロインジェクション;外部リポジトリリソースからの信頼できない テンプレート;フォークによる 変数グループのシークレット露出;ピン留めされていないリポジトリリソース。 |
🪣 Bitbucket Pipelines(bitbucket-pipelines.yml) | $BITBUCKET_BRANCH/$BITBUCKET_TAG/$BITBUCKET_PR_DESTINATION_BRANCH/コミットメッセージが引用符なしで展開されることによる script: へのシェルインジェクション;外部からトリガー可能な PR パイプラインでの セキュア変数/デプロイ変数の露出;ピン留めされていない pipes(:latest);trigger: manual ゲートのないデプロイ。 |
🚦 Travis CI(.travis.yml) | $TRAVIS_BRANCH/$TRAVIS_PULL_REQUEST_BRANCH/$TRAVIS_COMMIT_MESSAGE が引用符なしでライフサイクルフックに展開されることによるシェルインジェクション;PR/フォークでの secure-env シークレット露出;on: ブランチ/条件ゲートのない deploy: ステージ。 |
…さらに、ワンショットエージェントでは再現できない、ドメイン横断型の高度な検出器が2つ
| 検出器 | ci-sentinel が検出するもの |
|---|---|
| ☁️ OIDC クラウド信頼設定の誤り(Terraform/CloudFormation/GCP ワークロード ID/Azure フェデレーション資格情報) | CI の OIDC における クラウド側、すなわち IAM ロール/WIF プール/フェデレーションアプリの信頼ポリシーをモデル化します。広範なワイルドカードを含む sub 条件(repo:org/*、repo:*)、sub 条件自体がない状態(発行者のあらゆるワークフローからロールを引き受け可能)、リポジトリはピン留めされているものの ref/環境がピン留めされていない状態(あらゆるブランチから引き受け可能)、ベアな pull_request サブジェクト(フォークから到達可能)、またはピン留めされていない aud にフラグを付けます。さらに、IaC の信頼設定と CI 側(信頼できないトリガーから到達可能な id-token を発行するワークフロー)を相関分析し、エンドツーエンドで連鎖に到達可能な場合は重大に引き上げます。単一ファイルのリンターでは検出できません。CI のクレームとクラウドの信頼ポリシーにまたがるためです。 |
🔧 Jenkins 共有ライブラリ(@Library → vars/*.groovy) | 信頼できないパイプライン値(PR タイトル/ブランチ/ビルドパラメーター)が共有ライブラリのグローバル変数ステップに渡され、ライブラリの call() の内部を通って内部の sh/bat シンクに到達する汚染を追跡します。orb/テンプレート/複合アクションのファイル横断型汚染解析に相当する Jenkins 版であり、Jenkinsfile だけを読んでも見えません。また、変更可能な ref(ブランチ/デフォルトバージョン)を指定した @Library インポートにも、サプライチェーンリスクとしてフラグを付けます。 |
各アナライザーは、安全な変数(SHA、数値 ID、信頼できるスラッグ —
BITBUCKET_COMMIT、TRAVIS_PULL_REQUEST、pipeline.git.revision、…)と、
安全な OIDC 信頼設定(sub が repo:org/repo:ref:refs/heads/main/
:environment:prod にピン留めされ、aud も設定済みのもの)を認識するため、
すべての $VAR や信頼設定にフラグを付けることはありません。
堅牢化された設定では誤検知ゼロです。
これは本格的な静的アナライザーです。行を認識するワークフロー YAML パーサー →
トリガー/ジョブ/ステップ/権限/アクション/出力/依存関係のモデル →
ステップ間/ジョブ間の汚染解決器+権限+サプライチェーン検出器 →
検出結果ごとの ファイル名:行番号、完全な汚染経路、具体的な修正方法、
および GitHub コードスキャンにアップロードできる SARIF 2.1.0 レポート(codeFlows を含む)
を備えた、スコア付き判定を行います。
…フラグを立てるだけでなく、修正し、評価します
| プレミアム機能 | 内容 |
|---|---|
| 🔧 自動修正(具体的な修正内容) | ci-sentinel は検出事項ごとに、具体的な変更内容を提示します。修正済みの YAML/Groovy スニペットと、適用可能な unified diff が含まれます。アクション/orb/pipe を変更不可能な SHA/バージョンに固定する、注入される式を環境変数にバインドして引用符で囲む、write-all を最小権限に変更する、手動承認ゲートを挿入する、OIDC の sub/aud を固定する、ハードコードされたシークレットをストアに移してローテーションする、といった修正を行います。「バグがあります」ではなく、**「これを、これに変更してください」**と提示します。また、信頼度ラベル(exact/template/guided)により、そのまま適用できる修正か、値の入力が必要な修正かが分かります。検出事項には重複排除用の安定した fingerprint が付き、SARIF の結果にはインラインの fixes が含まれます。 |
| 📋 コンプライアンス・スコアカード(A~F) | CIS に準じた CI セキュリティベンチマークを A~F で採点し、各コントロール(最小権限、コンポーネントの固定、フォークへのシークレット非公開、公開 PR でのセルフホストランナー不使用、OIDC の固定、ハードコードされたシークレットの不使用、pwn checkout の不使用、デプロイのゲート化、インジェクションの防止、ジョブ間汚染の防止)について PASS/FAIL/WARN/N/A の内訳を表示します。各コントロールには判定の根拠となった検出事項の IDが記載されるため、セキュリティチームに説明できます。直接悪用可能な重大な欠陥がある場合、評価の上限が制限されます(未解決の RCE/シークレット流出経路が 1 つあるだけで、セキュリティ態勢全体に大きく影響します)。 |
| 🛰️ ライブ脅威インテリジェンスフィード(データの優位性) | 設定内のすべての uses:/orb/pipe を、既知の侵害済み CI コンポーネントを掲載したライブのサーバー側フィードと照合します。このフィードは、公開ソースである OSV.dev と GitHub Security Advisory データベース(ecosystem=actions)から cron で取り込み、代表的なインシデント(tj-actions/changed-files CVE-2025-30066、reviewdog/action-setup CVE-2025-30154 とその推移的依存関係、aquasecurity/trivy-action のタグ強制プッシュ、Ultralytics)をまとめた厳選シードに統合します。tj-actions/changed-files@v45 が有害である一方、同じアクションでもクリーンなコミットに SHA 固定するか @v46 にアップグレードすれば安全だと判別します。フィードを持たない静的 YAML スキャンやローカルリンターには、こうした区別はできません。フィードはホストサーバー上にのみ保存され(シンクライアントには含まれません)、鮮度は GET /feed/status で確認できます。さらに、ライブのレピュテーションシグナル(スター数/最終コミット/アーカイブ済みか/リポジトリが現在も解決可能か)により、アーカイブ済み/放棄されたコンポーネントや、乗っ取りを狙った参照切れにもフラグを立てます。これがホスト型の有料モデルを正当化するアクセス優位性です。価値は計算処理ではなく、ライブのデータにあります。 |
| 🪤 タグ書き換えと偽装の検知(ライブの参照先→コミット) | 可変の参照先について、期待していたコミット SHA(ロックファイル/SBOM から取得)を ci-sentinel に渡すと、上流でタグが現在指している先を解決します。そして、タグの書き換え/強制プッシュ(@v2 が、レビューしたものとは異なるコミットを現在実行している状態。tj-actions 攻撃そのものです)、削除済み/参照切れの参照先、または不自然なほど最近の変更にフラグを立てます。また、タイポスクワッティングの検知とライブのレピュテーションシグナルを組み合わせ、なりすましを確認します。たとえば actons/checkout は actions に酷似していますが、作成されたばかりでスター数が少ない、または参照切れの偽装リポジトリです。一方、正当な名前の小規模フォークは誤検知しません。さらに、フィードはコンポーネントの識別情報をキーとしているため、侵害されたアクションは、どの CI システムから参照されていても(CI をまたいで)検知されます。これは、単一の CI しか対象にしないスキャナーでは構造上実現できません。 |
MCP サーバー(無料)
{
"mcpServers": {
"ci-sentinel": { "command": "npx", "args": ["-y", "ci-sentinel-mcp"] }
}
}
ツール:audit_ci_security。files(ワークフローファイル名 → YAML のマップ)または
source(単一のワークフロー)を渡します。無料プランでは、判定と、各種の問題が
何件見つかったかが返されます。
ディープ監査(deep: true)— 2 種類の支払い方法
ディープ監査では、すべての検出事項とファイル名・行番号、ステップ間/ジョブ間のインジェクションをたどる完全な汚染経路、推移的なアクションのサプライチェーングラフ、検出事項ごとの具体的な修正(修正済みスニペット+統合差分)、コントロールごとの内訳を含む A~F のコンプライアンススコアカード、インラインの fixes を含む SARIF 2.1.0 ドキュメントが返されます(github/codeql-action/upload-sarif を介して GitHub コードスキャンにアップロードできます)。
- 💳 カード(Stripe) —
https://ci-sentinel.vercel.app/pro/checkoutでプリペイドキーを購入し、MCP 設定に"env": { "CI_SENTINEL_KEY": "<key>" }を設定します。 - 🪙 x402(USDC) — AI エージェントが呼び出しごとに自動で支払います(Base 上の USDC)。登録は不要です。
HTTP API
POST /audit # free, rate-limited — verdict + per-severity counts
POST /pro/audit # deep — pay-per-call (x402) or Authorization: Bearer <key>
POST /mcp # MCP-over-HTTP (free)
GET /presence # live active sessions (last 5 min)
GET / # this landing page
curl -X POST https://ci-sentinel.vercel.app/audit \
-H 'Content-Type: application/json' \
-d '{"files":{".github/workflows/ci.yml":"name: CI\non: pull_request_target\n..."}}'
ホスト型である理由(優位性)
npm パッケージは薄いクライアントです。ローカルでは分析を実行しません。パーサー、汚染エンジン、アクショングラフリゾルバー、検出器のナレッジベースはペイウォールの内側でサーバー側のみで実行されます。そのため、プレミアムコンテンツ(検出結果、証拠、汚染経路、修正案)が呼び出し元のマシンに保存されることはありません。npm pack に含まれるのは dist/mcp.js、dist/mcpServer.js、dist/types.js のみです。エンジンは tarball に含まれません(npm run test:moat により自動的に検証されます)。
ライブフィードを最新に保つ方法(更新パイプライン)
脅威インテリジェンスフィードはハードコードされず、取り込まれます。定期ジョブがサーバー側で実行されます。
- 取得 — 有料キーなしで、2 つの公開ソースからアドバイザリを取得します。
- GitHub Security Advisory DB —
GET /advisories?ecosystem=actions(公開されています。GITHUB_TOKENを指定するとレート制限が緩和されますが、必須ではありません)。 - OSV.dev —
GitHub Actionsエコシステムを対象に、すでに追跡しているコンポーネントと GHSA が新たに明らかにしたすべての項目を照会します(OSV がそれらを補完します)。
- GitHub Security Advisory DB —
- 正規化 — 各アドバイザリを
ThreatRecordに変換します。owner/name を分割し、アドバイザリのテキストからインシデントの分類(タグの書き換え/メンテナーの侵害/悪意あるもの/CVE…)を推定し、重大度を分類し、影響を受けるバージョン範囲を解析してセレクターに変換し、修正バージョンを取得します(これにより、ピンをアップグレードしていれば検出されません)。 - マージ — 行を厳選されたシードにマージします(
ingestFeed:参照を統合し、最悪の重大度を維持し、影響範囲を広げ、ID で重複を排除します)。 - 保存 — スナップショットを Cloudflare KV に保存します。すべての
/pro/auditはkvFeedProviderを介して読み込み、KV が未初期化の場合はコンパイル済みのシードにフォールバックします。そのため、検出器がブロックされることはなく、静的なベースラインより悪化することもありません。
# run the refresh once (live: hits the real public APIs)
node scripts/refreshFeed.mjs
# dry run with no network (produces the seed-only snapshot)
CI_SENTINEL_NO_NET=1 node scripts/refreshFeed.mjs
Vercel Cron({ "path": "/internal/refresh-feed", "schedule": "0 */6 * * *" }。FEED_REFRESH_TOKEN で保護)または node scripts/refreshFeed.mjs を実行するスケジュール済み GitHub Action でスケジュールしてください。GET /feed/status はライブスナップショットのバージョン、generatedAt、レコード数を返します。これが公開される鮮度の証明です。これらは npm クライアントには一切含まれません。
開発
npm install
npm run build # tsc
npm test # engine + parser + taint + SARIF + autofix + compliance + corpus tests (851 checks)
npm run test:moat # lock-proof: tarball ships no engine, deep degrades w/o pay
npm run dev:http # local HTTP server (FORCE_LISTEN)
提供されたワークフロー YAML に対するヒューリスティックな静的分析です。リポジトリレベルのデフォルトのトークン権限、ブランチ保護、組織ポリシーは確認できず、パイプラインも実行しません。検出結果は、検証が必要な手がかりとして扱ってください。
ソースとドキュメント:https://github.com/Baneado98/ci-sentinel · MIT
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。