开源许可证合规

本页提供:license-checker/FOSSA 命令行扫描示例、MIT/Apache/GPL/LGPL 许可证兼容性矩阵表、自动生成 NOTICE 文件的命令、CI 中阻断 GPL 库的配置,以及 SPDX JSON 包片段实验室。

SKILL 内置组织级「允许 / 需法务评审 / 禁止」许可证表,并要求扫描结果与 lockfile 一致;对 UNKNOWN 或双重许可需人工确认。分发二进制或 SaaS 时对源码提供、版权声明与 NOTICE 聚合的要求不同,Agent 应区分交付形态并列出需随包附带的文件清单。

扫描工具命令与 CI 阻断配置

license-checker / FOSSA 命令行扫描

# license-checker(Node.js 项目)
npx license-checker --production \
  --onlyAllow 'MIT;Apache-2.0;BSD-2-Clause;BSD-3-Clause;ISC;CC0-1.0' \
  --excludePackages 'myapp@1.0.0' \
  --json > license-report.json

# 列出所有许可证(含依赖树)
npx license-checker --production --csv > licenses.csv

# FOSSA CLI 扫描(需要 FOSSA_API_KEY)
fossa analyze --branch main
fossa test --timeout 600  # 非零退出表示策略不合规

# Python 项目 — pip-licenses
pip install pip-licenses
pip-licenses --format=json \
  --with-urls \
  --with-authors \
  --output-file=licenses.json

# 自动生成 NOTICE 文件
npx license-checker --production \
  --customFormat='{"name":"","version":"","licenses":"","copyright":""}' \
  --out NOTICE \
  --customPath notice-template.json

CI 中阻断 GPL 库(GitHub Actions)

# .github/workflows/license-check.yml
name: License Compliance
on: [pull_request]
jobs:
  check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with: { node-version: '20' }
      - run: npm ci --production
      - name: Check licenses (deny GPL)
        run: |
          npx license-checker --production \
            --onlyAllow 'MIT;Apache-2.0;BSD-2-Clause;BSD-3-Clause;ISC;CC0-1.0;Unlicense' \
            --excludePackages 'approved-exception@1.0.0' || \
            (echo "::error::发现不允许的许可证,请检查 license-report.json" && exit 1)
      - name: Upload report
        uses: actions/upload-artifact@v4
        with:
          name: license-report
          path: license-report.json

合规主流程(lockfile → 扫描 → SBOM)

  [ lockfile / 构建图 与 组织允许表 对齐 ]
        │
        ▼
  ┌─────────────┐     解析 SPDX License Expression;标记 UNKNOWN / OR / AND
  │  依赖扫描    │──── 冲突:copyleft × 闭源分发、专利授予、附加义务
  └─────────────┘
        │
        ▼
  ┌─────────────┐     CycloneDX / SPDX JSON:每组件 licenseDeclared / concluded
  │  SBOM 产出   │──── 版本漂移时 diff 许可证字段 → 触发合规复查工单
  └─────────────┘
        │
        ▼
  ┌─────────────┐     NOTICE / 源码义务 / UI 致谢;例外登记与到期日
  │ 分发与文档  │──── 非法律意见 → 重大风险升级法务
  └─────────────┘

流程要点:扫描器声明的 SPDX ID 与包元数据不一致时,以可追溯证据(官方 LICENSE 文件、SPDX 文档)为准,并在 SBOM 中保留 NOASSERTION 或注释说明直至闭环。

许可证兼容性矩阵

常见许可证在不同分发场景下的使用限制(非法律意见,重大决策转法务确认):

许可证 商业闭源使用 静态链接分发 SaaS(不分发二进制) 主要要求
MIT 保留版权声明与许可证文本
Apache-2.0 NOTICE 文件随包;专利授予(双向)
LGPL-2.1 ⚠️ ⚠️ 需动态链接或提供目标文件 允许闭源应用动态链接;修改 LGPL 库本身需开源
GPL-3.0 ❌ 需法务评审 ❌ 要求整个程序 GPL ⚠️ AGPL-3.0 更严(网络服务也触发) Copyleft 感染;分发须开放全部源码
  • NOASSERTION:元数据缺失且未人工确认前用于 SBOM 字段占位。
  • 扫描器输出的 UNKNOWN 必须进入评审队列,不得静默映射为允许。

SBOM 中的许可证字段与复查

CycloneDX 的 licenses、SPDX JSON 的 licenseDeclared / licenseConcluded 应与 CI 扫描及 lockfile 同源;合并 PR 时对比上一版 SBOM 的许可证集合差异。

建议自动化

  • 每次发布产物附带 SPDX 或 CycloneDX,与镜像 / 制品 digest 绑定。
  • 许可证变更打标签或阻塞合流(按组织策略)。
  • 将 SBOM 导入漏洞与许可证仪表板,统一 UNKNOWN 工单。

人工 / Agent 核对

  • 双重许可下实际选用的条款与分发方式是否一致。
  • 传递依赖升级引入的 copyleft 是否在允许表内。
  • 例外批准记录、复审日期与责任人。

允许清单、分发形态与 NOTICE

静态链接、动态链接、容器分发与纯 SaaS 对「源码提供」「版权声明」的要求不同;SKILL 应要求 Agent 按交付形态列出需随包文件(LICENSE、NOTICE、第三方列表)。

组织级允许表应版本化并与流水线门禁一致;例外须带 ticket、批准人与复审日期。UI「关于 / 开放源代码许可」页应与 SBOM 或构建时生成的致谢文件同源生成,避免手抄漂移。

SPDX JSON 包片段实验室

填写组件坐标与 SPDX 许可证表达式,生成可合并进 SPDX 2.3 JSON SBOM 的单个 packages[] 元素示意(需按你方 SPDXID 命名空间与关系边补全)。

可选字段

此为示意片段;完整 SBOM 还需 spdxVersiondataLicenseSPDXID 文档根、relationships 等。CycloneDX 用户可将许可证信息映射到 components[].licenses

---
name: license-compliance-cn
description: 扫描依赖许可证,核对兼容性矩阵,自动生成 NOTICE,在 CI 中阻断 GPL 库
---
# 步骤
1. 运行 license-checker --production --onlyAllow 'MIT;Apache-2.0;BSD-*;ISC'
2. 检查输出:UNKNOWN 和 GPL 类需人工评审,进入工单队列
3. 查对兼容性矩阵:静态链接 vs 动态链接 vs SaaS 三种分发形态的要求不同
4. 生成 NOTICE 文件:license-checker --customFormat + 模板输出
5. 生成 SBOM 中的 licenseDeclared 字段:与 lockfile 同源,不手工填写
6. CI 阻断:GitHub Actions 中 --onlyAllow 不通过则非零退出阻塞 PR 合并
7. FOSSA 集成(可选):fossa analyze + fossa test --timeout 600
8. 双重许可(OR):选择对业务最有利的条款并记录在工单中
9. Apache-2.0:确保 NOTICE 文件随包分发;注意专利授予条款
10. LGPL:确认是否动态链接;静态链接需法务确认
11. GPL 例外申请:附 ticket、批准人、到期复审日期
12. UI「开放源代码许可」页:从 SBOM 自动生成,不手工维护

# 禁止
- 禁止将 UNKNOWN 静默映射为允许
- 禁止将 GPL/AGPL 库与闭源代码静态链接未经法务评审
- 非法律意见:重大决策转交法务确认

返回技能库 更多技能入口