一套企业门户准备交付,安装包里带了一个前端图表库、一个 PDF 导出组件,还有一个从 GitHub 上拷来的工具类。上线前,客户法务发来邮件,要求提供这几个组件的许可证清单、版权声明和源码获取方式。项目经理打开 package.json 才发现,其中一个组件是 GPL,另一个是 AGPL,平时只看了 star 数,没人看过 LICENSE 文件。
这种事在定制开发里并不少见。开源组件用起来太方便,npm、pip、Maven 一条命令就拉下来,代码能跑、页面能显示,很少有人会在提交前追问一句,这个许可证允不允许我们这样交付。等到客户要源码、要投标、要做安全审计,问题才浮出来。
一、开源不等于免费,先分清许可证

开源许可证是有条件的著作权许可,免费下载只是表面。大多数 OSI 认可的开源许可证允许商业使用,也允许修改和再分发,前提是遵守它的条件。条件通常落在几件事上,保留版权声明和许可证文本,说明修改过哪些文件,分发时提供对应源码,或者要求衍生作品继续使用同一许可证。
许可证大致分四类。MIT、BSD、Apache 2.0 属于宽松型,商用限制少,保留声明即可,Apache 2.0 还带专利授权和专利报复条款。LGPL、MPL 属于弱传染型,修改库本身或者静态链接时要履行开放义务,动态调用和文件级隔离的边界要看具体用法。GPL、AGPL 属于强传染型,分发衍生作品时要求把对应源码一起开放。SSPL、BUSL、CC-BY-NC 这类许可证更接近源码可见或非商业授权,不能按开源来理解。
商用本身通常不是问题,分发才是触发器。把安装包发给客户,把 Docker 镜像推到客户服务器,把 APP 上架应用商店,把前端 bundle 部署到公网,这些动作都可能构成分发。只在公司内部跑、不对外提供,GPL 一般不触发,但 AGPL 通过网络提供服务时另有要求。很多团队把开发费和服务费分开算,就以为自己没卖软件,法律上看的是有没有把受许可证覆盖的代码交给别人使用。
还有一个容易漏掉的对象是模型权重和数据集。现在不少项目会拉一个开源模型做知识库问答或者图片处理,Llama、GLM 这类模型往往附带自定义许可证,商用条件、用户规模、署名要求各不相同。把它们当成普通 npm 包处理,只记录一个下载地址,交付时很难说清楚授权边界。
许可证文本要看的不是标题,是义务条款。有的许可证要求保留作者署名,有的要求公开修改文件,有的对网络服务单独设条件,有的禁止拿作者商标做宣传。把这些条件拆出来,做成一张内部对照表,研发在选组件时就能看见成本,而不是等法务在交付前才发现。
二、GPL/AGPL 会传染,商用闭源要当心

GPL 允许商用,真正的约束落在同一作品及其衍生作品的开放义务上。判断重点是有没有构成衍生作品,链接、合并、修改、打包都可能影响结论。静态链接、把代码编进同一个二进制、在同一个进程里调用,风险通常更高。动态链接和独立进程调用常被拿来做隔离,但这不是万能挡箭牌,具体要看两边是不是结成一个整体。
AGPL 比 GPL 多了一层网络服务条款。修改过的 AGPL 程序,如果让用户通过网络访问,就要向这些用户提供对应源码。SaaS 项目最容易在这里踩坑,代码没有交付给客户,服务却在客户的浏览器里跑着。有人把 AGPL 组件放在后端接口里,以为不发行客户端就没事,审计时照样会被追问源码。
LGPL 和 MPL 看起来温和一些,义务并没有消失。LGPL 允许商业软件动态链接,但修改 LGPL 库本身仍要开放修改部分,静态链接通常要求提供目标文件或源码。MPL 是文件级传染,改了哪个文件就开放哪个文件,其他文件可以保持原样。Apache 2.0 宽松,不等于可以删掉 NOTICE 文件,也不等于专利风险自动清零。
许可证之间还有兼容性问题。Apache 2.0 的代码并入 GPLv2 项目,可能产生冲突,MIT 代码并入 GPL 项目通常没问题,GPLv2 和 GPLv3 混用也要看具体条款。前端项目尤其容易忽略这一点,打包后的 bundle 里混着十几份许可证,构建工具只负责压缩,不负责帮你判断兼容性。
国内法院在 GPL 纠纷里,已经把开源许可证按著作权合同来对待。违反许可证条件,许可可能终止,继续使用就从合规使用变成侵权使用。它不是行业倡议,也不是社区道德,是可以被起诉的合同条款。把 LICENSE 文件删掉、把包名改掉、把版权头注释掉,都不会让义务消失。
常见的自我安慰还有几种。比如把 GPL 组件放在单独的目录里,就认为没有链接。比如只在前端引用一个 CDN 地址,就认为没有分发。比如把代码转译、压缩、混淆,就认为别人看不出来。这些做法在技术上有时候能降低风险,在法律上都不能自动免责,具体要看使用方式和许可证文本。
三、交付前做组件清单和许可证扫描

