mcpField
C
ci-sentinel

ci-sentinel

远程服务
ci-sentinel.vercel.app开发工具018 周前更新

关于 ci-sentinel

面向七种 CI 系统工作流文件的安全分析器,并提供已遭入侵组件的托管威胁情报源。它可通过 MCP 服务或 HTTP API 使用,并能输出问题、修复建议、合规等级和 SARIF 结果。

主要功能

  1. 01分析七种 CI 系统的工作流
  2. 02追踪注入与供应链风险
  3. 03通过实时威胁源检查组件
  4. 04生成修复内容和统一差异
  5. 05生成等级评估与 SARIF 报告

适用场景

  1. 01在拉取请求运行代码前审计 CI 工作流
  2. 02查找遭入侵或可变更的 CI 组件
  3. 03为代码扫描整理安全问题

MCP 相关

MCP 服务提供 `audit_ci_security` 工具,可接收工作流文件集合或单个源文件。免费层返回判定结果和各类问题数量;深度审计提供详细发现与修复建议。

配置

远程服务无需本地安装。选择你使用的客户端,复制配置或使用一键安装。

服务地址https://ci-sentinel.vercel.app/mcp
一键复制安装命令
Claude CodeTerminal
Cursor.cursor/mcp.json
VS Code.vscode/mcp.json
Claude Desktopclaude_desktop_config.json
Windsurf~/.codeium/windsurf/mcp_config.json

命令在终端中运行;JSON 粘贴到对应客户端的 MCP 配置后重启。需要授权的服务会在首次连接时提示登录。

工具

详细介绍

ci-sentinel 🛡️

面向七种 CI 生态的安全审计工具——GitHub Actions、GitLab CI/CD、 Jenkins、CircleCI、Azure Pipelines、Bitbucket Pipelines 和 Travis CI——可发现 YAML 检查器无法识别的供应链漏洞和注入缺陷,避免攻击者的拉取请求/合并请求在运行代码时访问仓库机密。

