faultline-go/faultline

GitHub: faultline-go/faultline

本地优先的 Go 仓库结构性风险扫描器,通过代码结构、git 历史、覆盖率、依赖和所有权等信号生成可解释的包级风险证据,帮助团队有目标地偿还技术债。

Stars: 2 | Forks: 0

# Faultline [![ci](https://static.pigsec.cn/wp-content/uploads/repos/2026/05/5b02cb7fd5094340.svg)](https://github.com/faultline-go/faultline/actions/workflows/ci.yml) [![release](https://static.pigsec.cn/wp-content/uploads/repos/2026/05/fe85ebc8af094341.svg)](https://github.com/faultline-go/faultline/actions/workflows/release.yml) [![License](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE) [![Go Reference](https://pkg.go.dev/badge/github.com/faultline-go/faultline.svg)](https://pkg.go.dev/github.com/faultline-go/faultline) **结构性风险。为 Go 仓库提供无源代码证据。** Faultline 是一个本地优先的 Go 仓库结构性风险扫描器。它根据代码结构、git 历史、所有权、覆盖率、依赖项元数据、测试信号、事件注解和架构策略输入,生成可解释的包级证据,而无需将源代码发送到托管服务。 ``` go install github.com/faultline-go/faultline/cmd/faultline@latest faultline scan ./... --format html --out faultline-report.html ``` ![Faultline HTML 报告截图](https://static.pigsec.cn/wp-content/uploads/repos/2026/05/56a594f19a094342.png) Faultline 是本地优先的。它不上传源代码、不运行服务器、不执行仓库脚本,也不需要运行时网络访问。报告可以生成为 HTML、JSON、用于 GitHub 代码扫描的 SARIF、PR markdown,或用于项目组合治理的仅元数据快照。 ## 为什么团队使用它 - **证据胜于观点:** 展示哪些包具有高变动、低覆盖率、不明确的所有权、高中心性、薄弱的测试、事件历史、过期的抑制或策略偏离。 - **默认保持本地:** 在开发者 shell 或 CI 中进行扫描,无需上传源代码。 - **保持分析可解释性:** 每个分数都包含证据,以便团队了解某个包存在风险的原因。 - **通往治理的桥梁:** 导出 `faultline.snapshot.v1` 元数据用于仪表板、抑制审查、策略工作流和审计就绪报告,同时保持代码私有。 ## 一次配置完成从开源到企业版的过渡 当您需要在开发者控制的环境中生成本地报告、PR 评论、SARIF 或元数据快照时,请使用开源扫描器。当重度使用 Go 的工程组织需要跨仓库的治理证据层时(每周审查、所有权偏移、抑制债务、策略包工作流、依赖项健康状况、事件关联和审计证据),请使用 Faultline 企业版。 最快的企业版路径是: 1. 在 [app.gofaultline.dev](https://app.gofaultline.dev) 开始试用。 2. 在 **Settings -> API Tokens** 中创建 API token。 3. 运行启用了企业版上传的扫描器: ``` faultline scan ./... \ --enterprise-url https://api.gofaultline.dev \ --enterprise-token "$FAULTLINE_API_TOKEN" \ --enterprise-org-id "$FAULTLINE_ORG_ID" ``` 激活里程碑是在企业版仪表板中的第一个非演示快照。源代码保留在您的 shell 或 CI 运行器中;企业版接收无源代码的仓库元数据、包风险记录、发现、抑制、策略信号、依赖项元数据和审计事件。 尝试捆绑的示例: ``` go build -o bin/faultline ./cmd/faultline cd testdata/simple-go-module ../../bin/faultline scan ./... --format html --out faultline-report.html --no-history ``` 有关示例输出,请参阅 [docs/demo.md](docs/demo.md),有关生成的示例报告,请参阅 [examples/reports](examples/reports)。 Faultline OSS 采用 Apache 2.0 许可证。该公共项目旨在对本地和 CI 工作流保持真正的实用性;付费产品应该从组织范围的治理和自动化中获利,而不是削弱本地扫描功能。 ## Faultline 是什么 - 一个用于包级 Go 结构性风险证据的本地 CLI 工具。 - 一种揭示具有高变动、低覆盖率、不明确的所有权、高中心性、薄弱的测试、事件历史、依赖项风险信号或重度生成代码指标的包的方法。 - 一个用于可选托管治理、审计和项目组合报告的无源代码元数据生产器。 ## Faultline 不是什么 - 它不是漏洞扫描器。 - 它不是代码质量平台。 - 它不是运行时可观测性工具。 - 它不是工程生产力分析工具。 - 它不是 SaaS 后端。 - 它不是仪表板。 - 它不是测试、代码审查或架构所有权的替代品。 ## 开放核心边界 Faultline 的 OSS 核心包括扫描引擎、本地 HTML/JSON/SARIF/快照报告、PR markdown 输出、本地基线、本地 SQLite 历史、配置治理、抑制审计、本地规则包、依赖项发现、边界发现、所有权发现和多模块扫描。 商业 Faultline 产品应该是附加的:多仓库仪表板、集中式策略包、抑制审批工作流、SSO/RBAC、Slack/Jira 自动化、项目组合趋势、审计导出和托管入职。扫描器、SARIF、PR markdown、本地报告、本地趋势、基线和配置策略引擎必须保持无需登录即可使用。 付费系统的公共集成契约是仅限元数据的:`faultline scan --format snapshot` 会发出 `faultline.snapshot.v1`,这是一个无源代码的上传契约。请参阅 [docs/open-core.md](docs/open-core.md) 和 [docs/export-contracts.md](docs/export-contracts.md)。 ## MCP 和 Agent Skills Faultline 企业版为希望 AI 助手在不将源代码上传的情况下查询项目组合治理数据的团队公开了可选的代理集成。 OSS 扫描器保持本地优先;代理基于企业版元数据工作,例如快照摘要、风险分数、发现代码、抑制、策略包和审计事件。 - MCP 端点:`https://mcp.gofaultline.dev/mcp` - MCP 文档:`https://docs.gofaultline.dev/mcp/` - Agent Skills 发现:`https://skills.gofaultline.dev/llms.txt` - Faultline 技能清单: `https://skills.gofaultline.dev/faultline/SKILL.md` 诸如 `faultline_explain_finding` 和 `faultline_explain_score` 之类的实用 MCP 工具不需要身份验证。企业版数据工具需要来自 `app.gofaultline.dev` 的 Faultline API token,并针对仅限元数据的组织/仓库记录进行操作。 ## 安装 使用 Go 从源代码安装: ``` go install github.com/faultline-go/faultline/cmd/faultline@latest faultline version ``` 从发布归档文件安装: ``` # 从 GitHub Releases 中选择一个 release。 VERSION=vX.Y.Z curl -L -o faultline.tar.gz "https://github.com/faultline-go/faultline/releases/download/${VERSION}/faultline_${VERSION#v}_linux_amd64.tar.gz" curl -L -o checksums.txt "https://github.com/faultline-go/faultline/releases/download/${VERSION}/checksums.txt" sha256sum --check --ignore-missing checksums.txt tar -xzf faultline.tar.gz install -m 0755 faultline /usr/local/bin/faultline faultline version ``` 在 macOS 上,如果 `sha256sum` 不可用,请使用 `shasum -a 256 -c checksums.txt`。在 Windows 上,下载 `.zip` 归档文件并使用 `Get-FileHash` 验证 SHA-256 哈希值。 在 tap 发布后,使用 Homebrew 安装: ``` brew tap faultline-go/tap brew install --cask faultline faultline version ``` 使用 Docker 运行: ``` docker run --rm ghcr.io/faultline-go/faultline:latest version docker run --rm -v "$PWD:/workspace" -w /workspace ghcr.io/faultline-go/faultline:latest scan ./... --format html --out faultline-report.html ``` 该容器包含 Go 和 git,以便包加载和历史分析可以在 CI 中工作。仅当挂载可写时,`.faultline/` 下的本地历史才会写入挂载的仓库中;否则,历史会降级为报告警告。 运行第一次本地扫描: ``` faultline scan ./... --format html --out faultline-report.html ``` 创建无源代码的企业版快照: ``` faultline scan ./... --format snapshot --out faultline-snapshot.json ``` ## 验证发布 Faultline 的发布工件设计为分层次检查: - `checksums.txt` 验证文件完整性。 - `checksums.txt.sig` 和 `checksums.txt.pem` 使用 Cosign 无密钥签名验证校验和的真实性。 - GitHub 工件证明将工件链接到发布工作流。 - SPDX JSON SBOM 文件描述了打包的内容和依赖项。 验证示例: ``` sha256sum --check --ignore-missing checksums.txt cosign verify-blob checksums.txt \ --signature checksums.txt.sig \ --certificate checksums.txt.pem \ --certificate-identity-regexp 'https://github.com/faultline-go/faultline/.github/workflows/release.yml@refs/tags/v.*' \ --certificate-oidc-issuer https://token.actions.githubusercontent.com gh attestation verify faultline_vX.Y.Z_linux_amd64.tar.gz --repo faultline-go/faultline ``` SBOM 是与发布归档文件同名的 SPDX JSON 文件,例如 `faultline_vX.Y.Z_linux_amd64.tar.gz.spdx.json`。 对于本地开发: ``` make build bin/faultline version make quality ``` `make quality` 运行仓库的格式化、模块 tidy 状态、测试、`golangci-lint` 和 Go 团队的 `deadcode` 分析器的同等性检查门。 请参阅 [docs/tool-parity.md](docs/tool-parity.md),了解 Faultline 的原生信号与委托的 Go 静态分析工具之间的完整映射。 ## 贡献与安全 Faultline 在 Apache 2.0 许可证下接受带有开发者原创证书签核的贡献: ``` git commit -s ``` 有用的首次贡献包括嘈杂的发现报告、来自真实 Go monorepo 的示例配置、文档修复和小型扫描器边缘情况。当报告在技术上是正确的但没有用时,请使用 `Noisy finding` 问题模板。 有关贡献指南,请参阅 [CONTRIBUTING.md](CONTRIBUTING.md),有关漏洞报告,请参阅 [SECURITY.md](SECURITY.md)。Faultline 名称和标志未获得 Apache 2.0 许可;请参阅 [NOTICE](NOTICE)。 ## 用法 ``` faultline scan ./... --format html --out faultline-report.html faultline scan ./... --format json --out faultline-report.json faultline scan ./... --format sarif --out faultline.sarif faultline scan ./... --format snapshot --out faultline-snapshot.json ``` 使用 `--format snapshot` 获取仅限元数据的 `faultline.snapshot.v1` 上传契约。使用 `--format json` 获取本地开发者报告。 默认情况下,扫描存储在本地 `.faultline/faultline.db` 中,以便后续报告可以显示风险趋势。可以使用以下命令禁用此功能: ``` faultline scan ./... --no-history --format html --out faultline-report.html ``` 使用覆盖率: ``` go test ./... -coverprofile=coverage.out faultline scan ./... --coverage coverage.out --format html --out faultline-report.html ``` 使用构建标签和排除项: ``` faultline scan ./... --tags integration,linux --exclude "testdata/..." --format json --out report.json ``` ## 多模块仓库 Faultline 会发现仓库根目录下的所有 `go.mod` 文件,同时跳过 `vendor/`、`third_party/`、`node_modules/` 和 `.git/`。当存在根 `go.work` 时,报告会显示工作区包含哪些模块。 默认行为: - 从仓库根目录运行会扫描所有已发现的模块。 - 从一个模块内部运行会扫描该模块。 - `--all-modules` 会扫描每个已发现的模块,即使是从一个模块内部调用。 模块选择: ``` faultline scan ./... --all-modules --format html --out faultline-report.html faultline scan ./... --module service-a --format json --out service-a-report.json faultline scan ./... --module example.com/org/service-a --ignore-module shared --format json --out report.json ``` 报告包含一个 `modules` 数组,包括模块路径、模块根目录、`go.mod` 路径、go.work 包含情况和选择状态。包记录包括 `module_path` 和 `module_root`,依赖项清单按源模块分组。仓库内的跨模块本地 `replace` 会发出 `FL-DEP-007`。 当前的 monorepo 限制: - 包加载是面向模块的;所选模块根目录之外的异常包模式可能需要显式选择模块。 - `go.work` 在仓库根目录下检测。 - PR 审查更改包检测处理模块边界,但依赖项影响仍然是基于包/import 的,而不是完整的模块图影响。 ## 所有权解析 Faultline 使用确定性优先级从多个本地信号中解析包所有权: 1. 来自 `owners.modules` 的显式模块所有者 2. CODEOWNERS 匹配 3. 通过 `owners.aliases` 映射的主要最近 git 作者 4. 作为低置信度回退的主要最近 git 作者 5. 未知 示例: ``` owners: aliases: "@payments-platform": - "alice@example.com" - "bob@example.com" - "@github-team/payments" modules: "github.com/acme/service-a": owner: "@service-a-team" "github.com/acme/shared": owner: "@platform-team" ``` 报告包括所选所有者、所有者来源、候选所有者、置信度以及每个所有权来源的证据。在多模块仓库中,为每个模块添加 `owners.modules` 条目,以便在模块路径或目录移动时包所有权保持稳定。 Faultline 将包所有权和文件所有权分开: - 包所有权用于包风险报告和评分证据。 - 文件所有权用于确切文件上下文重要的情况:更改文件的 PR 审查摘要、边界违规以及具有确切文件位置的 SARIF 结果。 所有权发现: - `FL-OWN-001`:未找到所有者。 - `FL-OWN-002`:过去 90 天内作者数量多。 - `FL-OWN-003`:CODEOWNERS 所有者与主要 git 作者或别名不同。 - `FL-OWN-004`:多模块仓库中缺少模块所有者。 Git 作者身份是一种推断信号,而非权威。使用别名将电子邮件和外部团队句柄映射到规范的所有者团队,并优先使用显式模块所有者或 CODEOWNERS 进行强制执行。 ### CODEOWNERS 兼容性 Faultline 使用 GitHub 的位置优先级读取找到的第一个 CODEOWNERS 文件: 1. `.github/CODEOWNERS` 2. `CODEOWNERS` 3. `docs/CODEOWNERS` 在该文件中,最后匹配的规则优先。Faultline 支持注释、空行、多个所有者、模式中实用的转义空格、以 `/` 结尾的目录模式、以 `/` 开头的根锚定模式以及常见的通配符模式。 所有权证据包括匹配的 CODEOWNERS 文件、行号、模式以及来自所选规则的所有者。当 Faultline 可以定位导入时,边界发现还包括导入文件的文件级所有者证据。PR 审查使用所有者总结更改的文件、没有所有者的更改文件,以及确切文件所有者与所选包所有者之间的不匹配。CODEOWNERS 诊断默认是警告,包括格式错误的规则、没有所有者的规则、不支持的模式以及既不是 `@` 前缀也不是类似电子邮件的所有者 token。使用 `--strict-config` 时,当使用 CODEOWNERS 文件时,CODEOWNERS 诊断将导致扫描和 PR 审查失败。 已知的兼容性偏差: - Faultline 会针对不支持的 GitHub CODEOWNERS 构造(例如 `!` 否定和字符范围)发出警告,而不是将其视为权威策略。 - 匹配是有意近似且面向包的;GitHub 在文件路径处评估所有权。 - CODEOWNERS 是治理证据,而不是所列团队当前负责的证明。 通过仅读取本地 `go.mod` 和 `go.sum`,模块仓库会自动包含依赖项清单。Faultline 在默认扫描期间不调用模块代理、运行 `go get`、修改模块文件或查询漏洞数据库。 可选的 `govulncheck` 集成默认关闭: 启用后,`govulncheck` 输出将标记为外部工具输出。Faultline 将不可用或失败的 `govulncheck` 运行视为警告,以便结构性报告仍能完成。 ## 配置治理 `faultline.yaml` 在用作 CI 强制执行工件之前可以进行验证和解释: ``` faultline config validate --config faultline.example.yaml faultline config validate --config faultline.yaml --strict faultline config explain --config faultline.yaml --format markdown faultline config explain --config faultline.yaml --format json --out faultline-config.json faultline config schema --format markdown --out faultline-config-schema.md faultline config docs --config faultline.yaml --format markdown --out faultline-policy.md faultline config resolved --config faultline.yaml --format yaml --out resolved.yaml ``` 验证检查支持的配置版本、边界规则形状、解析后的 `suppression_policy`、抑制必填字段和过期日期、所有权别名/模块所有者形状、阈值范围,以及顶层和 `ownership`、`owners`、`coverage`、`scoring`、`boundaries[]`、`suppression_policy` 和 `suppressions[]` 下的未知键。默认情况下,未知键是警告。使用 `--strict` 时,普通验证警告将返回退出代码 `1`;强制执行警告(例如嵌套的未知键或抑制策略违规)、解析错误和不支持的版本将返回退出代码 `2`。 `config schema` 生成包含字段类型、必填状态、默认值、验证规则和示例的支持 schema。`config docs` 从特定的 `faultline.yaml` 生成人类可读的治理文档,包括分组的抑制和严格模式就绪性摘要。 有关单一服务仓库、多模块 monorepo、重度使用 CODEOWNERS 的仓库和架构边界强化的经过清理的 `faultline.yaml` 起始点,请参阅 [docs/config-examples.md](docs/config-examples.md)。 通过使用 `--strict-config`,扫描、基线和 PR 审查可以在遇到配置警告时快速失败: ``` faultline scan ./... --config faultline.yaml --strict-config --format json --out faultline-report.json faultline baseline check --baseline faultline-baseline.json --config faultline.yaml --strict-config faultline pr review --config faultline.yaml --strict-config --comment-out review.md ``` 抑制审计显示豁免是处于活动、已过期、在 30 天内过期、不完整、违反策略,还是与任何当前发现均不匹配: ``` faultline suppressions audit --config faultline.yaml --format markdown faultline suppressions audit --config faultline.yaml --format json --out faultline-suppressions.json ``` 配置解释和扫描输出包括配置哈希,以便可以将 CI 工件与确切的策略输入绑定。 ### 规则包 规则包允许组织跨仓库重用版本化的本地治理策略: ``` version: 1 rule_packs: - path: .faultline/rules/platform.yaml - path: .faultline/rules/payments.yaml coverage: min_package_coverage: 75 suppressions: - id: FL-BND-001 category: BOUNDARY package: "*/internal/legacy/*" reason: "Repo-owned migration waiver" owner: "@payments" created: "2026-04-01" expires: "2026-06-30" ``` 规则包可以定义 `ownership`、`owners`、`coverage`、`scoring`、`boundaries` 和 `suppression_policy`。抑制被有意限制为仓库本地,如果放置在规则包内,将被忽略并发出警告。 在所有导入解析完毕后,将对仓库本地的抑制强制执行规则包抑制策略: ``` suppression_policy: require_owner: true require_reason: true require_expiry: true max_days: 90 ``` 每个抑制上的 `created` 是可选的。当存在时,`max_days` 从 `created` 开始计算;否则,Faultline 使用扫描或验证日期。在非严格模式下,会报告违反策略的抑制,并且它们可能仍然适用。使用 `--strict-config` 时,抑制策略警告会导致扫描、基线检查和 PR 审查以退出代码 `2` 失败。 合并优先级是确定性的: - 规则包按列出的顺序处理。 - 后面的规则包覆盖前面的标量设置。 - 仓库本地的 `faultline.yaml` 覆盖导入的标量设置。 - 边界通过 `name` 附加并去重;非相同的重复项会发出警告,并且后面的规则优先。 - 仓库本地的抑制在完整策略解析完毕后应用。 规则包路径仅为本地文件。Faultline 不会从网络获取规则包、展开环境变量、执行命令或读取远程注册表。默认情况下,规则包路径必须保留在仓库根目录内,并且逃逸仓库的符号链接会被拒绝。仅对显式受信任的本地策略布局使用 `--allow-config-outside-repo`。 ## 基线治理 基线允许团队逐步降低风险,而不会因为现有技术债导致 CI 失败。从已接受的扫描创建一个无源代码的快照: ``` faultline baseline create --out faultline-baseline.json ``` 然后根据它检查未来的扫描: ``` faultline baseline check --baseline faultline-baseline.json --fail-on-new high faultline baseline check --baseline faultline-baseline.json --fail-on-new high --fail-on-risk-delta 10 --format markdown --out faultline-baseline-check.md ``` 基线文件存储扫描元数据、仓库指纹、配置哈希、包风险分数、发现身份、活动抑制和摘要计数。它们不存储源代码或文件内容。 发现身份基于发现 ID、包导入路径、类别、稳定的证据键/值对、边界拒绝导入证据(如果存在)以及包级位置元数据。被抑制的发现仍然在基线检查输出中可见,但它们不会触发 `--fail-on-new`。 典型的棘轮式工作流: 1. 审查当前报告并修复紧急问题。 2. 从已接受的状态创建 `faultline-baseline.json`。 3. 将基线文件签入仓库或将其作为受控 CI 工件存储。 4. 在 CI 中运行 `baseline check`,仅在出现新的未抑制发现或配置的风险增量时失败。 5. 仅在审查已解决的技术债和剩余的豁免后定期重新生成基线。 基线是治理豁免,而不是安全证明。它们保留了已知风险,以便团队可以刻意地改善它。 CI 基线门槛示例: ``` name: Faultline Baseline on: [pull_request] jobs: baseline: runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 with: fetch-depth: 0 - uses: actions/setup-go@v6 with: go-version: stable - run: go install github.com/faultline-go/faultline/cmd/faultline@latest - run: faultline baseline check --baseline faultline-baseline.json --fail-on-new high --fail-on-risk-delta 10 --format markdown --out faultline-baseline-check.md - uses: actions/upload-artifact@v7 if: always() with: name: faultline-baseline-check path: faultline-baseline-check.md ``` 对于在本地生成的拉取请求审查评论: ``` faultline pr review --base origin/main --head HEAD --compare-mode auto --comment-out faultline-pr-review.md ``` 要在 CI 中发布或更新 GitHub 拉取请求评论: ``` faultline pr review --post --compare-mode auto --fail-on high ``` 使用架构边界: ``` version: 1 boundaries: - name: handlers-must-not-import-storage from: "*/internal/handlers/*" deny: - "*/internal/storage/*" except: - "*/internal/storage/contracts" ``` 边界规则匹配包导入路径和包目录。违规会发出 `FL-BND-001`,其中包含导入包、拒绝导入、规则名称和匹配的策略证据。 评分校准可以在仓库本地配置或共享规则包中进行调整。默认值保留 Faultline 的初始风险模型。 ``` scoring: churn_max_lines_30d: 1000 complexity_max_loc: 1000 complexity_max_imports: 20 complexity_max_files: 30 dependency_centrality_max_reverse_imports: 10 ``` 抑制是豁免,而不是删除。被抑制的发现仍保留在包发现和顶级抑制审计中,但它们不会触发 `--fail-on`。 ``` suppression_policy: require_owner: true require_reason: true require_expiry: true max_days: 90 suppressions: - id: FL-BND-001 category: BOUNDARY package: "*/internal/handlers/*" reason: "Temporary migration while storage interface is extracted" owner: "@platform-team" created: "2026-04-30" expires: "2026-07-29" ``` 有用的标志: - `--format html|json|sarif` - `--out ` - `--coverage ` - `--config ` - `--tags ` - `--fail-on none|high|critical` - `--include-generated` - `--exclude ` 可重复使用 - `--strict-config` - `--no-history` - `--verbose` ## 本地历史 Faultline 在 `.faultline/faultline.db` 的 SQLite 中持久化扫描元数据、包指标、发现、警告和抑制元数据。它使用纯 Go 的 SQLite 驱动程序,因此不需要 CGO 和原生 SQLite 工具链。 它不存储源代码、完整文件内容或远程遥测。历史记录行仅包含指标和发现元数据。 趋势字段将当前扫描与同一仓库身份的最近一次先前扫描进行比较: - `previous_risk_score` - `risk_delta` - `trend`:`NEW`、`IMPROVED`、`WORSENED` 或 `UNCHANGED` 检查本地历史: ``` faultline history list faultline history show faultline history prune --before 2026-01-01 faultline history doctor ``` ### 仓库指纹 Faultline 在每次扫描时存储一个稳定的 `repo_fingerprint` 和显示名称,以便历史可以跟随仓库跨越移动的目录、CI 工作区和容器。 指纹输入,按优先级顺序: 1. 规范化的 `git remote origin` URL、git 顶级目录名称以及可用时的默认/当前分支。 2. `go.mod` 模块路径加上仓库基本名称。 3. 排序后的已扫描包导入根目录加上仓库基本名称。 该指纹是这些本地元数据字段的 SHA-256 哈希值。远程 URL 在哈希前会被规范化,并且不包括源代码。 `.faultline/` 通常应该被 gitignore: ``` .faultline/ ``` ## 退出代码 - `0`:扫描完成;未达到配置的失败阈值。 - `1`:扫描或基线检查完成,并且配置的阈值匹配到了未抑制的发现或风险增量。 - `2`:执行或配置错误。 默认值对 CI 是安全的:除非显式设置 `--fail-on`,否则扫描不会导致构建失败。 ## 风险模型摘要 Faultline 报告标准化的 0-100 组件分数和加权总分: ``` risk_score = churn_score * 0.25 + coverage_gap_score * 0.20 + complexity_score * 0.20 + ownership_entropy_score * 0.20 + dependency_centrality_score * 0.15 ``` 每个包都包括评分证据。发现包括类别、严重性、证据、建议和置信度。 边界发现是策略发现,目前不纳入数字风险评分中。使用 `--fail-on high` 可使未抑制的边界违规导致 CI 失败。 依赖项发现也与数字包风险评分分开。它们是来自 `go.mod`、`go.sum` 和加载的导入图的结构性模块治理信号: - `FL-DEP-002`:存在本地 `replace` 指令。 - `FL-DEP-003`:模块被替换为不同的模块路径。 - `FL-DEP-004`:直接依赖项似乎未使用,尽力而为。 - `FL-DEP-005`:依赖项具有广泛的导入影响范围。 - `FL-DEP-006`:依赖项版本是 Go 伪版本。 - `FL-DEP-007`:本地 replace 指向同一仓库中的另一个模块。 Faultline 依赖项风险不是 CVE 扫描。仅当您希望包含可选的外部漏洞工具输出时,才使用 `--govulncheck auto` 或固定的 `--govulncheck /path/to/govulncheck`。 ## 隐私与安全 源代码和扫描数据保留在本地环境中。Faultline 仅调用只读的 git 命令进行历史分析,并读取本地 Go 模块文件进行依赖项清单构建。默认扫描不调用模块代理、漏洞数据库或远程服务。本地历史存储指标和发现元数据,而不存储源代码。缺少 git、浅克隆、缺少覆盖率、不可用的历史存储以及不可用的可选 `govulncheck` 会降级为警告,而不是导致扫描失败。 ## GitHub Action 在 CI 中运行 Faultline 的最简单方法: ``` name: Faultline on: pull_request: push: branches: [main] permissions: contents: read pull-requests: write security-events: write jobs: faultline: runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 with: fetch-depth: 0 - uses: faultline-go/action@v1 ``` 请参阅 [github.com/faultline-go/action](https://github.com/faultline-go/action) 以获取所有选项,包括企业版快照上传、覆盖率集成和架构边界强化。 ## Docker GitHub Action ``` name: faultline-container on: [pull_request] jobs: scan: runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 with: fetch-depth: 0 - run: | docker run --rm \ -v "$PWD:/workspace" \ -w /workspace \ ghcr.io/faultline-go/faultline:latest \ scan ./... --format json --out faultline-report.json --fail-on high - uses: actions/upload-artifact@v7 if: always() with: name: faultline-report path: faultline-report.json ``` ## GitHub 代码扫描 SARIF ``` name: Faultline SARIF on: pull_request: push: branches: [main] jobs: faultline: runs-on: ubuntu-latest permissions: security-events: write contents: read steps: - uses: actions/checkout@v6 with: fetch-depth: 0 - uses: actions/setup-go@v6 with: go-version: stable - run: go test ./... -coverprofile=coverage.out - run: faultline scan ./... --coverage coverage.out --format sarif --out faultline.sarif - uses: github/codeql-action/upload-sarif@v3 with: sarif_file: faultline.sarif ``` ## 拉取请求风险审查 `faultline pr review` 将已更改的 Go 包和受影响的一跳包与配置的基准引用进行比较,并以本地历史作为回退。它呈现一个简洁的 markdown 审查,包含已更改的包、受影响的包、新的未抑制发现、已解决的发现、最差的风险增量和审查者指导。 该命令使用 `git diff --name-only ...`,并且可以在没有 GitHub 环境变量的情况下运行: ``` faultline pr review --base origin/main --head HEAD --compare-mode auto --comment-out faultline-pr-review.md ``` 您还可以在不签出的情况下比较任意引用: ``` faultline pr review --base origin/main --head feature/foo --compare-mode worktree --comment-out review.md ``` 比较模式: - `--compare-mode auto`:默认。对可用的引用使用临时分离的 git worktree,然后回退到本地历史进行基准比较并发出警告。 - `--compare-mode worktree`:需要基准引用 worktree 比较。如果无法扫描基准引用,命令将以代码 `2` 退出。 - `--compare-mode history`:使用最近的本地 `.faultline/faultline.db` 扫描历史来获取增量和先前的发现。 如果省略 `--head` 或解析为调用者的当前 `HEAD`,Faultline 将扫描调用者的 worktree。如果 `--head` 是显式的不同引用或 SHA,Faultline 将为该 head 引用创建第二个分离的 worktree。无效的显式 head 引用以代码 `2` 退出;它们不会静默降级为调用者的 `HEAD`。 Worktree 比较从不签出、重置或删除调用者的工作树。Faultline 运行: ``` git worktree add --detach git worktree remove --force ``` 临时的基准/head 扫描不会持久化到调用者的 `.faultline/faultline.db` 中。 要仅为新的未抑制 PR 发现生成内联 GitHub 代码扫描注释,请编写 PR SARIF 并从工作流上传它: ``` faultline pr review --base origin/main --head feature/foo --compare-mode worktree --sarif-out faultline-pr.sarif --comment-out review.md ``` 当使用 `--sarif-out` 时,markdown 审查会指出可以通过上传的 SARIF 获得内联注释。Faultline 在本地编写 SARIF 文件,但它本身不上传 SARIF。 当提供 `--post` 时,Faultline 使用 `GITHUB_TOKEN`、仓库和 PR 号上下文来更新插入标记有 `` 的单个评论。如果发布失败或没有可用的 token,本地 markdown 生成仍然有效。 凭借企业版凭证,PR 审查还会为已审查的 head 修订版上传无源代码的 `faultline.snapshot.v1` 快照: ``` faultline pr review \ --compare-mode auto \ --enterprise-url https://api.gofaultline.dev \ --enterprise-token "$FAULTLINE_API_TOKEN" \ --enterprise-org-id "$FAULTLINE_ORG_ID" ``` GitHub Actions 应使用 `fetch-depth: 0`,以便 `origin/main` 或检测到的基准分支在本地存在。对于浅签出或缺少基准引用的情况,`auto` 模式会回退到历史记录并在评论中报告回退原因。 示例工作流: ``` name: Faultline PR Review on: pull_request: jobs: faultline: runs-on: ubuntu-latest permissions: security-events: write pull-requests: write contents: read steps: - uses: actions/checkout@v6 with: fetch-depth: 0 - uses: actions/setup-go@v6 with: go-version: stable - run: go install github.com/faultline-go/faultline/cmd/faultline@latest - run: faultline pr review --compare-mode auto --sarif-out faultline-pr.sarif --comment-out review.md --post --fail-on high env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - uses: github/codeql-action/upload-sarif@v3 if: always() with: sarif_file: faultline-pr.sarif - uses: actions/upload-artifact@v7 if: always() with: name: faultline-pr-review path: | review.md faultline-pr.sarif ``` ## 当前限制 - 分数是启发式和方向性的,而不是缺陷的证据。 - 边界策略支持包导入路径和目录 glob 检查,但它们尚未对完整的架构层进行建模。 - 依赖项风险是结构性的且仅限本地;它不能替代漏洞管理。 - 抑制作为即将过期的豁免实施;它们不会从报告中删除发现。 - CODEOWNERS 匹配是近似的。 - 生成的代码被单独计算,并且默认情况下从 LOC 复杂度中排除,但重度生成代码的包仍然需要人工解释。 - GitHub App 安装已在路线图中。托管的企业版上传可通过 CLI 标志 `faultline-go/action@v1` 获得,而 OSS 扫描器有意保持本地优先和无源代码。 ## 治理说明 抑制应该具有所有者、原因、创建日期和有效期。Faultline 强制执行解析后的 `suppression_policy`,对不完整或过长的豁免条目发出警告,忽略过期的抑制,并保留被抑制的发现以供审查。对于企业级 CI,请保持启用 `require_owner`、`require_reason` 和 `require_expiry`,并将 `max_days` 设置为您的治理流程允许的最大豁免期限。
标签:DevSecOps, EVTX分析, GitHub代码扫描, Git历史分析, Go语言, SARIF, WebSocket, 上游代理, 云安全监控, 代码分析, 代码审查, 代码覆盖率, 依赖分析, 凭证管理, 技术债务, 数据管道, 日志审计, 本地优先, 架构治理, 程序破解, 结构风险分析, 请求拦截, 软件工程, 静态分析, 风险扫描