Go项目混入GPL库会导致整个二进制受传染性条款约束,必须用go-licenses工具实锤验证许可证;它递归解析go.mod所有依赖,准确提取许可证类型,支持CSV报告和许可证文件归档,CI中需强制拦截GPL/AGPL/SSPL等违规项。

Go 项目里混入 GPL 库,哪怕只用了一个函数,也可能让整个二进制分发受传染性条款约束。这事不能靠“我觉得没用到核心代码”来免责,得靠工具链实锤验证。
go-licenses 是当前最可靠的许可证提取工具
它能递归解析 go.mod 中所有直接和间接依赖,并准确抓取每个模块声明的许可证类型(不是靠猜或文件名匹配)。其他方式如 go list -m all 只输出路径和版本,不带许可证字段;go list -m -json all 里的 License 字段多数为空,不可信。
- 安装命令必须用最新版:
go install github.com/google/go-licenses@latest - 导出 CSV 报告最实用:
go-licenses csv .,结果含package、license-type、license-file-path三列,可直接导入 Excel 筛选 GPL 或 AGPL - 导出完整许可证文件到目录:
go-licenses save . --save_path=third_party_licenses,用于审计归档,注意该命令会复制原始 LICENSE 文件,不是生成摘要 - 若某模块没附 LICENSE 文件,
go-licenses会跳过它,不会报错——这意味着你得人工查 pkg.go.dev 页面确认其声明的许可证
别忽略间接依赖里的许可证冲突
一个 github.com/gin-gonic/gin(MIT)可能依赖 golang.org/x/crypto(BSD),看起来安全;但若它又通过某个 fork 的 github.com/xxx/encoding 拉入了 GPLv3 的补丁,整条链就失效了。这种传递链在 go.mod 里不显眼,却决定合规底线。
- 用
go mod graph | grep "your-suspicious-package"查清谁引入了可疑模块 -
go list -m -f '{{.Path}} {{.Version}} {{.Indirect}}' all能标出所有间接依赖,配合grep快速定位非直接引用的 GPL 包 - 对
Indirect=true的模块,别假设“我没调用它就没事”——只要它被编译进最终二进制,GPL 条款就可能适用
CI 中必须卡死禁止许可证白名单
光生成报告没用,得让构建失败来强制拦截。GitHub Actions 或 GitLab CI 里加一行检查,比开会强调十次都管用。
- 写个简单脚本解析
go-licenses csv .输出,用grep -i "gpl\|agpl\|sspl"扫描违规项,命中即exit 1 - 避免用
go-licenses json .——它的 JSON schema 不稳定,不同版本字段名可能变,CSV 更可靠 - 把白名单写死在 CI 脚本里,比如只允许
MITE、Apache-2.0、BSD-3-Clause,其他一律拒绝 - 注意:某些模块声明为
MIT OR Apache-2.0,这种双许可是安全的;但声明为GPL-2.0-only就必须剔除
真正麻烦的不是找到 GPL 包,而是发现它被三个不同间接依赖层层嵌套引入,且替换成本高。这时候别硬删,先用 replace 指向已修复的分支,再推动上游合并——许可证问题从来不是单点技术问题,而是依赖链上的协作节点。

