靠人记不住依赖树。一个中等规模的项目,直接依赖几十个,间接依赖几百个,前端、后端、移动端、构建工具各有一摊。交付前至少要生成一份组件清单,写清组件名、版本、来源、许可证、是否修改、以什么方式使用。能输出 SPDX 或 CycloneDX 格式更好,客户和审计方都认。
扫描工具可以帮上忙。npm 用 npm ls,Python 用 pipdeptree,Maven 用 dependency:tree,Gradle 用 dependencies,Go 用 go mod graph,Rust 用 cargo tree。许可证扫描可以用 ScanCode、FOSSA、Black Duck、ORT,CI 里加一道门禁,出现 GPL、AGPL 或者未知许可证就拦住。工具会漏掉手工拷贝的代码、压缩过的第三方脚本、从博客里复制的片段,所以还要有人工复核。
清单之外,还要准备许可证文本、版权声明、NOTICE 文件、源码获取方式。GPL 交付时,源码要包括构建和安装所需的脚本,不能只给一个 GitHub 链接就完事。前端 bundle 里被压缩掉的注释,可能正好是版权声明,构建配置要保留 license banner。Docker 镜像里也要能追溯到基础镜像和系统包,别只扫业务代码。
扫描结果不是一张绿表就结束了。未知许可证要人工判断,双许可证要选清楚用哪一种,自定义许可证要逐条读。工具标成低风险,不代表可以商用,也不代表可以在网络服务里使用。把每个组件的使用方式写进清单,静态链接、动态链接、修改、分发、SaaS,这几种状态对应的义务不一样。
供应商交付也要管。让对方提供 SBOM、许可证清单、第三方素材授权、开源使用说明,合同里写清许可证不合规时的整改、替换、赔偿和配合义务。只写一句乙方保证原创,遇到 GPL 组件时没有可执行的办法。招标文件里要求自主知识产权时,先确认自己的组件清单撑不撑得住这句话。
验收清单可以加几项。开源组件清单有没有,许可证文本全不全,源码获取方式写没写,SBOM 能不能打开,第三方素材授权有没有,扫描报告和人工复核记录在不在。把这些东西随交付物归档,后面客户换开发方、做安全审计、申报项目,都能拿得出来。
四、已经用了怎么办,替换、隔离还是开源

发现用了 GPL 或 AGPL 组件,先别急着删 LICENSE 文件。第一步是停下来评估,涉及哪些产品、哪些交付物、哪些客户、有没有已经分发。把组件版本、修改记录、链接方式、分发路径整理出来,再让法务和研发一起判断风险等级。已经发出去的安装包和镜像,不会因为本地删了依赖就消失。
处理路径通常有四条。能替换就替换,找 MIT、Apache 2.0 的同类库,改造成本可能比打官司低。能拿到商业授权就谈商业授权,有些开源项目背后有商业公司,双许可证是常见模式。确实离不开,就把受覆盖的部分单独开源,或者把组件拆成独立服务,确保不构成衍生作品。剩下一条是清场重写,成本最高,适合核心产品。
隔离不是把组件扔进另一个进程就结束了。还要看接口、数据格式、调用关系、部署方式,审计时会不会被认定为一个整体。把 GPL 组件做成独立微服务,通过 HTTP 调用,通常比静态链接安全,但也不是自动免责。真要走到这一步,让律师看具体的许可证文本和架构图,别让研发自己拍板。
开源合规要进研发流程,不能只靠交付前临时补材料。建立组件白名单,新依赖上线前审批,CI 自动扫描,交付前生成 SBOM,许可证文本和源码包随交付物归档。培训研发看 LICENSE 文件,比出事后再补救便宜。公司内部还要区分个人账号和企业账号,别让员工用个人 GitHub 账号拉一个来路不明的库,结果变成公司的交付物。
合同里的写法也要改。供应商保证其交付物使用的开源组件符合许可证要求,提供完整清单和许可证文本,出现第三方索赔时负责抗辩和赔偿,客户要求时配合提供源码和整改方案。自己对外承诺时,别轻易写完全自主知识产权、保证不侵权,先把组件清单和许可证审一遍,再决定这句话能不能说。
在线
电话
微信
需求
TOP