Metbcy/securescan

GitHub: Metbcy/securescan

一款自托管的多扫描器安全编排工具,通过 diff 感知在 PR 工作流中仅展示新增安全发现,消除遗留告警噪音并支持签名发布。

Stars: 0 | Forks: 0

# SecureScan [![Container](https://static.pigsec.cn/wp-content/uploads/repos/2026/05/0590efb61a133236.svg)](https://github.com/Metbcy/securescan/actions/workflows/container.yml) [![Security Audit](https://static.pigsec.cn/wp-content/uploads/repos/2026/05/1cf0e056f9133237.svg)](https://github.com/Metbcy/securescan/actions/workflows/securescan.yml) [![License: Apache 2.0](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](./LICENSE) ## 快速开始 (60 秒) ``` # 1. 安装 pip install securescan # 2. 初始化 securescan init # 3. 运行 securescan diff . --base-ref origin/main --head-ref HEAD ``` 这会为您提供一份仅包含 NEW(新增)发现的统一 PR 评论风格报告。有关完整的仪表板、容器和 CI 集成,请参见下文。 ## 仪表板 自托管仪表板位于每次扫描、发现、扫描器、SBOM 和 webhook 之前。下面的截图是实时本地部署扫描真实目标(`~/quantsense`,`~/securescan/backend`)的界面。 ### 概览 跨所有扫描的风险评分趋势、带有其首要发现的最新扫描摘要,以及一目了然的严重性总计。 ![概览](https://static.pigsec.cn/wp-content/uploads/repos/2026/05/8b6e039232133238.png) ### 实时扫描进度 每次扫描通过 SSE 流式传输其生命周期事件 —— 单个扫描器状态(已排队 / 运行中 / 已完成 / 已跳过 / 失败)、单个扫描器持续时间和发现计数,以及实际运行时间,所有这些都在一个随着扫描运行而更新的单一面板中显示。 ![实时扫描进度](https://static.pigsec.cn/wp-content/uploads/repos/2026/05/32ec3a4e23133239.png) ### 扫描详情 风险评分、严重性明细、运行的所有 11 个扫描器,以及带有严重性 + 分流状态过滤器的发现表。每个发现可展开以显示规则、文件、代码片段、修复建议和每个发现的评论线程。 ![带有发现的扫描详情](https://static.pigsec.cn/wp-content/uploads/repos/2026/05/4196cbfbef133240.png) ### 历史记录 可排序、可过滤的每次扫描列表,包含运行的扫描器、发现计数和风险评分。点击行可查看完整详情。 ![扫描历史记录](https://static.pigsec.cn/wp-content/uploads/repos/2026/05/462a3ffab7133241.png) ### 扫描器 所有 14 个受支持的扫描器,包含每个扫描器的可用性、版本以及适用于 pip 可安装版本的一键安装功能。“刷新状态”控制会重新检查主机并显示上次检查运行的时间。 ![扫描器清单](https://static.pigsec.cn/wp-content/uploads/repos/2026/05/d3f952df68133243.png) ## 为什么? PR 上最具可操作性的安全问题是*“这个 diff 中有哪些我应该担心的变化?”* —— 而不是*“我的仓库现在有什么?”*。 SecureScan 通过将 base ref 和 head ref 的发现分类为 NEW / FIXED / UNCHANGED 来回答第一个问题,然后仅将 NEW 发现(带有严重性计数)作为单个更新插入的 PR 评论发布。预先存在的遗留发现会被排除在外,直到您选择处理它们,因此该工具可以留在整个组织中使用,而不会使每个 PR 淹没在噪音中。 将其与确定性输出(排序后的发现、稳定的每个发现指纹、无实际运行时间戳)相结合,相同的评论可以在每次推送到 PR 分支时通过评论标记进行更新插入,SARIF 可以干净地重新上传到 GitHub 的 Security 选项卡而不会产生虚假的新警报噪音,并且渲染器对于相同输入是字节一致的。 ## 文档 完整文档:**https://metbcy.github.io/securescan/** - [快速开始](https://metbcy.github.io/securescan/quick-start.html) - [API 参考](https://metbcy.github.io/securescan/api/overview.html) - [生产环境清单](https://metbcy.github.io/securescan/deployment/production-checklist.html) ## 安装 有三种受支持的安装途径。请选择与您想运行 SecureScan 的方式相匹配的一种。 ### GitHub Action(推荐用于 CI) 复合 action 包装了 `securescan diff`,发布更新插入的 PR 评论,并将 SARIF 上传到 Security 选项卡。它首先尝试 wheel 包,当扫描器二进制文件不在 `PATH` 上时,回退到固定的容器镜像。 ``` # .github/workflows/securescan.yml on: pull_request permissions: contents: read pull-requests: write # required for the upserted PR comment security-events: write # required for SARIF upload to the Security tab jobs: securescan: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: fetch-depth: 0 # diff needs both base and head commits - uses: Metbcy/securescan@v1 # floating major; pin to @v0.11.0 for fully-deterministic CI with: scan-types: code,dependency fail-on-severity: high ``` 该 action 的完整输入/输出参考位于 [`action/README.md`](./action/README.md)。 ### Action 版本控制 - `Metbcy/securescan@v1` —— 浮动的主要版本。在 v1.x 内自动更新。推荐大多数用户使用。 - `Metbcy/securescan@v0.11.0` —— 精确固定。当您需要完全确定性的 CI 时使用。 - **未**发布 `:latest`;请固定到一个标签。 ### 从 PyPI 安装 Wheel 包 ``` pip install securescan # latest pip install securescan==0.11.0 # exact pin pip install 'securescan[pdf]' # with PDF reports (pulls WeasyPrint) ``` 该 wheel 包仅发布 SecureScan 本身。底层的扫描器 CLI(`semgrep`、`bandit`、`safety`、`pip-licenses`、`checkov`、`trivy`、`npm`、`nmap`、ZAP 等)需要单独安装,并且在 `PATH` 上可供包装它们的扫描器运行。使用 `securescan status` 查看检测到了什么。如果您不想自己管理扫描器安装,请使用容器。 ### 容器 (`ghcr.io/metbcy/securescan`) 该镜像支持多架构 (amd64 + arm64),预装了所有 14 个固定版本的扫描器,并且是当 wheel 模式先决条件未满足时 GitHub Action 回退的方案。 ``` docker run --rm -v "$PWD:/work" -w /work \ ghcr.io/metbcy/securescan:v0.11.0 \ diff . --base-ref origin/main --head-ref HEAD \ --output github-pr-comment ``` ## 使用方法 ``` # Diff 本地 PR (refs 必须存在于本地 clone 中) securescan diff . --base-ref main --head-ref HEAD # CI snapshot path (跳过 git checkouts;使用两个预扫描的 JSON) securescan diff . \ --base-snapshot before.json \ --head-snapshot after.json \ --output github-pr-comment # 完整一次性扫描 (legacy v0.1.0 模式 — 仍受支持) securescan scan ./your-project \ --type code --type dependency \ --output sarif --output-file results.sarif # 刷新用于抑制 legacy 发现的 baseline JSON securescan scan . --output json --output-file baseline.json ``` `securescan diff` 接受 ref 模式 (`--base-ref` / `--head-ref`) **或** 快照模式 (`--base-snapshot` / `--head-snapshot`),但不能同时使用两者。快照模式是推荐的 CI 路径:每一侧独立运行 `securescan scan ... --output json`,然后单个分类步骤执行 diff 而无需重新检出代码树。 在 CI 中,当设置 `CI=true` 环境变量时,AI 增强会自动禁用;传递 `--ai` 可强制开启,或传递 `--no-ai` 以明确禁用。 ## 配置 SecureScan 从项目根目录读取 `.securescan.yml`(它会从 `securescan diff` 的目标目录向上查找,直到找到该文件或到达 `.git/` 边界)。配置完全是可选的;没有它,将保留 v0.2.0 的行为。 ``` # .securescan.yml — 完整 schema 参考。每个键都是可选的。 # 当 CLI 上未传递 --type 时的默认扫描类型。 scan_types: - code - dependency # 按规则严重性覆盖。键为 scanner 规则 ID,正如它们出现在 # JSON 输出中的 `rule_id` 一样。当规则对您的 codebase 触发过高或 # 过低时很有用。原始严重性保留在 # `metadata.original_severity` 中,因此 audit trail 保持完整。 severity_overrides: python.lang.security.audit.dangerous-system-call: medium python.lang.security.audit.eval-detected: low # 全局忽略的规则。具有这些 rule_ids 的发现在 # CI 输出 (PR 评论, SARIF) 中被过滤掉,但在本地使用 # --show-suppressed 仍可见。 ignored_rules: - python.lang.security.audit.dynamic-django-attribute - B106 # bandit: hardcoded password (we use a vault) # 自定义 Semgrep 规则包。路径相对于此 config 文件的 # 目录。当非空时,替换 `semgrep --config auto`。 semgrep_rules: - .securescan/rules/secrets.yml - .securescan/rules/unsafe-deserialization.yml # 默认的 fail-on-severity 阈值 (由 CLI --fail-on-severity 覆盖)。 fail_on_severity: high # AI enrichment。true 强制开启,false 强制关闭;省略让 CLI / CI # 默认决定 (CI 中关闭,本地开启)。 ai: false ``` 使用 `securescan config validate` 验证文件,以便在扫描时造成问题之前捕获拼写错误和缺失的规则包路径。 ## 抑制发现 当一个发现对您的代码库不适用时 —— 已知的误报、故意使用的被标记模式、或您已接受的问题 —— 有三种方法可以抑制它。优先级为 **内联 > 配置 > 基线**。 ### 1. 内联忽略注释(最接近代码) 在触发发现的行或其上方一行添加注释: ``` data = eval(payload) # securescan: ignore python.lang.security.audit.eval-detected # securescan: ignore-next-line python.lang.security.audit.eval-detected result = eval(other_payload) ``` 可识别的注释风格:`#`、`//`、`--`。多个规则 ID 以逗号分隔。`*` 是通配符。 ### 2. 配置驱动的 `ignored_rules`(仓库范围) `.securescan.yml`: ``` ignored_rules: - python.lang.security.audit.eval-detected ``` ### 3. 基线(遗留发现) 当您在现有代码库上采用 SecureScan 时,运行一次 `securescan baseline` 以将当前存在的所有问题设为检查点。随后的扫描传递 `--baseline .securescan/baseline.json`(或在 CI 中设置路径);只有 NEW 发现会出现在 PR 评论中。 ``` securescan baseline > /dev/null # writes to .securescan/baseline.json securescan diff . --base-ref main --head-ref HEAD --baseline .securescan/baseline.json ``` 每当发现被修复时刷新基线(以便它们在 `securescan compare` 中显示为偏移): ``` securescan baseline # overwrites .securescan/baseline.json securescan compare .securescan/baseline.json # what disappeared since the last baseline? ``` ### 审计:什么被抑制了? 默认情况下,被抑制的发现会从 CI 输出中隐藏。在本地,TTY 上的 `securescan diff`(以及 `scan` 和 `compare`)会以 `[SUPPRESSED:]` 前缀显示它们,以便您可以在审查期间看到隐藏的内容。使用 `--show-suppressed` 强制在任何地方可见。使用 `--no-suppress` 完全禁用抑制(紧急停止开关)。 ## 内联 PR 审查评论 当在 `Metbcy/securescan@v1` action 上设置 `pr-mode: inline` 时,SecureScan 会将发现作为单一的 GitHub Review 发布,并带有锚定在每个受影响行上的内联评论 —— 而不是 PR 线程中的单个摘要评论。 审查者可以单独解决每个发现;回复保留了跨重新运行的线程,因为每条评论都由一个稳定的每个发现的指纹作为键。 ``` # .github/workflows/security.yml - uses: Metbcy/securescan@v1 with: pr-mode: inline # was: summary (default; backward-compatible) review-event: COMMENT # COMMENT | REQUEST_CHANGES | APPROVE inline-suggestions: true # one-click `# securescan: ignore RULE` suggestion ``` ### 工作原理 1. **Diff 解析**:SecureScan 读取 `git diff ..` 以计算每个发现的 *position* —— GitHub 的偏移到 PR diff 中的坐标,而不是源代码行号。 2. **diff 之外的发现回退到 review 正文**,因此它们不会静默丢失。 3. **建议块**(当 `inline-suggestions: true` 时): - 对于审查者可以抑制的发现,SecureScan 提供一键式 `\`\`\`suggestion` 块,在行上方添加 `# securescan: ignore `。 - 对于严重性不适合此代码库的发现,SecureScan 显示一个可复制粘贴的 `severity_overrides:` 片段用于 `.securescan.yml`。 4. **幂等的重新运行**:每条评论都带有一个隐藏的 `` 标记。在重新运行时,SecureScan 会 PATCH 现有评论而不是发布重复评论 —— 审查者的回复线程得以保留。 5. **已解决的发现会被标记**,而不是删除:当一个发现在重新运行中消失时,其评论会被修补为 `**Resolved in ** — ...`,并将原始正文加上删除线。审查者手动解决的发现会得到尊重(我们不会自动解决线程)。 ### 本地开发 要检查将要发布的内容而不运行 CI: ``` securescan diff . --base-ref main --head-ref HEAD \ --output github-review --repo Metbcy/securescan \ --output-file review.json cat review.json | jq . ``` 该 CLI 需要 `--repo`、`--sha` 和 `--base-sha`(在 git 工作树中从 `--base-ref`/`--head-ref` 自动解析)。它本身不会发布到 GitHub —— 那是 Action 的工作。 ### 权限 ``` permissions: contents: read pull-requests: write # covers BOTH summary comment AND inline review submission security-events: write # for SARIF upload (unrelated; only if you also enable SARIF) ``` ### 与 `pr-mode: summary` 相比 | | summary (默认) | inline | both | |---|---|---|---| | 评论数量 | 1 (更新插入) | 1 个带有 N 条内联评论的 review | summary + inline | | 审查者可以按发现解决 | 否 | 是 | 是 (inline) | | 仅针对触及代码的发现 | 全部 | 仅限 PR diff 中的行 | summary 覆盖所有 | | 触及代码之外的发现 | 在评论中 | Review 正文回退 | 两种方式均覆盖 | | 建议块 | 否 | 是 (启用时) | 是 (仅限 inline) | `summary` 仍是 v0.2.0/v0.3.0 的默认值。`inline` 是选择启用的。`both` 适用于希望在对话选项卡上获得摘要并在文件更改选项卡上获得内联锚点的团队。 ## 生产部署 对于本地开发,仪表板在未经验证的情况下对不安全的 API 运行。从 v0.5.0 开始,生产部署需要满足三个条件: ### 1. API 密钥认证 在启动 FastAPI 服务器之前,将 `SECURESCAN_API_KEY` 设置为一个强随机字符串: ``` export SECURESCAN_API_KEY="$(openssl rand -hex 32)" uvicorn securescan.main:app --host 0.0.0.0 --port 8000 ``` 设置环境变量后,每个 `/api/*` 端点都需要请求头 `X-API-Key: `(或者对于倾向于 Bearer 认证的工具,使用 `Authorization: Bearer `)。`/health` 和 `/ready` 保持公开,以供 Kubernetes / 负载均衡器探测。 当未设置 `SECURESCAN_API_KEY` 时,服务器在启动时会记录清晰的警告(`SECURESCAN_API_KEY not set; API is unauthenticated (dev mode).`),并在无认证的情况下提供所有路由服务 —— 这是为零配置本地开发保留的 v0.4.0 行为。 对于仪表板前端,在构建/部署时设置 `NEXT_PUBLIC_SECURESCAN_API_KEY`,以便所有客户端请求自动携带该标头。 ### 2. 结构化日志 容器中默认使用 JSON 日志(捆绑的 Dockerfile 设置了 `SECURESCAN_IN_CONTAINER=1`)。使用以下内容覆盖: ``` export SECURESCAN_LOG_FORMAT=json # or "text" export SECURESCAN_LOG_LEVEL=INFO # DEBUG | INFO | WARNING | ERROR ``` 每个请求会发出一个带有 `request_id`、`method`、`path`、`status` 和 `latency_ms` 的结构化日志条目,以便日志聚合器能按请求生命周期进行关联。客户端可以通过发送 `X-Request-ID: ` 来固定 request_id;否则服务器会生成一个,并通过相同的标头回传。 ### 3. 健康和就绪探测 | 端点 | 目的 | 何时访问 | |---|---|---| | `GET /health` | 存活 —— 进程在运行。除非进程崩溃,否则始终返回 200。 | Kubernetes `livenessProbe`,简单的正常运行时间检查。 | | `GET /ready` | 就绪 —— 数据库可打开,扫描器注册表已加载。就绪时返回 200 和检查 JSON;未就绪时返回 503 和详细信息。 | Kubernetes `readinessProbe`,ALB 目标组健康检查滚动更新门控。 | Kubernetes 部署片段示例: ``` livenessProbe: httpGet: { path: /health, port: 8000 } initialDelaySeconds: 5 periodSeconds: 10 readinessProbe: httpGet: { path: /ready, port: 8000 } initialDelaySeconds: 2 periodSeconds: 5 ``` ### 4. 反向代理 / TLS 捆绑的 uvicorn 入口点提供普通 HTTP 服务。生产部署应位于 TLS 终止代理(nginx、Traefik、AWS ALB、Caddy 等)之后,并转发 `X-Request-ID` 标头,以便客户端关联能够端到端工作。 ### 5. 速率限制 `POST /api/scans`(以及向前兼容的 `POST /api/v1/scans` 挂载点)使用内存中的令牌桶进行速率限制,因此单个客户端不能用昂贵的扫描任务淹没协调器。读取端点(列出扫描、获取发现、仪表板、sbom)不受速率限制 —— 它们成本很低,并且有利于在事件分流期间保持响应性。 默认值:**60 个请求 / 分钟**,突发为 **10 个**,按 API 密钥(或者在未设置 `SECURESCAN_API_KEY` 时按客户端 IP)。使用环境变量覆盖: ``` export SECURESCAN_RATE_LIMIT_PER_MIN=60 # sustained rate export SECURESCAN_RATE_LIMIT_BURST=10 # burst capacity export SECURESCAN_RATE_LIMIT_ENABLED=true # set to false to disable ``` 每个受速率限制的响应都带有 `X-RateLimit-Limit`、`X-RateLimit-Remaining` 和 `X-RateLimit-Reset` (unix-ts),因此客户端可以干净地退避。当桶为空时,服务器返回带有 `Retry-After` 标头和结构化 JSON 主体的 HTTP `429`: ``` { "detail": "Rate limit exceeded", "retry_after": 7, "limit_per_min": 60 } ``` 桶存储是有界的(最多 1 万个活动密钥,1 小时空闲 TTL,采用 LRU 淘汰),因此密钥轮换或 DoS 模式不会无限制地增加内存。 ### 6. 实时扫描进度 (SSE) —— 仅限单 worker `GET /api/v1/scans/{scan_id}/events`(以及旧版 `/api/scans/...` 别名)会发出生命周期事件的 Server-Sent Events 流(`scan.start`、`scanner.start`、`scanner.complete`、`scanner.skipped`、`scanner.failed`、`scan.complete`、`scan.failed`、`scan.cancelled`),以便仪表板无需轮询即可显示实时进度。迟到的订阅者会获得一个 30 秒的重放缓冲区,因此在扫描最后几秒钟内的选项卡刷新仍然可以接收完整的事件序列和终止事件。 ## 子命令 | 命令 | 作用 | |---|---| | `securescan scan ` | 对目录进行完整扫描。以任何格式输出发现。 | | `securescan diff --base-ref --head-ref ` | Diff 感知扫描:仅显示自 base ref 以来引入的 NEW 发现。 | | `securescan compare ` | 将当前扫描与保存的基线进行比较;报告偏移(消失了什么)。 | | `securescan baseline [-o ]` | 写入当前发现的规范基线 JSON(确定性;可检入 git)。 | | `securescan config validate []` | 对 `.securescan.yml` 进行 Lint 检查,包括拼写错误、错误的严重性、缺失的规则包路径。 | | `securescan history` | 列出过去保存的扫描。 | | `securescan status` | 列出哪些扫描器已安装且可用。 | | `securescan serve` | 运行 FastAPI 仪表板后端。 | ## 输出格式 | 格式 | 用例 | |---|---| | `github-pr-comment` (`diff` 的默认值) | 通过 `` 标记进行 PR 更新插入 —— 每个 PR 一条评论,每次推送时原地更新 | | `sarif` | GitHub Code Scanning / Security 选项卡;发出 `partialFingerprints` 以便重新上传时干净地去重 | | `json` | 下游工具、基线、快照模式的 diff 输入、调试 | | `text` | 人类可读的终端输出(当未提供 `--output` 时,TTY 上 `diff` 的默认值) | ## 确定性 每个渲染器都会为相同的输入产生字节一致的输出: - 发现按规范键(严重性、扫描器、规则 id、文件路径、行号)排序。 - 每个发现都会获得一个稳定的指纹 `sha256(scanner | rule_id | file_path | normalized_line_context | cwe)`,因此微不足道的空白或行偏移不会将其重新分类为新发现。 - 任何输出负载中都没有实际运行时间戳 —— 在测试或 CI 重放中设置 `SECURESCAN_FAKE_NOW` 以固定唯一存在的时间派生字段。 - SARIF 中的规则列表已去重并排序。 PR 评论的更新插入和 SARIF Security 选项卡的去重都依赖于这一点 —— 不确定的输出会静默破坏“每个 PR 单条评论”的属性。 ## 扫描器 | 扫描器 | 类型 | 发现内容 | |---------|------|--------------| | **Semgrep** | 代码 (SAST) | SQL 注入、XSS、硬编码机密、命令注入 | | **Bandit** | 代码 (Python) | 特定于 Python 的安全问题、不安全的导入 | | **Secrets** | 代码 | 硬编码凭证、API 密钥、令牌、私钥 | | **Git Hygiene** | 代码 | 仓库中的敏感文件、缺少 `.gitignore` 保护 | | **Trivy** | 依赖 | 包清单和锁文件中已知的 CVE | | **Safety** | 依赖 | Safety DB 中的 Python 依赖漏洞 | | **License Checker** | 依赖 | Copyleft / 未知许可证合规风险 | | **npm Audit** | 依赖 | npm 包公告和传递性漏洞 | | **Checkov** | IaC | Terraform、K8s、Docker 和云配置错误 | | **Dockerfile** | IaC | 不安全的 Docker 模式(`:latest`、root 用户、`curl \| sh`、`ENV` 中的机密) | | **Baseline** | 系统配置 | SSH、防火墙、密码策略、内核安全检查 | | **DAST Built-in** | DAST | 缺少安全标头、信息泄露、不安全的 cookie 标志 | | **OWASP ZAP** | DAST | 通过 ZAP 主动/被动扫描发现 Web 应用程序漏洞 | | **Nmap** | 网络 | 开放端口、服务检测、风险分类 | 使用 `--type code --type dependency`(等)以将运行限制在某个类别;`securescan diff` 的默认值是 `code`,以实现快速的 PR 反馈。 ## AI 增强(可选) 设置 Groq API 密钥(免费层级)以启用 AI 驱动的修复建议、执行摘要和上下文风险分析: ``` export SECURESCAN_GROQ_API_KEY=your-key-here ``` AI 增强**在 CI 中默认关闭**(当设置 `CI=true` 时自动禁用,无论 API 密钥如何),因为它是不确定的,并且会破坏评论更新插入 / SARIF 去重不变性。使用 `--no-ai` 以明确禁用,或使用 `--ai` 在已选择退出这些不变性的 CI 运行中强制重新启用增强。 ## 仪表板(辅助界面) 原有的 v0.1.0 仪表板仍保持不变地工作:位于 [`backend/securescan/main.py`](./backend/securescan/main.py) 的 FastAPI 后端和位于 [`frontend/`](./frontend) 的 Next.js 前端。当您希望浏览历史扫描、交互式检查发现或通过 UI 而不是 CLI 标志选择扫描目标时,它是合适的界面。v0.2.0 的切入点是 GitHub Action;仪表板现在被定位为辅助的本地/内部工具,而不是主要入口点。 快速开始: ``` # Backend (FastAPI 在 :8000) cd backend python3 -m venv venv && source venv/bin/activate pip install -e . pip install semgrep bandit safety pip-licenses checkov securescan serve --host 127.0.0.1 --port 8000 # Frontend (Next.js 在 :3000),在另一个 shell 中 cd frontend npm install npm run dev # All-in-one docker compose up ``` 打开 http://localhost:3000 —— 它与位于 http://localhost:8000 的后端通信。 ## 本地配置 SecureScan 在启动时加载 `~/.config/securescan/.env`。使用它在重启之间持久化凭证: ``` # ~/.config/securescan/.env SECURESCAN_ZAP_ADDRESS=http://127.0.0.1:8090 SECURESCAN_ZAP_API_KEY=your-key-here ``` Shell 环境变量优先于此文件。 ## 发布签名 每个带标签的发布都会发布已签名的构件。确切的验证命令由 [`.github/workflows/release.yml`](./.github/workflows/release.yml) 附加到每个 GitHub Release 的说明中;模板在此处针对 ``(例如 `v0.2.0`)和 ``(例如 `0.2.0`)进行复现: ### Wheel 包 + sdist (sigstore-python) ``` pip install sigstore sigstore verify identity \ --cert-identity 'https://github.com/Metbcy/securescan/.github/workflows/release.yml@refs/tags/' \ --cert-oidc-issuer https://token.actions.githubusercontent.com \ securescan--py3-none-any.whl ``` 匹配的 `*.sigstore.json` 包作为 GitHub Release 资产与 wheel 包一起提供。 ### 容器镜像 (cosign 无密钥) ``` cosign verify \ --certificate-identity 'https://github.com/Metbcy/securescan/.github/workflows/release.yml@refs/tags/' \ --certificate-oidc-issuer https://token.actions.githubusercontent.com \ ghcr.io/metbcy/securescan: ``` 这两个身份都固定为 `refs/tags/` —— 这就是为什么发布工作流仅由标签触发,且不提供 `workflow_dispatch`(手动运行将在 `refs/heads/...` 身份下发布,并破坏这些验证命令)。 ### 固定 GitHub Action `Metbcy/securescan@v1` 是浮动的主要版本标签 —— 它会自动跟踪最新的 `v1.x.y` 稳定版发布,并且是推荐大多数用户固定的版本。`Metbcy/securescan@v0.11.0`(或任何特定的 `vX.Y.Z`)是不可变的每个发布固定 —— 当您想要可重现的 CI 行为和显式升级时使用它。**未**发布 `:latest`;请固定到一个标签。 ## 非目标 SecureScan 故意**不**尝试成为: - SBOM 生成器(请使用 Syft / cyclonedx-cli)。 - 依赖树可视化工具。 - 完整 SCA 平台(Snyk、Dependabot 等)的替代品。 SecureScan 编排开源扫描器并增加 diff 感知能力;它不维护自己的漏洞数据库。 - 自身的漏洞数据库。 切入点是*“在您已信任的扫描器之上提供 diff 感知的 PR 评论 + SARIF + 签名发布”*,而不是*“重新发明安全工具链”*。 ## 参考
v0.1.0 仪表板 / API 端点(仍然可用) | 方法 | 端点 | 描述 | |--------|----------|-------------| | GET | `/` | 带有文档和健康检查链接的 API 信息 | | GET | `/health` | 简单的健康检查 | | POST | `/api/scans` | 启动新的扫描 | | GET | `/api/scans` | 列出所有扫描 | | GET | `/api/scans/{id}` | 获取扫描详情 | | GET | `/api/scans/{id}/findings` | 获取扫描发现 | | GET | `/api/scans/{id}/summary` | 获取扫描摘要 | | POST | `/api/scans/{id}/cancel` | 取消活动的扫描 | | GET | `/api/scans/compare` | 比较两次扫描(新增、已修复、未更改) | | GET | `/api/dashboard/status` | 扫描器可用性 | | GET | `/api/dashboard/stats` | 聚合统计信息 | | GET | `/api/dashboard/trends` | 风险/发现趋势数据 | | GET | `/api/browse` | 文件系统目录选择器数据 | | POST | `/api/dashboard/install/{scanner}` | 安装受支持的扫描器 |
运行测试 ``` cd backend source venv/bin/activate pytest tests/ -v ```
技术栈 - **后端**: Python, FastAPI, SQLite, asyncio, Typer - **前端**: Next.js 15, Tailwind CSS, Recharts - **CI / 发布**: GitHub Actions, sigstore-python, cosign - **AI**: Groq API (Llama 3) —— 可选,在 CI 中关闭 - **扫描器**: 14 个集成扫描器(代码、依赖、IaC、DAST、网络、基线)
## 许可证 Apache 2.0 —— 参见 [`LICENSE`](./LICENSE)。
标签:CI/CD安全, DevSecOps, Docker容器, Llama, Python, SARIF, SBOM, SSE实时通信, Sysdig, Webhook, 上游代理, 代码安全分析, 力导向图, 多扫描器编排, 安全仪表盘, 安全合规, 安全基线对比, 安全扫描, 攻击面发现, 无后门, 时序注入, 硬件无关, 终端工具, 网络代理, 自托管, 请求拦截, 跌倒检测, 软件物料清单, 逆向工具, 风险评分