可作为 MCP 服务(供 Claude / Cursor / 任意 Agent 使用),也可作为 按次付费的 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.* }}(议题/PR 标题、正文、评论、审查、分支名称、提交消息、标签名称、派生仓库身份、编辑前的值)标记为污点,并追踪到 run: shell 或 actions/github-script 接收点——还会沿着 steps.<id>.outputs.*、needs.<job>.outputs.*、env: 变量、matrix 值和可复用工作流的 inputs.* 追踪。即使攻击者把不可信值藏在中间输出中,也能被发现;逐文件 grep 做不到这一点。
🎭 利用拉取请求在具有特权且包含机密的上下文中,通过 pull_request_target / workflow_run 检出不可信的派生仓库代码,会导致攻击者利用机密执行任意代码。
🔑 令牌权限权限过大的 GITHUB_TOKEN 范围(write-all、contents:write、id-token:write)、缺少 permissions: 块,以及机密暴露给不可信触发事件。
🔁 可复用工作流workflow_call 调用方通过 inputs.* 将不可信数据传过边界,以及在不可信触发事件中通过 secrets: inherit 将全部机密交给可复用工作流。
📌 固定 Action 版本第三方 Action(以及可复用工作流的 uses:)使用可变标签/分支而非提交 SHA(如 tj-actions/changed-files 式劫持),并会追踪传递依赖 Action 图。
🖥️ 自托管运行器上的 RCE可从公开仓库 PR 访问的自托管运行器(攻击者可在你的基础设施上执行 RCE),以及滥用 OIDC id-token 信任。
……并以同样的深度分析 GitLab CI/CD(.gitlab-ci.yml)
类别ci-sentinel 的功能
💉 CI 变量注入将插入 script: 的不可信 GitLab 变量(CI_COMMIT_REF_NAME/BRANCH/TAG、CI_MERGE_REQUEST_TITLE/DESCRIPTION/SOURCE_BRANCH_NAME、提交消息/作者、触发用户字段)标记为污点——沿着 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: 或共享缓存路径)——可导致跨作业甚至跨流水线权限升级。
……以及另外五种 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 >> / 流水线参数的 Shell 注入,流入 run:;未固定版本的 orbs(@volatile / 仅指定主版本号);Fork PR context secret 暴露,且没有 type: approval 关卡;特权部署缺少审批。
🟦 Azure Pipelines(azure-pipelines.yml)来自 $(Build.SourceBranch) / $(System.PullRequest.SourceBranch) / 提交消息的宏注入,流入 script:/bash:/pwsh:;来自外部仓库资源的不可信 templates;Fork variable-group 密钥暴露;未固定版本的仓库资源。
🪣 Bitbucket Pipelines(bitbucket-pipelines.yml)来自 $BITBUCKET_BRANCH / $BITBUCKET_TAG / $BITBUCKET_PR_DESTINATION_BRANCH / 提交消息的 Shell 注入,这些值未经引号保护便展开到 script: 中;可由外部触发的 PR 流水线中 secured/deployment-variable 暴露;未固定版本的 pipes(:latest);部署缺少 trigger: manual 关卡。
🚦 Travis CI(.travis.yml)来自 $TRAVIS_BRANCH / $TRAVIS_PULL_REQUEST_BRANCH / $TRAVIS_COMMIT_MESSAGE 的 Shell 注入,这些值未经引号保护便展开到生命周期钩子中;secure-env PR/Fork 密钥暴露;deploy: 阶段缺少 on: 分支/条件关卡。
……另外还有两个单次运行的 Agent 无法复现的深度跨域检测器
检测器ci-sentinel 可检测的问题
☁️ OIDC 云信任配置错误(Terraform / CloudFormation / GCP workload-identity / Azure federated-credential)对 CI OIDC 的云端部分建模:IAM 角色 / WIF 池 / 联合应用的信任策略。检测带有宽泛通配符(repo:org/*、repo:*)的 sub 条件、完全没有 sub 条件(该颁发者上的任何工作流都能假定该角色)、仓库已固定但 ref/environment 未固定(任何分支都能假定该角色)、裸 pull_request 主体(可由 Fork 触发),或未固定的 aud。随后将 IaC 信任与 CI 侧关联(可从不可信触发器触达并生成 id-token 的工作流),并在整条链路端到端可触达时提升为严重级别。没有任何单文件检查器能检测到这一问题——它横跨 CI 声明和云信任策略。
🔧 Jenkins 共享库(@Library → vars/*.groovy)跟踪传入共享库全局变量步骤的不可信流水线值(PR 标题 / 分支 / 构建参数),穿过库的 call() 内部,流向内部的 sh/bat 接收点——这是 Jenkins 中与跨文件污点分析(orb/template/composite-action)相对应的检测,仅查看 Jenkinsfile 时无法发现。还会将引用可变引用(分支 / 默认版本)的 @Library 导入标记为供应链风险。

每个分析器都了解哪些变量是安全的(SHA、数字 ID、可信 slug—— 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 片段以及可直接应用的统一差异——将 action/orb/pipe 固定到不可变的 SHA/版本,将注入的表达式绑定到环境变量并加引号,将全量写入权限降至最小权限,插入手动/审批关卡,固定 OIDC sub/aud,将硬编码密钥移至存储库(并轮换密钥)。不是只说“你有个漏洞”,而是明确指出**“把这个改成那个”**,并标注置信级别(exact / template / guided),让你知道哪些可以直接套用,哪些需要填写具体值。发现会带有稳定的 fingerprint,便于去重;SARIF 结果则包含内联 fixes。
📋 合规评分卡(A–F)采用类似 CIS 的 CI 安全基准,按 A–F 评分,并为每项控制措施提供 PASS / FAIL / WARN / N/A 明细(最小权限、组件固定、不向 fork 泄露密钥、公有 PR 不使用自托管运行器、固定 OIDC、不使用硬编码密钥、不使用 pwn checkout、部署设审批关卡、不存在注入、不存在跨作业投毒)。每项控制措施都会列出影响判定的发现 ID,便于向安全团队说明。可直接利用的严重漏洞会限制评分上限(一个未修复的 RCE/密钥外泄路径就足以主导整体安全态势)。
🛰️ 实时威胁情报源(数据护城河)配置中的每个 uses: / orb / pipe 都会与已知遭入侵 CI 组件的实时服务器端情报源进行比对。情报源通过定时任务从公开来源——OSV.dev 和 GitHub Security Advisory 数据库(ecosystem=actions)——摄取数据,并与精选的标志性事件种子库合并,其中包括 tj-actions/changed-files CVE-2025-30066、reviewdog/action-setup CVE-2025-30154 及其传递依赖项、aquasecurity/trivy-action 标签强制推送事件和 Ultralytics。它能识别 tj-actions/changed-files@v45 是恶意的,并知道同一 action 固定到干净提交的 SHA 或升级至 @v46 后是安全的——静态 YAML 扫描或本地 Linter 无法作出这种区分,因为它们没有情报源。情报源仅存于托管服务端(轻量客户端不会携带它);GET /feed/status 可显示其最新状态。实时信誉信号(星标数 / 最近提交时间 / 是否已归档 / 仓库是否仍可解析)还会标记已归档/已弃用的组件,以及可能成为接管目标的失效引用。**这就是支撑托管付费模式的准入护城河:**价值来自实时数据,而非计算能力。
🪤 标签重写与冒名检测(实时引用→提交)向 ci-sentinel 提供你预期可变引用指向的提交 SHA(来自锁定文件/SBOM),它就会解析该标签在上游当前指向的对象,并标记标签重写/强制推送(@v2 现在运行的提交与审核过的不同——这正是 tj-actions 攻击的手法)、已删除/失效的引用或近期出现的可疑变更。它还会结合实时信誉信号进行拼写仿冒检测,确认是否存在冒名行为——例如 actons/checkout(与 actions 近似但拼错),其仓库是刚创建、星标很少或已失效的冒名仓库——并将其与名称真实但规模较小的 fork 区分开来(不产生误报)。此外,由于情报源以组件身份为索引,无论哪个 CI 系统引用了受感染的 action,都能检测出来(跨 CI);这是单一 CI 扫描器在结构上无法具备的能力。

MCP 服务(免费)

{
  "mcpServers": {
    "ci-sentinel": { "command": "npx", "args": ["-y", "ci-sentinel-mcp"] }
  }
}

工具:audit_ci_security。传入 files(工作流文件名 → YAML 的映射)或 source(单个工作流)。免费版会返回判定结果,以及发现的各类问题 数量。

深度审计(deep: true)——两种付费方式

深度审计会返回每项发现及其文件和行号、完整的步骤间/作业间注入污染路径、传递式 Action 供应链图、每项发现对应的具体修复方案(修正后的代码片段 + 统一差异)、包含各项控制措施明细的 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 Agent 自动按次调用付费(使用 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 包是一个精简客户端:不会在本地运行任何分析。解析器、污点引擎、Action 图解析器和检测器知识库仅在服务端运行,置于付费墙之后——因此,付费内容(发现、证据、污点路径、修复建议)绝不会出现在调用方的机器上。npm pack 只会打包 dist/mcp.js、dist/mcpServer.js 和 dist/types.js;引擎不会进入 tarball(由 npm run test:moat 自动验证)。

实时动态的情报源如何保持更新(更新管道)

威胁情报源通过摄取更新,而非硬编码。服务端会运行一个定期任务:

  1. 获取来自两个公开来源的公告(无需付费密钥):
    • GitHub Security Advisory DB——GET /advisories?ecosystem=actions(公开;GITHUB_TOKEN 仅会提高速率限制,并非必需)。
    • OSV.dev——查询 GitHub Actions 生态系统中我们已跟踪的组件,以及 GHSA 刚刚披露的所有组件(由此让 OSV 补充相关信息)。
  2. 规范化每条公告并转换为 ThreatRecord——拆分所有者和名称、根据公告文本推断事件类别(标签重写/维护者遭入侵/恶意行为/CVE……)、划分严重性等级、将受影响版本范围解析为选择器,并记录修复版本(因此升级后的固定版本不会触发告警)。
  3. 合并记录并写入精选种子数据(ingestFeed:合并引用、保留最高严重性、扩大受影响范围,并按标识去重)。
  4. 存储快照到 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

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。