2026-04-22 · architecture / opensource
【开源许可与版权工程】闭源项目如何选择开源依赖:公司内部合规实操
面向做闭源/商业产品的团队:逐一拆解 MIT、LGPL、GPL、AGPL、SSPL、BSL 在 SaaS、私有化部署、移动 App、嵌入式固件等形态下的许可边界,给出三级名单模板、CI 扫描配置、SBOM 存证方案与出海补充要求。






















“MIT 是最宽松的许可证”——这句话在 Stack Overflow 上被复制了几十万遍,也误导了几十万工程师。
真正的问题不是”最宽松”,而是宽松到什么程度、严格到什么程度、以及在哪个维度上宽松。MIT 要求保留版权声明,Apache-2.0 额外要求传递专利授权,GPL-3.0 要求所有分发出去的二进制必须附带源码,AGPL-3.0 连通过网络提供服务都算”分发”,SSPL-1.0 甚至要求你把整个运维栈(数据库管理面板、备份工具、日志系统)都一起开源。
这是一个四维坐标系,不是一条线。
本文把开源许可证按”Copyleft 强度”分成四类——宽松(Permissive)、弱 Copyleft(Weak Copyleft)、强 Copyleft(Strong Copyleft)、网络 Copyleft(Network Copyleft),然后逐个拆解它们的条款、SPDX 标识符(Software Package Data Exchange ID)、OSI 认证状态(Open Source Initiative approval)、兼容性矩阵和工程选型。
在阅读本文之前,如果你还不清楚”开源”这个概念本身的工程含义,建议先读开源全景:从 Freedom 0 到供应链;如果你对中国法语境下的”软件著作权”和开源许可证的交叉还不熟悉,可以先看中国法下的软件著作权与开源。
市面上被 OSI 认证的许可证有 100 多个,FSF(Free Software
Foundation)的名单更长。把它们按字母排列没有任何工程意义——Apache-2.0
和 AGPL-3.0
只差一个字母,但前者是宽松许可证,后者是网络
Copyleft,两者在合规约束上几乎处在光谱两端。
真正有意义的分类维度是 Copyleft 强度:“接收方在什么情况下必须把源码放出来”。Copyleft 这个词是 Richard Stallman 在 1985 年发明的,字面是 “copyright” 的反义双关——版权(copyright)用来限制再分发,而 Copyleft 用来要求再分发时不得施加更严的限制。
按触发条件的宽松到严格,有四个台阶:
| 层次 | 触发条件 | 典型许可证 |
|---|---|---|
| 宽松 | 只要求保留版权和许可证声明 | MIT、BSD-3-Clause、Apache-2.0 |
| 弱 Copyleft | 修改原文件/原库时触发,链接使用不触发 | LGPL-2.1/3.0、MPL-2.0、EPL-2.0 |
| 强 Copyleft | 分发(distribute)整个作品时触发 | GPL-2.0、GPL-3.0 |
| 网络 Copyleft | 通过网络提供服务也算”分发” | AGPL-3.0、SSPL-1.0(非 OSI) |
这四类不是连续的——它们之间有质变。从宽松到弱 Copyleft 的跨越是”我改了你的代码要交回来”;从弱到强是”我只是链接你也要交回来”;从强到网络是”我没分发二进制但在网上提供服务也要交回来”。每一级都会显著影响你的商业模式。
宽松(Permissive)——本质上是一个”版权声明保留”的承诺:
MIT)BSD-2-Clause)BSD-3-Clause)Apache-2.0)ISC)Unlicense)——公共领域贡献弱 Copyleft(Weak Copyleft)——文件/库级别的 Copyleft:
LGPL-2.1-only /
LGPL-2.1-or-later)LGPL-3.0-only /
LGPL-3.0-or-later)MPL-2.0)EPL-2.0)EUPL-1.2,也可视为强
Copyleft,取决于视角)CDDL-1.0)强 Copyleft(Strong Copyleft)——整个作品级别的 Copyleft:
GPL-2.0-only)GPL-2.0-or-later)GPL-3.0-only)GPL-3.0-or-later)网络 Copyleft(Network Copyleft)——把网络服务也纳入触发条件:
AGPL-3.0-only /
AGPL-3.0-or-later),OSI 认证SSPL-1.0),OSI 未认证BUSL-1.1),OSI
未认证,严格说不算开源注意:SSPL、BSL、Commons Clause 在社区讨论中经常被称为”source-available”(可见源)而不是 “open source”(开源)。这个区分不是文字游戏——它直接决定一个许可证能不能写进 Red Hat、Debian、Fedora 等发行版的仓库。
宽松 ──────── 弱 Copyleft ──────── 强 Copyleft ──────── 网络 Copyleft ──── 非开源
│ │ │ │ │
MIT LGPL GPL AGPL SSPL
BSD-3 MPL-2.0 GPL-2.0 AGPL-3.0 BSL-1.1
Apache-2.0 EPL-2.0 GPL-3.0 CC BY-NC
ISC CDDL Commons Clause
从左到右,你对下游的约束递增、你的商业模式越窄;但从左到右,你反制”搭便车”的能力也递增。
在进入后面章节之前,先把本文的关键术语统一一下——这几个词在不同文献里口径不完全一致:
| 术语 | 本文口径 |
|---|---|
| 开源(Open Source) | 通过 OSI 认证、符合 OSD 十条的许可证 |
| 自由软件(Free Software) | FSF 的四项自由(Freedom 0-3) |
| Copyleft | 要求衍生作品以同样/兼容许可证分发的机制 |
| Permissive | 仅要求保留版权声明的宽松机制 |
| Source-available | 源码可见但不符合 OSD 的许可证(SSPL、BSL、RSAL) |
| 分发(Distribute) | 把二进制或源码交付给组织外部的行为 |
| Convey | GPL-3.0 里对 “distribute” 的更精确替代术语 |
| 衍生作品(Derivative Work) | 版权法意义上基于原作品创作的新作品 |
| 集合作品(Collective Work) | 多个独立作品组合成一个整体,但各自保留原许可证 |
SPDX(Software Package Data Exchange)是 Linux Foundation 孵化、后被 ISO 采纳的软件元数据标准。2021 年 9 月,SPDX 2.2 被采纳为 ISO/IEC 5962:2021,成为全球第一个被 ISO 收录的 SBOM(Software Bill of Materials,软件物料清单)格式。截至本文写作时,业内主流版本是 SPDX 2.3,SPDX 3.0 已经发布但工具链仍在迁移。
SPDX 最核心的产出之一,是每个许可证被分配的唯一标识符(SPDX License Identifier)。这个标识符的设计原则:
Apache-2.0 不等于
apache-2.0
在语义上相同,但规范形式是前者)+ 和 WITH
组合表达版本范围和例外一句话:合规扫描工具只认 SPDX。
现在几乎所有 SBOM
生成工具(Syft、Trivy、ORT、FOSSology、ScanCode)、SCA(Software
Composition Analysis,软件成分分析)平台(Black
Duck、Snyk、Mend)、以及包管理器(cargo、npm、go mod、maven)的
license 元字段都是按 SPDX 标识符识别的。
在源代码头部推荐使用 SPDX 单行注释:
// SPDX-License-Identifier: Apache-2.0
// Copyright 2026 Example Corp.# SPDX-License-Identifier: MIT
# Copyright (c) 2026 Example Corp.// SPDX-License-Identifier: Apache-2.0 OR MIT
// 双许可:下游可以任选其一Linux 内核从 2017
年开始强制要求每个新增文件的第一行必须包含
SPDX-License-Identifier,不符合会被
checkpatch.pl 告警。这背后的动因之一,是 2016
年前后内核代码里发现了几十个许可证标注不明、需要手工考古才能判定的文件,合规团队压力巨大。
SPDX 标识符不只是字符串,还是一套小型表达式语言:
MIT 单个许可证
Apache-2.0 OR MIT 双许可,下游可任选
(GPL-2.0-only AND BSD-3-Clause) 组合作品同时受两个许可证约束
GPL-2.0-or-later WITH Classpath-exception-2.0 带例外条款
LGPL-2.1-or-later 2.1 及更高版本
其中 WITH
用于加载许可证例外(license
exception),典型的是 GCC Runtime Library 使用的
GCC-exception-3.1 和 OpenJDK 使用的
Classpath-exception-2.0——这是 GPL
族能够被用于标准库而不”感染”应用程序的关键机制。
| 常用名 | SPDX 标识符 | OSI 认证 | FSF Free |
|---|---|---|---|
| MIT | MIT |
是 | 是 |
| BSD 2-Clause | BSD-2-Clause |
是 | 是 |
| BSD 3-Clause | BSD-3-Clause |
是 | 是 |
| Apache 2.0 | Apache-2.0 |
是 | 是 |
| ISC | ISC |
是 | 是 |
| Unlicense | Unlicense |
是 | 是 |
| CC0 1.0 | CC0-1.0 |
否(2012 OSI 拒绝) | 是 |
| LGPL 2.1 | LGPL-2.1-only /
LGPL-2.1-or-later |
是 | 是 |
| LGPL 3.0 | LGPL-3.0-only /
LGPL-3.0-or-later |
是 | 是 |
| MPL 2.0 | MPL-2.0 |
是 | 是 |
| EPL 2.0 | EPL-2.0 |
是 | 是 |
| CDDL 1.0 | CDDL-1.0 |
是 | 是 |
| EUPL 1.2 | EUPL-1.2 |
是 | 是 |
| GPL 2.0 | GPL-2.0-only /
GPL-2.0-or-later |
是 | 是 |
| GPL 3.0 | GPL-3.0-only /
GPL-3.0-or-later |
是 | 是 |
| AGPL 3.0 | AGPL-3.0-only /
AGPL-3.0-or-later |
是 | 是 |
| SSPL 1.0 | SSPL-1.0 |
否 | 否 |
| BSL 1.1 | BUSL-1.1 |
否 | 否 |
| 木兰宽松 v2 | MulanPSL-2.0 |
是(2020 年认证) | 未审查 |
| CC BY-NC 4.0 | CC-BY-NC-4.0 |
否 | 否 |
注意两个容易错的坑:
GPL-2.0 /
GPL-3.0,从 SPDX 3.0 开始被
deprecated(废弃),必须写成 GPL-2.0-only 或
GPL-2.0-or-later,明确你的意图。MIT 这个标识符对应的是 “MIT License”(也叫
Expat License),而不是 X11 License 或 MIT
的其它历史变体——它们在 SPDX 里是不同的 ID。OSI 在 1998 年发布了 The Open Source Definition(OSD),核心十条:
其中第 6 条是争议焦点:“no discrimination against fields of endeavor” 禁止许可证针对特定使用场景——但 SSPL 和 Commons Clause 都是明确针对”把软件作为服务卖”这个特定商业模式的。
OSI 认证有三个工程上的实际含义:
这个灰色地带也经常被称为 source-available(可见源):
2018 年 8 月 21 日,Redis Labs 宣布把 RediSearch、Redis Graph、Redis-ML、Rebloom、Redis-JSON 五个模块的许可证从 AGPL-3.0 改为 “Apache-2.0 + Commons Clause”。Commons Clause 的核心条款:
“Without limiting other conditions in the License, the grant of rights under the License will not include, and the License does not grant to you, the right to Sell the Software.”
即禁止”销售”软件——这里的 “Sell” 包括对外提供付费服务。OSI 随后发表立场文章,明确 Commons Clause 违反 OSD 第 6 条,不是开源。
2019 年 2 月,Redis Labs 再次调整,把 Commons Clause 移除,改用自己的 “Redis Source Available License”(RSAL)。这个许可证同样不是开源。2024 年 3 月 20 日,Redis Inc.(原 Redis Labs)将 Redis 本体的许可证从 BSD-3-Clause 切换到 RSAL v2 + SSPL 双许可,社区 fork 出 Valkey 项目,现由 Linux Foundation 托管。
国内厂商影响:阿里云早在 2018 年就基于 Redis 开源分支构建了 Tair(原名 Aliyun Redis),其中的增强模块(持久内存引擎、全球多活等)走的是自研路径;2024 年 Redis 改协议后,阿里云、腾讯云、华为云对外公开声明迁移到 Valkey 或维持 Redis 7.x 分支(最后的 BSD-3-Clause 版本)。
MongoDB 从 2009 年起用 AGPL-3.0。但 AGPL 有一个“只要你不修改源码就不触发”的灰色地带——云厂商可以拿未修改的 MongoDB 二进制提供托管服务,只要不 fork 不改代码,就不需要公开任何东西。AWS DocumentDB(2019 年 1 月发布)正是这个灰区的典型例子——尽管 AWS 声称是”兼容 MongoDB API”的自研实现,争议从未停止。
MongoDB 在 2018 年 10 月推出 SSPL,把”作为服务对外提供”本身作为触发条件,并要求开源”使该服务可用的所有程序”——包括管理后台、监控系统、自动化运维工具、备份和日志服务等。这个范围大到几乎没有公司能够满足。
SSPL 的后果: - OSI 在 2019 年 1 月拒绝认证。 - Debian、Fedora、Red Hat 立即把 MongoDB 移出主仓库。 - Homebrew 把 MongoDB 移到 cask(需要显式接受许可证)。 - 但 MongoDB 公司的营收并未受冲击——AWS 没有像 Elastic 那样大规模转售。 - 国内厂商应对:阿里云、腾讯云都维持了 MongoDB 4.0(最后的 AGPL 版本)分支,或者迁移用户到自研的文档型数据库(阿里云 Lindorm 等)。
教训:SSPL 的实际效果不是把云厂商关在门外——是让 MongoDB 本身失去了开源身份。对很多”上游只用不改”的公司来说,是否 OSI 认证不是合规问题,是能不能进 Linux 发行版、能不能进 CNCF、能不能成为默认依赖的问题。
历史:由麻省理工学院在 1980 年代发布,原名 “Expat License”。全文不到 200 字。
核心条款(摘要):
Permission is hereby granted, free of charge, to any person obtaining a copy of this software …, to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software …, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
关键点:
一个合规但容易被忽略的点:你不能用另一个项目的 MIT 代码但删掉它的版权声明。Facebook 早期在 React Native 里有一例:被发现某个文件的上游声明被剥离,补丁一天内合入。
BSD 家族来自加州大学伯克利分校。主要有三个变体:
4-Clause
BSD(原始版本,含”广告条款”):要求所有广告材料都必须提到伯克利。已被
FSF 判定与 GPL 不兼容,现在基本不用。SPDX:
BSD-4-Clause。
3-Clause BSD(“New BSD” 或 “Modified BSD”):删除了广告条款,增加了 “no endorsement”(不得用原作者名字背书):
Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
2-Clause BSD(“Simplified BSD” 或 “FreeBSD License”):连 “no endorsement” 条款也去掉了,功能上接近 MIT。
SPDX:
BSD-3-Clause、BSD-2-Clause。
Apache-2.0 是宽松许可证里唯一大范围使用、且包含显式专利授权条款的许可证。这是它和 MIT/BSD 最大的差异。
关键机制:
SPDX: Apache-2.0。
工程意义:对于涉及专利密集领域(加密、编解码、机器学习推理)的项目,Apache-2.0 比 MIT 更有保护力。这也是为什么 Kubernetes、TensorFlow、Kafka、Spark、RocksDB 都选 Apache-2.0 而不是 MIT。
ISC 由 Internet Systems Consortium 编写,语义上等同于简化 MIT:
Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
SPDX: ISC。OpenBSD 几乎全部使用 ISC。npm
生态里也极为常见(npm init 默认许可证就是
ISC)。
两者都尝试把作品放到公共领域(Public Domain):
需要注意的是,“公共领域”在大陆法系(包括中国、德国、法国)没有直接对应概念——作者的人身权(作者身份权、保护作品完整权)通常不能放弃。所以即使用了 Unlicense,中国法律下你仍然享有署名权等不可转让权利。工程里一般把 Unlicense 当作”等同于 MIT 但去掉了版权声明要求”理解。
下面这张表把四个主流宽松许可证的每条强制义务列出来:
| 义务 | MIT | BSD-2 | BSD-3 | Apache-2.0 | ISC | Unlicense |
|---|---|---|---|---|---|---|
| 保留版权声明 | ✓ | ✓ | ✓ | ✓ | ✓ | — |
| 保留许可证全文 | ✓ | ✓ | ✓ | ✓ | ✓ | — |
| 禁止用作者名背书 | — | — | ✓ | ✓ | — | — |
| 修改声明义务 | — | — | — | ✓(Section 4b) | — | — |
| 保留 NOTICE 文件 | — | — | — | ✓(Section 4d) | — | — |
| 显式专利授权 | — | — | — | ✓(Section 3) | — | — |
| 专利报复终止 | — | — | — | ✓ | — | — |
| 贡献者 CLA 机制 | — | — | — | ✓(Section 5) | — | — |
许多人以为”宽松许可证之间没区别”,这是错觉。以下几个场景需要仔细挑:
场景 A:Rust crate 发布到
crates.io。Rust 社区惯例是
Apache-2.0 OR MIT
双许可——下游可以任选。这是为了同时满足: - 想要 Apache
专利条款保护的企业使用者。 - 想要极简 MIT 的个人开发者。 -
与 GPL-2.0 兼容(通过 MIT 路径)。
# Cargo.toml 示例
[package]
name = "my-crate"
version = "0.1.0"
license = "Apache-2.0 OR MIT"场景 B:给嵌入式芯片厂商做 SDK。推荐 Apache-2.0:芯片行业专利密集,MIT 的缺失专利条款会让下游法务不放心。
场景 C:小型 CLI 工具。MIT 或 ISC,简洁为王。
场景 D:学术论文附带的 reference implementation。有人选 MIT,有人选 BSD-3-Clause(保留实验室的 no-endorsement 要求)。
LGPL(GNU Lesser General Public License)最初叫 “Library GPL”,目标明确:允许闭源应用”链接”LGPL 库而不触发 Copyleft。
核心机制:
SPDX:
LGPL-2.1-only、LGPL-2.1-or-later、LGPL-3.0-only、LGPL-3.0-or-later。
工程陷阱:静态链接 LGPL 库会触发 Copyleft。Qt 历史上的双许可模式(LGPL / 商业)正是利用了这一点——嵌入式设备厂商如果要静态链接 Qt,必须买商业许可证;如果动态链接就用 LGPL 即可。
MPL 2.0 是文件级 Copyleft:
这是 Mozilla(Firefox、Thunderbird)的核心许可证,设计目的是允许 Mozilla 项目被集成进专有产品(比如嵌入浏览器引擎)。
SPDX: MPL-2.0。
MPL-2.0 还引入了与 GPL 的显式兼容性——在许可证文本 Section 3.3 里明确,MPL 文件可以被纳入 GPL/LGPL/AGPL 作品中,这解决了 MPL-1.1 时代的兼容性痛点。
EPL 2.0 是 Eclipse 基金会的旗舰许可证,模块级 Copyleft:
SPDX: EPL-2.0。
EUPL-1.2:欧盟官方许可证,专为应对欧盟 27 国管辖权设计——许可证文本有 23 种官方语言版本,全部具有同等法律效力。它的 Copyleft 强度介于 LGPL 和 GPL 之间,并且通过 “Compatible Licenses” 附录允许与 GPL、AGPL、MPL、EPL 等兼容切换。
CDDL-1.0:Sun Microsystems 为 OpenSolaris 设计的许可证,与 GPL-2.0 不兼容——这是 ZFS 不能原生合入 Linux 内核的历史原因。Oracle 接手 Sun 后一直没有重新授权,导致 ZFS on Linux 只能以”用户态挂载”或”DKMS 外置模块”的方式存在,成为许可证兼容性教科书案例。
SPDX: EUPL-1.2、CDDL-1.0。
| 许可证 | Copyleft 作用域 | 典型提问:我加了一个新文件,要开源吗? |
|---|---|---|
| LGPL | 库整体(以库为边界) | 新文件在库内→要;新文件在应用内→不要 |
| MPL-2.0 | 单个文件 | 新文件→不要;修改了既有 MPL 文件→要改动 |
| EPL-2.0 | 模块 | 新文件在新模块→不要;同模块内→要 |
| CDDL-1.0 | 文件 | 类似 MPL |
三个”边界”在实际项目里的可辨识度是文件 > 库 > 模块。MPL 因为是文件级,二进制合规最容易判断——扫描所有带 MPL 头的文件,改动过的回传即可。EPL 因为”模块”定义模糊(Java 下通常是 jar 或 OSGi bundle,其它语言就很主观),合规判断更费劲。
如果你的商业应用要链接 LGPL 库:
[ ] 确认是动态链接,不是静态链接
[ ] 在安装包 / 文档里列出所用的 LGPL 库和版本
[ ] 提供该 LGPL 库对应的源码(镜像站或链接)
[ ] 提供重新编译替换的"足够信息"——LGPL-3.0 还要求可操作的安装方法
[ ] 保留库的版权声明和许可证文本
[ ] 如果修改了库本身,以 LGPL 回传修改(通常用补丁形式)
[ ] LGPL-3.0 的情况下,检查 Anti-Tivoization 条款是否适用(是否算 "User Product")GPL(GNU General Public License)是强 Copyleft 的祖师。核心机制是三句话:
“分发”(distribute / convey)的核心:把二进制交到另一个法人/自然人手里。只要没跨越法人边界,就不是分发——内部使用、内部部署都不触发。
GPL-2.0 发布于 1991 年,GPL-3.0 发布于 2007 年 6 月 29 日。主要差异:
| 维度 | GPL-2.0 | GPL-3.0 |
|---|---|---|
| 专利条款 | 无显式专利授权 | 显式专利授权 + 专利报复终止 |
| 反硬件锁定 | 无 | 有(Anti-Tivoization,§6) |
| DRM 条款 | 无 | 明确 DRM 不构成”有效技术措施” |
| 与 Apache-2.0 | 不兼容(专利冲突) | 兼容(2007 年 FSF 确认) |
| 许可证传递 | 较宽松 | 更精确定义 “conveying” |
| 国际化 | 美国法为主 | 采用更中立术语 |
反硬件锁定条款(俗称 Anti-Tivoization)的由来:2003 年 TiVo 公司销售基于 Linux(GPL-2.0)的机顶盒,遵守了 GPL-2.0——公开了所有源码。但 TiVo 用硬件签名机制防止用户刷入修改过的内核——结果就是”源码开源、但你改了也装不进设备”。Stallman 认为这违反了 GPL 的精神。GPL-3.0 §6 明确要求:分发”User Products”时,必须提供”Installation Information”(安装信息),使接收方能把修改过的版本装回设备。
Linux 内核的选择:Linus Torvalds
明确拒绝 GPL-3.0,内核永远停留在
GPL-2.0-only。他的公开理由是反对”把
DRM/硬件锁定和软件许可证绑定在一起”。这意味着 Linux
永远不能接纳任何 “GPL-3.0-only” 的代码。
GPL 的触发词是 “distribute”(GPL-2.0)或 “convey”(GPL-3.0)。严格来说:
触发: - 把二进制拷贝给公司外部员工、客户 - 在 App Store、应用市场上架 - 烧录进硬件销售(TiVo 场景、嵌入式设备) - 作为 SDK 发给下游集成商
不触发(“Internal Use Loophole”,内部使用漏洞): - 公司内部部署给自己员工使用 - 作为 SaaS 后端运行(只对外提供服务,不交付二进制本身)——这正是 AGPL 要堵的口子 - 同一法人内跨部门传递 - 开发测试阶段在本地编译运行
这个”内部使用不算分发”的设计,是云厂商能够长期免费使用 GPL 软件提供托管服务的根本原因。MongoDB 用 SSPL 堵这个口子,走到了”不再是开源”的位置。
GPL 不是空气中飘着的病毒——它只通过作品的衍生关系传递。
判断一段代码是否变成”GPL 衍生作品”,有三个法律维度(美国法视角,FSF 的立场):
ls)。这个话题复杂到足以单独成篇,详见 Copyleft 的工程边界:动态链接、容器、SaaS 算不算”分发”。
GPL 历史上的主要执法主体有两个:Software Freedom Conservancy(SFC)和 gpl-violations.org(Harald Welte 创立,2004-2018 活跃)。被起诉的对象大多是嵌入式领域——路由器、电视、摄像头厂商。
典型案例: - Welte v. Sitecom (2004, 德国):Sitecom 的路由器固件使用 Linux 内核但未提供源码。德国法院发布禁制令,Sitecom 合规并下架该批产品。这是 GPL 第一次获得法院支持。 - BusyBox v. Verizon (2007, 美国):Verizon OEM 的路由器使用 BusyBox 未遵守 GPL-2.0。最终和解,Verizon 提供源码并支付律师费。 - VMware v. SFC (2015-2019, 德国):Christoph Hellwig(Linux 内核贡献者)起诉 VMware 的 ESXi 使用 vmklinux 未遵守 GPL-2.0。汉堡法院以”证据不足”驳回,但 VMware 此后仍然逐步剥离了 vmklinux。 - Vizio 案(2021 至今, 美国加州):SFC 作为软件最终用户起诉 Vizio 智能电视未遵守 GPL-2.0。这是第一次以”第三方受益人”身份起诉——开创了先例:GPL 执法者不必是原作者。2022 年 5 月联邦法院驳回了 Vizio 的管辖动议,案件继续。
这些案例的共同点:几乎所有胜诉或和解都发生在”分发二进制”的嵌入式场景。纯 SaaS 场景下 GPL 执法几乎不可能成功——这正是 AGPL 存在的意义。
GPL-2.0 起草于 1991 年,那时候软件专利还不是主流。2007 年 V3 发布时增加的专利条款非常精细:
相比之下 GPL-2.0 完全没有显式专利条款,只靠 §7 “Liberty or Death” 提供间接保护:如果有人因为专利无法遵守 GPL,他就不能分发——一种”要么自由、要么死”的原则。
AGPL(Affero General Public License)的历史:Affero 公司在 2001 年发布了最早的 AGPL v1,专门针对”SaaS 漏洞”。2007 年与 GPL-3.0 同期推出 AGPL v3,并被 OSI 认证。
AGPL 相对 GPL 的唯一实质差异在 §13 Remote Network Interaction:
Notwithstanding any other provision of this License, if you modify the Program, your modified version must prominently offer all users interacting with it remotely through a computer network … an opportunity to receive the Corresponding Source of your version …
翻译:如果你修改了程序,并通过网络向用户提供该程序的功能,你必须给所有通过网络与之交互的用户提供下载”Corresponding Source”(对应源码)的机会。
关键词是”修改”(modify)——如果你部署的是未修改的上游二进制,AGPL 的 §13 不直接触发。这个灰区正是 AWS 拿未修改版 MongoDB 提供 DocumentDB 服务(早期)的法律依据。
SPDX:
AGPL-3.0-only、AGPL-3.0-or-later。
典型使用者:MongoDB(2009—2018)、MinIO、Plausible Analytics、Bitwarden、Nextcloud、Mastodon。
工程上的致命点:如果你在公司内部自研 SaaS,哪怕只是打了一个补丁、加了一个监控埋点,都要给用户提供完整源码。这对商业公司几乎是不可接受的——所以绝大多数公司对 AGPL 的态度是“除非商业授权,否则禁止引入”。Google 的内部许可证政策是著名的 AGPL 黑名单——贡献、使用都被严格限制。
SSPL 的核心差异在 §13 Offering the Program as a Service:
If you make the functionality of the Program or a modified version available to third parties as a service, you must make the Service Source Code available via a network download … The “Service Source Code” means the Corresponding Source for the Program or the modified version, and the Corresponding Source for all programs that you use to make the Program or modified version available as a service, including, without limitation, management software, user interfaces, application program interfaces, automation software, monitoring software, backup software, storage software and hosting software …
关键是”all programs that you use to make the Program available as a service”——所有你用来把程序作为服务提供的程序。这个范围有多大?MongoDB 的意图就是让它大到没人能达成——云厂商想要开源整个调度系统、账单系统、身份认证系统。
SPDX: SSPL-1.0。OSI 未认证。
SSPL 的实际使用者:MongoDB(2018 至今)、Elastic(2021 ELv2 or SSPL 双许可)、Redis(2024 RSAL v2 or SSPL 双许可)。
BSL 严格说不是”许可证”,是一个许可证模板。核心设计:
SPDX: BUSL-1.1。OSI 未认证,FSF
明确不认为是开源。
使用者:MariaDB MaxScale(2016)、CockroachDB(2019)、Sentry(2019)、Couchbase(2021)、HashiCorp Terraform/Vault/Consul/Packer/Boundary/Nomad/Vagrant/Waypoint(2023 年 8 月集体切换)。
HashiCorp 切换后立即引发社区反弹。2023 年 9 月 Linux Foundation 宣布成立 OpenTofu(原名 OpenTF),基于 Terraform 最后的 MPL-2.0 版本 fork。这是 BSL 时代的第一个大规模 “fork 事件”。
OSI 在 2019 年 1 月 19 日官方拒绝 SSPL,理由集中在两点:
BSL 没有提交到 OSI 认证,因为 Change Date 前的限制明显违反 OSD 第 6 条(禁止商业使用的某些形式)——它的设计者(David Axmark)从一开始就承认 BSL 是一种”eventually open source”(最终开源)模式,不是纯开源。
AGPL §13 的触发条件是”if you modify the Program”。什么算 modify?
实际操作中,大多数公司律师建议保守对待——只要你部署的不是 100% 官方二进制,就按 “modified” 处理,向用户提供源码入口。
AGPL-3.0 的合规实操,一般是这样:
<!-- 产品网页页脚 -->
<footer>
This service is built on <a href="https://example.com/source">open source</a>
licensed under <a href="https://www.gnu.org/licenses/agpl-3.0.html">AGPL-3.0</a>.
Complete source code for this deployment is available at:
<a href="https://github.com/example/our-fork">github.com/example/our-fork</a>
</footer>或者在 API 的 HTTP 响应头里加一行:
HTTP/1.1 200 OK
X-Source-Code: https://github.com/example/our-fork/tree/deployed-v2.3.1
关键是:用户在”与服务远程交互”时必须显眼地看到源码获取方式。只在 GitHub 上放了 fork 但网站上完全没提,不符合 §13 “prominently offer” 的要求。
案例一:HashiCorp Terraform → OpenTofu 分叉(2023)
2023 年 8 月 10 日 HashiCorp 宣布所有产品(Terraform/Vault/Consul/Nomad/Packer/Boundary/Vagrant/Waypoint)从 MPL-2.0 切换到 BUSL-1.1。核心条款变化:
社区反应在 3 天内形成——到 8 月 14 日,Gruntwork、Spacelift、Env0 等 Terraform 生态公司联合发起 OpenTF Manifesto,有 166 家公司、数千名个人开发者签名支持。9 月 20 日 OpenTF 加入 Linux Foundation,更名 OpenTofu。2024 年 1 月 OpenTofu 1.6 发布,正式成为 Terraform 的 fork 替代。
这一案例的意义是:单方切换许可证的代价越来越大——社区的 fork 能力比十年前强得多,只要代码公开 + 有资本支持,任何许可证切换都可能招来 fork。
案例二:MongoDB 与国内云厂商(2018 至今)
2018 年 MongoDB 切换到 SSPL 后,国内云厂商的应对大致是三条路:
这也催生了若干”MongoDB 协议兼容”的开源项目:Ferret DB(Apache-2.0,在 PostgreSQL 之上实现 MongoDB 协议)是其中最有名的一个。
案例三:Redis 7.4 切换 RSAL v2 + SSPL(2024)→ Valkey fork
Redis Inc.(原 Redis Labs)在 2024 年 3 月 20 日宣布从 Redis 7.4 起切换到 RSAL v2 或 SSPL 双许可。核心受影响的云厂商再次联合——AWS、Google Cloud、Oracle、Ericsson、阿里云、华为云联合发起 Valkey 项目,基于 Redis 7.2.4(最后的 BSD-3-Clause 版本)fork。2024 年 3 月 28 日 Valkey 加入 Linux Foundation。
对国内而言: - 阿里云 Tair 在 Redis 改协议后迅速表态支持 Valkey。 - 华为云、腾讯云类似。 - 自用 Redis 的国内企业(美团、字节跳动等)多年前就基于 Redis 源代码有自研分支,改协议对他们影响有限。
你的产品是否对外提供网络服务?
├── 否(本地桌面/CLI/库)→ 网络 Copyleft 不适用,考虑 GPL/LGPL/MIT
└── 是
├── 你想阻止云厂商托管转售吗?
│ ├── 不想→ AGPL 或更宽松
│ └── 想
│ ├── 你能接受项目"不算开源"吗?
│ │ ├── 能接受 → SSPL 或 BUSL
│ │ └── 不能接受 → AGPL-3.0(能阻止部分场景)
└── 你需要双许可(开源 + 商业)变现吗?
├── 需要 → AGPL + 商业许可(GitLab / MongoDB 早期模式)
└── 不需要 → 纯 AGPL 或纯 SSPL
“兼容”(compatibility)指的是:能不能把 A 许可证的代码和 B 许可证的代码合并在一起,输出一个符合两者要求的复合作品。
大多数情况下,兼容是单向的——宽松许可证可以”嵌入”Copyleft 许可证的项目(最终作品受 Copyleft 约束),反过来不行。
下面这张表是业内共识(以 FSF 公开意见为主要依据),不构成法律意见:
| 合并 → | MIT | Apache-2.0 | LGPL-2.1 | LGPL-3.0 | MPL-2.0 | GPL-2.0-only | GPL-3.0-only | AGPL-3.0 |
|---|---|---|---|---|---|---|---|---|
| MIT | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Apache-2.0 | ✓ | ✓ | ✓(注1) | ✓ | ✓ | ✗(专利冲突) | ✓ | ✓ |
| LGPL-2.1 | ✓ | ✓(注1) | ✓ | ✓(注2) | ✓ | ✓(升级到 GPL) | ✓(升级到 GPL) | ✓ |
| LGPL-3.0 | ✓ | ✓ | ✓(注2) | ✓ | ✓ | ✗ | ✓(升级到 GPL) | ✓ |
| MPL-2.0 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓(注3) | ✓(注3) | ✓(注3) |
| GPL-2.0-only | ✓ | ✗ | ✓ | ✗ | ✓ | ✓ | ✗ | ✗ |
| GPL-3.0-only | ✓ | ✓ | ✓ | ✓ | ✓ | ✗ | ✓ | ✓ |
| AGPL-3.0 | ✓ | ✓ | ✓ | ✓ | ✓ | ✗ | ✓ | ✓ |
注 1:Apache-2.0 含专利条款,LGPL-2.1 不含,技术上可以合并(因为 LGPL-2.1 不禁止额外授权),但有部分法律意见认为存在微妙冲突——保守做法是”LGPL-2.1-or-later”。
注 2:LGPL-2.1 和 LGPL-3.0 互相兼容需要走 “upgrade to 3.0” 路径(LGPL-2.1 有 “or any later version” 选项)。
注 3:MPL-2.0 的 Section 3.3 Secondary License 机制允许它被纳入 GPL/LGPL/AGPL 作品。
GPL-2.0 vs Apache-2.0:Apache-2.0 的专利报复条款施加了额外限制(GPL-2.0 不允许额外限制)——冲突。FSF 明确指出这是 GPL-3.0 设计动机之一。
GPL-2.0 vs CDDL-1.0:ZFS 的经典案例。两者都是 Copyleft 风格,但对”Modifications”和”作品范围”的定义不同,导致不能合并。
GPL-2.0-only vs GPL-3.0-only:同一项目同一次合并中不能共存——除非至少一方是 “or-later”。
严格来说,LGPL 本身允许”动态链接闭源应用”——这是它的核心设计,不需要额外的例外。
真正需要”linking exception”的是把 GPL 转化成 “LGPL-like” 的场景:
SPDX
表达:GPL-3.0-or-later WITH GCC-exception-3.1、GPL-2.0-only WITH Classpath-exception-2.0。
一个使用 MIT 主程序、Apache-2.0 库、LGPL-2.1 动态链接、MPL-2.0 工具的项目,最终输出的二进制的 SPDX 许可证字段可能是:
MIT AND Apache-2.0 AND LGPL-2.1-or-later AND MPL-2.0
一旦其中任何一个变成 GPL,整个表达式会变成:
GPL-3.0-or-later # 被 "感染"后的实际有效许可证
设想这样一个项目结构:
my-saas/
├── frontend/ # React 应用,MIT
│ └── node_modules/
│ └── some-chart/ # GPL-3.0(JavaScript 图表库)
├── backend/ # 自研,Apache-2.0
│ ├── pom.xml # 依赖 mysql-connector-j(GPL-2.0 with FOSS Exception)
│ └── src/main/java/...
├── ops/ # Helm charts,Apache-2.0
│ └── redis-image/ # 基于 Redis 7.4(RSAL v2 + SSPL),不是开源
└── docs/ # 文档,CC BY-SA 4.0
这里至少有四处合规隐患:
some-chart 是
GPL-3.0:如果你的 React
应用打包后分发(比如做成桌面版 Electron
应用),整个前端可能变成 GPL-3.0。如果只是 SaaS
网页交付,不触发
GPL-3.0,但如果代码里对这个库做了改动,建议切换为带
LGPL-3.0 或 MIT 的替代品。mysql-connector-j 老版本是
GPL-2.0-only with FOSS Exception(一个特殊的”如果整个应用是
FOSS 就豁免”机制)——但 Apache-2.0 不在 FOSS Exception
列表里,需要走 MariaDB Connector/J(LGPL-2.1)或 MySQL
商业许可。这就是为什么 SCA 工具不是可选项,是 SaaS 合规的基础设施。
最常见的 MIT 违规行为:从 GitHub 抄一段 MIT 代码,只保留函数,删掉文件头。这是许可证违反——MIT 的唯一硬性要求就是保留版权声明。
正确做法: - 在文件头保留原作者的版权行和许可证行。 -
或者在项目根目录的 THIRD_PARTY_NOTICES.md
统一列出所有 MIT 依赖及其版权。
两个经典陷阱:
这个误解经常出现在: - 采购文档里写”优先采用开源”,结果采了 MongoDB 7.x(SSPL)。 - CNCF 项目审核时被发现有 SSPL 依赖,不能毕业。 - 国内信创目录里的”开源”定义与 OSI 不完全一致——有时候宽,有时候窄。
JavaScript 生态最容易出现这个问题。一个 Express 项目的
node_modules 下经常有 2000+ 依赖,深度 5-10
层。如果某个远处的传递依赖是 GPL 或 AGPL,而你写的是闭源
SaaS,整个服务的法律状态就不干净。
检测:
# 使用 license-checker
npx license-checker --production --onlyAllow "MIT;ISC;Apache-2.0;BSD-2-Clause;BSD-3-Clause;Unlicense;CC0-1.0;0BSD"
# 使用 Syft 生成 SPDX SBOM
syft dir:. -o spdx-json=sbom.spdx.json
# 使用 ORT(OSS Review Toolkit)全流程扫描
ort analyze -i . -o ort-output
ort scan -i ort-output/analyzer-result.yml -o ort-output常见场景:你的服务依赖 Kafka(Apache-2.0)和一个 MySQL driver(某些 driver 是 GPL-2.0)。这两者在同一个进程里链接会出现合规不一致——必须走 MySQL 商业许可(或者换 MariaDB Connector/J,它用 LGPL-2.1)。
如果一个 Apache-2.0 项目要求贡献者签 CLA(Contributor License Agreement,贡献者许可协议),CLA 里经常包含”授予项目所有者以任何许可证再分发你贡献的代码”的条款。这意味着项目随时可以把你的代码改成专有许可证——这也是 Elastic、HashiCorp、MongoDB 能够单方面切换许可证的法律基础。
把 GPL 软件打进 Docker 镜像并 docker push
到公共 registry——这是”分发”。你必须:
LABEL 或
/usr/share/doc/ 里保留许可证文本。详见 Copyleft 的工程边界:动态链接、容器、SaaS 算不算”分发”。
个人脚本 / 学习项目:MIT 或 ISC。最简单,没人会为你的小项目去审查合规。
企业发布的 SDK / 库(希望被广泛采用):Apache-2.0。专利授权让企业法务放心,兼容 GPL-3.0 不会挡住下游。典型例子:Kubernetes、Kafka、TensorFlow、gRPC。
企业发布的库(需要防止闭源 fork 取代上游):MPL-2.0 或 LGPL。允许商业使用,但修改要回传。典型例子:Firefox(MPL)、Qt(LGPL + 商业)。
强意识形态开源(希望所有衍生产品开源):GPL-3.0-or-later。典型例子:GIMP、GNU 工具链、Bash。
SaaS 产品的开源核心(希望云厂商不能白嫖): - 选 AGPL-3.0:保住”开源”身份,但接受 Google/AWS 等大厂可能不用。 - 选 SSPL-1.0 或 BUSL-1.1:换来更强的反制能力,但失去”开源”身份,失去 Debian/Fedora 发行权。 - 选双许可(AGPL + 商业):GitLab、MongoDB(早期)的典型模式。
政府 / 欧盟项目:EUPL-1.2。23 种语言的法律等效文本、与 GPL/AGPL 兼容、有明确的司法管辖条款。
中国信创 / 国产软件项目:MulanPSL-2.0(木兰宽松许可证第 2 版)。详见 木兰许可证:设计动因与工程影响。
如果没有特殊考虑,闭着眼选 Apache-2.0——这是当前工程语境下最不会踩坑的默认选项:
什么时候不要默认 Apache-2.0: - 你的项目是一个超小的单文件工具——MIT 可能更符合社区习惯。 - 你希望防止 AWS 转售——考虑 AGPL 或 BUSL。 - 你在为 GNU 生态做贡献——用 GPL 保持一致性。
“开源 + 商业”双许可是反制搭便车的主流商业模式:
| 公司 | 开源许可证 | 商业许可证模式 |
|---|---|---|
| MySQL AB / Oracle | GPL-2.0 | 企业版 + OEM 许可 |
| Qt | LGPL-3.0 / GPL-3.0 | 商业许可(嵌入式强制) |
| MongoDB | SSPL-1.0 | Atlas 云服务 + 企业许可 |
| GitLab | MIT(CE)+ 专有(EE) | 企业版订阅 |
| Elastic | ELv2 / SSPL | Elastic Cloud + 企业版 |
双许可能生效的前提是贡献者把版权授予给主导公司(通过 CLA 或雇佣关系)——否则你无法改变许可证。
OceanBase:蚂蚁集团的分布式数据库,2021 年 6 月开源,使用 MulanPSL-2.0。选 MulanPSL 而不是 Apache-2.0 的原因:司法管辖权明确、法律文本中文原生、国内合规路径更清晰。但代价是国际采用面较窄——国外部分公司合规团队需要额外审查 MulanPSL-2.0 的条款(尽管 2020 年已 OSI 认证)。
PingCAP TiDB:选 Apache-2.0。设计目的之一是追求全球采用——CNCF 孵化毕业的项目几乎都是 Apache-2.0。
阿里云 Tair / PolarDB:核心开源分支走 Apache-2.0,增强模块走商业许可。云厂商的典型模式。
华为 openEuler 和 openGauss:openEuler 整体使用 Mulan PSL v2,openGauss 使用 Mulan PSL v2。选用本土许可证对应”供应链自主可控”的定位。
成熟公司通常把许可证分为四档内部政策:
| 档位 | 许可证 | 政策 |
|---|---|---|
| 绿灯(允许无审批使用) | MIT, BSD-2/3, Apache-2.0, ISC, 0BSD, Unlicense, CC0 | 直接用,记录到 SBOM |
| 黄灯(允许但需登记) | LGPL-2.1/3.0, MPL-2.0, EPL-2.0, CDDL, EUPL | 提交合规登记,动态链接,不静态链接 |
| 红灯(原则禁止、个案审批) | GPL-2.0/3.0, AGPL-3.0 | 除非作为独立服务部署且不与闭源代码混合,否则禁止 |
| 黑灯(禁止) | SSPL, BUSL, Commons Clause, CC BY-NC, 任何非 OSI 许可证 | 禁止在产品里引入 |
Google、Meta 等公司公开披露过类似的政策(Google 的 go/thirdparty 文档、Meta 的 OSPO 政策)。国内大厂(阿里、字节、腾讯)也都有内部版本,细节各异但大致框架一致。
如果你的项目已经发布了一段时间,想切换许可证——能切吗?取决于:
在实际项目里,选定许可证只是第一步。完整的”许可证工程”包含以下步骤:
[ ] 在项目根目录放一个 `LICENSE` 文件,内容是许可证全文(不是链接)
[ ] 在 README 里说明许可证,用 SPDX 标识符
[ ] 每个源文件顶部添加 `SPDX-License-Identifier:` 单行
[ ] 如果是 Apache-2.0,放一个 `NOTICE` 文件
[ ] 如果使用了第三方依赖,在 `THIRD_PARTY_NOTICES.md` 列出
[ ] 设置 CI 扫描(license-checker / syft / ORT)
[ ] 如果接受外部贡献,决定用 CLA 还是 DCO(详见下一篇)
[ ] 如果要双许可,保证所有贡献者都通过 CLA 转让了必要的权利
[ ] 生成 SPDX SBOM 作为发布物的一部分
[ ] 在官网/文档显著位置标注许可证(特别是 AGPL/SSPL 这种触发条件敏感的)回到 开源许可与版权工程系列索引。
本文不构成法律意见。许可证合规的最终判断依赖于具体司法辖区、具体合同条款和具体使用场景。涉及重大商业决策时,请咨询有开源许可证经验的律师。本文所引用的企业案例(Redis、MongoDB、Elastic、HashiCorp、阿里云 Tair 等)基于公开资料,事件细节以各公司官方声明为准。
上一篇:中国法下的软件著作权与开源
下一篇:Copyleft 的工程边界:动态链接、容器、SaaS 算不算”分发”
把当前热点继续串成多页阅读,而不是停在单篇消费。
2026-04-22 · architecture / opensource
面向做闭源/商业产品的团队:逐一拆解 MIT、LGPL、GPL、AGPL、SSPL、BSL 在 SaaS、私有化部署、移动 App、嵌入式固件等形态下的许可边界,给出三级名单模板、CI 扫描配置、SBOM 存证方案与出海补充要求。
2026-04-22 · architecture / opensource
面向工程团队的开源许可证完整操作手册:许可证选型决策树、LICENSE/NOTICE/SPDX 文件写法、第三方依赖声明、CI 自动化检查、发布物合规标注,以及六套真实可复制的项目结构模板。
2026-04-22 · architecture / opensource
面向中国工程团队的开源许可、版权与合规系列。从 GPL、AGPL、Apache、木兰协议到中国真实案例、SCA/SBOM 工具链与出海合规,讲清楚开源在工程落地中的坑与方法。
2026-04-22 · architecture / opensource
从 GPLv2 的 distribute 到 GPLv3 的 convey,再到 AGPL-3.0 的网络交互条款,本文系统梳理动态链接、容器镜像、SaaS 部署、嵌入式固件在 Copyleft 语境下的触发边界,并给出工程化合规清单与真实案例。
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。