go mod 无法规避许可证风险,因其不识别、不拦截、不警告许可证信息;真正有效的合规须在依赖引入前通过 go-licenses 扫描、白名单机制及 ci 拦截实现。

不能靠 go mod 自动规避许可证 —— 它不检查、不拦截、不警告,只管下载和构建。 你得在依赖引入前就做判断,否则等代码跑起来再发现用了 GPL 库,可能已埋下分发风险。
go mod 本身不识别许可证类型
go mod 的所有命令(go mod tidy、go get、go list -m all)都完全忽略许可证字段。它只读 go.mod 和 go.sum,而这两个文件里根本没存许可证信息。即使某个依赖的 go.mod 文件里写了 // License: GPL-3.0,go mod 也视而不见。
- 许可证信息通常藏在依赖仓库根目录的
LICENSE、LICENSE.md或COPYING文件里,go mod不扫描这些 -
go list -m -json all输出里只有Version、Indirect等字段,没有License - 所以指望
go mod verify或go mod download拦住 GPL 依赖,纯属误解
真正有效的许可证过滤必须发生在依赖引入之前
关键不是“怎么让 go mod 拒绝 GPL”,而是“怎么在 go get 执行前就知道它要拉什么、带什么许可证”。
- 先用
go-licenses csv .扫当前项目已有依赖,但这是事后检查 —— 适合 CI 拦截,不适合开发时预防 - 想提前预判,得对目标模块单独查:运行
go list -m -json github.com/some/lib@v1.2.3,再手动去它的 GitHub/GitLab 仓库看 LICENSE 文件 - 更可靠的做法是建立组织级白名单:
go-licenses支持--include和--exclude参数,但仅用于报告生成,不能阻止go get - 若需硬性拦截,必须在 CI 中加校验脚本:解析
go list -m all输出 → 对每个模块调用go-licenses csv→ 匹配黑名单(如GPL-3.0、AGPL-3.0)→ 非零退出
replace 和 indirect 依赖照样受许可证约束
有人以为用 replace 把 GPL 库替换成 MIT 版本就能绕开,或觉得 indirect 依赖“不算我主动引入”就没事 —— 这两种想法都错。
-
replace只改路径,不改法律义务:如果你replace github.com/x/y => ./forked-y,而forked-y仍基于 GPL 原版修改,那整个衍生作品仍受 GPL 约束 -
indirect依赖在go.mod里显式列出,go-licenses csv .会完整扫描它,且 GPL 的传染性不因“间接”而减弱 - Go 没有“依赖隔离”机制:只要二进制链接了 GPL 代码(哪怕只调一个函数),GPL-3.0 就可能要求你开源全部衍生作品
- 别依赖
go mod graph看调用链来“评估影响范围”—— 法律上只看是否链接,不看调了多少行
许可证合规不是技术开关,而是法律事实。go mod 能帮你精准控制版本和路径,但它不提供法律层抽象。最容易被忽略的点是:你本地 go run 成功,不代表你有权把构建产物打包分发出去 —— 那一刻才真正触发许可证条款。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











