AGPL、SSPL、BSL 开源协议对比:传染边界与商业选型指南
开源许可证这个话题,很多开发者平时不太在意,觉得“能跑就行”,可一旦项目要商业化、要融资、要做技术选型,或者公司要引入第三方组件,许可证就成了绕不开的坎。我见过不少团队在选型时只看功能不看协议,结果产品上线后被要求开源自有代码,或者被迫临时替换核心依赖,代价非常大。AGPL、SSPL 和 BSL 这三种协议,是近几年争议最大、也最容易被误读的三类,它们分别代表了“强传染性”“服务边界扩展”和“延迟开源”三种截然不同的思路。这篇内容就是把这三种协议的核心区别、适用场景和商业影响掰开揉碎讲清楚,适合正在做技术选型的架构师、负责合规的法务同学,以及准备把内部工具开源出来的独立开发者参考。读完你至少能判断:某个组件能不能放心用、用了之后自家代码要不要跟着开源、以及自己发起的项目该选哪种协议来平衡社区和商业。
1. 三种协议的整体设计思路拆解
1.1 为什么会有这三种“非标准”开源协议
要理解 AGPL、SSPL 和 BSL,得先明白它们各自在回应什么问题。传统的 MIT、Apache 2.0 这类宽松协议,核心诉求是“随便用,别找我麻烦”,商业友好但保护不了开发者的商业利益;GPL 系列则强调“用了我的代码,你的衍生作品也得开源”,保护了社区但让很多商业公司望而却步。问题在于,云服务时代出现了一个巨大的漏洞:一家公司可以把 GPL 软件改一改,部署成 SaaS 服务对外售卖,既不分发二进制、也不回馈代码,GPL 的“分发触发”条款根本管不到它。
AGPL 就是冲着这个漏洞来的,它把“分发”的概念扩展到了“通过网络提供服务”,只要用户能通过网络和你的修改版交互,你就得提供源码。SSPL 是另一家数据库厂商在 AGPL 基础上更进一步,把“服务”本身也纳入了开源范围,你拿它做托管服务,就得把整个服务栈的开源义务扛起来。BSL 则走了完全相反的路子:它压根不假装自己是开源协议,而是“源码可见、延迟开源”,先用商业限制保护作者几年,到期后自动转成真正的开源协议。这三种协议本质上是三种不同的商业防御策略,理解了这个底层动机,后面的条款细节就都好懂了。
1.2 传染范围对比:从代码到服务到时间
这三种协议最核心的差异,体现在“传染边界”上。我用一个表格把关键维度拉平对比,这样选型时一眼就能看清。
| 维度 | AGPL v3 | SSPL v1 | BSL 1.1 |
|---|---|---|---|
| 触发条件 | 网络交互 + 修改 | 提供该软件作为服务 | 生产环境使用(可自定义) |
| 传染对象 | 修改后的程序本身 | 整个服务栈(含配套工具) | 无传染性,仅限制用途 |
| 是否 OSI 认证 | 是 | 否 | 否 |
| 到期转换 | 无 | 无 | 有,默认4年转开源 |
| 商业使用限制 | 无,但需开源 | 无,但需开源服务栈 | 有,通常禁止竞品托管 |
这张表里最容易被忽略的是“传染对象”这一行。AGPL 的传染范围其实和 GPL 类似,只覆盖“基于该程序的衍生作品”,你写一个独立进程通过 API 调用它,通常不算衍生。但 SSPL 的措辞要激进得多,它要求“提供服务所必需的所有软件”都得开源,这个“必需”的边界非常模糊,可能把监控、编排、管理面板全卷进去,这也是它没拿到 OSI 认证、被各大发行版拒之门外的原因。BSL 则完全没有传染性,它只是在时间维度上限制你“不能拿它做竞品”,四年后自动变成 Apache 2.0 或 MIT,对使用者来说风险最可控。
1.3 选型背后的商业逻辑
站在项目发起方的角度,选哪种协议取决于你想靠什么赚钱。如果你的商业模式是卖技术支持、卖托管服务,那 AGPL 是合理的,因为它逼着那些拿你代码做 SaaS 又不回馈的厂商要么开源要么买商业授权。如果你的核心资产是数据库这类基础设施,且你打算自己做云服务,SSPL 的强约束能挡住云厂商白嫖,但代价是社区信任度下降。如果你是个初创公司,产品还在快速迭代,既想让人看到源码建立信任,又不想被竞争对手直接拿去托管,BSL 的“延迟开源”是最务实的折中。我个人的经验是,越是基础设施层、越靠近“别人拿去做服务就能赚钱”的组件,越需要强约束协议;越是应用层、工具链层的项目,宽松协议反而更有利于生态扩散。
2. AGPL 核心条款与实操要点
2.1 网络交互条款到底怎么触发
AGPL 相对于 GPL 唯一实质性的增量,就是第 13 条“Remote Network Interaction”。原文的意思是:如果你的修改版程序支持网络交互,你必须给所有通过网络与之交互的用户提供获取对应源码的机会。注意这里的措辞是“提供机会”,不是“主动推送”,实践中通常是在服务界面放一个显眼的“源码”链接,指向你修改版的完整源码仓库。
关键在于“修改版”三个字。如果你原封不动地部署一个 AGPL 软件对外提供服务,理论上你也需要提供源码,但因为上游源码本来就公开,你只要链接回原项目即可。真正麻烦的是你打了补丁、改了配置逻辑、加了自定义模块的情况。这里有个常见的误区:很多人以为“我只是改了配置文件,不算修改”。这个理解是危险的,如果配置改动构成了具有独创性的逻辑(比如你写了一套复杂的路由规则嵌进配置),很可能被认定为衍生作品。稳妥的做法是,任何对 AGPL 组件的非平凡改动,都保留独立的补丁文件并公开,同时确保你的自有业务代码通过进程隔离或 API 边界与之解耦。
2.2 什么情况下你的自有代码会被“传染”
这是所有人最关心的问题。AGPL 的传染性遵循“衍生作品”原则,判断标准是代码之间是否构成紧密耦合的单一程序。我总结了几条实操中的判断经验:
- 同进程链接:你的代码和 AGPL 库编译进同一个二进制、同一个进程空间,基本可以确定是衍生作品,必须开源。
- 动态加载插件:如果你的插件通过 AGPL 程序定义的接口加载并运行在同一进程内,风险很高,通常视为衍生。
- 独立进程 + 网络/管道通信:你的服务作为独立进程,通过 HTTP、gRPC、消息队列与 AGPL 组件通信,一般不构成衍生,这是最安全的隔离方式。
- 数据库层面的耦合:如果你的代码直接读写 AGPL 组件管理的内部数据结构(绕过其 API),边界会变得模糊,需要谨慎评估。
注意:以上是基于常见实践的判断,不构成法律意见。真正涉及核心商业利益时,务必让法务介入,或者直接购买该组件的商业授权,这是最省心的路径。
我踩过的一个坑是早期把一个 AGPL 的搜索组件以动态库方式嵌进主服务,后来做合规审查时被迫重构,把搜索拆成独立微服务才算了事。那次重构花了两周,远比一开始就做好隔离的成本高。所以我的建议很直接:引入任何 AGPL 组件前,先想清楚它和你的核心代码之间有没有一道清晰的进程边界,没有就先设计边界。
2.3 部署 AGPL 服务的合规清单
如果你确定要用 AGPL 组件对外提供服务,下面这份清单可以直接抄作业:
- 锁定版本与来源:记录组件名称、版本号、上游仓库地址,存档对应的 LICENSE 文件原文。
- 建立修改台账:所有对组件的改动(补丁、配置、插件)单独存放,与上游版本做 diff,形成可公开的补丁集。
- 界面挂源码入口:在服务的关于页或页脚放置“获取源代码”链接,指向包含完整修改版的仓库或压缩包下载地址。
- 隔离自有代码:自有业务逻辑放在独立服务中,通过明确定义的 API 与 AGPL 组件交互,避免同进程耦合。
- 留存分发记录:如果同时提供二进制下载,确保二进制对应的源码可获取,且版本严格一致。
这套流程跑下来,合规成本其实可控,关键是“台账”和“隔离”两件事要前置,别等产品上线了再补。
3. SSPL 的争议点与使用边界
3.1 “服务栈”条款为什么让社区炸锅
SSPL 最核心的条款是:如果你把该软件作为服务提供给第三方,你必须以相同协议开源“运行该服务所需的所有软件”,包括但不限于管理工具、自动化脚本、监控系统、备份方案。这个条款的杀伤力在于“所有软件”的边界完全由作者解释,理论上你自研的运维平台、调度系统都可能被要求开源。
这就是它没能通过 OSI 认证的根本原因——开源定义要求协议不能歧视特定使用领域,而 SSPL 实质上对“提供服务”这一用途施加了额外义务。各大 Linux 发行版因此把它从软件仓库中移除,很多企业内控清单也直接把它列为禁用协议。站在使用者角度,SSPL 组件的风险不在于“能不能用”,而在于“用了之后边界不可控”。你永远不知道自己哪套配套系统会被认定为“服务所必需”。
3.2 内部使用与对外服务的分界线
好消息是,SSPL 的义务只在“作为服务提供给第三方”时触发。纯内部使用、不对外提供服务的场景,通常不受开源义务约束。这条分界线对很多企业来说是够用的——比如你把某个 SSPL 数据库部署在公司内网,只给内部业务系统用,不对外售卖数据库服务,一般没问题。
但“内部”和“对外”的界定在实践中并不总是清晰。比如你做了一个面向客户的产品,底层用了 SSPL 数据库,客户通过你的产品间接使用了数据库能力,这算不算“提供服务”?保守解读下,只要客户不直接接触数据库、你也没有把数据库能力单独包装成服务售卖,风险相对可控。但如果你做的是 DBaaS、数据平台这类产品,客户本质上就是在使用数据库服务,那就踩线了。我的经验是,凡是产品形态接近“把该组件的能力直接暴露给外部用户”的,一律按触发义务处理,别抱侥幸心理。
3.3 使用 SSPL 组件的风险评估表
| 使用场景 | 触发风险 | 建议 |
|---|---|---|
| 内网自用,不对外 | 低 | 可用,留存使用记录 |
| 嵌入自有产品,用户不直接接触 | 中 | 评估产品形态,必要时买商业授权 |
| 直接提供该组件的托管服务 | 高 | 必须开源服务栈或购买授权 |
| 二次分发修改版 | 高 | 按协议开源全部相关代码 |
这张表是我在做技术选型评审时常用的速查工具,核心逻辑就一句话:越接近“把组件本身当产品卖”,风险越高。对于中高风险场景,最务实的做法是直接联系厂商谈商业授权,把不确定性用合同锁死,比事后扯皮划算得多。
4. BSL 的延迟开源机制与商业玩法
4.1 变更日期与变更协议怎么定
BSL 的结构非常简洁:协议里写明一个“变更日期”(Change Date)和一个“变更协议”(Change License),在变更日期之前,软件按 BSL 的条款授权;到了变更日期,自动转为变更协议(通常是 Apache 2.0 或 MIT)。默认的变更日期是每个版本发布后四年,变更协议默认是 Apache 2.0,但这两项都可以由作者自定义。
这个设计的巧妙之处在于,它给了作者一个“有限期的商业保护窗口”。在窗口期内,作者可以限制竞品拿去做托管服务;窗口期一过,软件彻底开源,社区可以放心采用,不用担心被永久锁死。对使用者来说,BSL 的最大价值就是“确定性”——你能清楚知道哪天之后它变成什么协议,这个时间表是写死在协议里的,不会因为作者心情变化而改变。
实操中,变更日期的设定有讲究。设太短,商业保护不够;设太长,社区不敢用。我观察到的主流做法是三年到四年,既能挡住最直接的竞品抄袭,又不至于让采用者觉得遥遥无期。另外要注意,BSL 是按版本滚动的,每个新版本都有自己的变更日期,所以老版本会先转开源,新版本继续受保护,这个机制保证了项目持续演进的同时逐步释放。
4.2 附加使用限制的常见写法
BSL 允许作者在协议里附加“附加使用限制”(Additional Use Grant),这是它灵活性的来源。最常见的写法是:允许你出于非生产目的使用,或者允许生产使用但禁止提供与该软件竞争的托管服务。比如某数据库项目的写法是“你可以免费用于生产和非生产环境,但不得将该软件作为托管服务或数据库服务提供给第三方”。
写附加限制时有几个坑要避开。第一,限制条款必须明确具体,不能写“不得用于任何商业用途”这种模糊表述,否则采用者无法判断自己是否合规,干脆不用。第二,限制范围要和商业模式匹配,如果你自己不做托管服务,却禁止所有人做托管,会显得动机不纯,社区反弹大。第三,记得在协议里写清楚变更日期和变更协议,这两项缺失会让 BSL 失去“延迟开源”的意义,变成永久限制。
4.3 从 BSL 平滑过渡到开源的实操
如果你打算用 BSL 发布自己的项目,下面这套流程可以保证过渡平滑:
- 在仓库根目录放 LICENSE 文件,开头明确写清“Business Source License 1.1”,紧接着列出参数:Licensor、Licensed Work、Additional Use Grant、Change Date、Change License。
- 每个版本打 tag 时核对变更日期,确保新版本的变更日期按发布日顺延,避免出现“新版本比老版本先开源”的混乱。
- 在 README 里用大白话解释限制,别只丢一个协议链接,用两三句话说明“什么能做、什么不能做、什么时候转开源”,降低采用者的理解成本。
- 到期前主动公告,在变更日期临近时发公告确认转换,并检查仓库里的 LICENSE 是否已更新为变更协议,避免出现“协议说转了但文件没改”的尴尬。
我见过一个项目因为忘记更新 LICENSE 文件,变更日期过了半年还在用 BSL 文本,被社区质疑“假开源”,口碑受损。这种低级错误完全可以通过发布检查清单避免。
5. 三种协议的商业影响与选型决策
5.1 对使用方:引入依赖前的尽调流程
作为使用方,引入任何第三方组件前,我建议跑一遍这个尽调流程,成本不高但能挡掉大部分雷:
- 第一步,查协议类型:看 LICENSE 文件,别只看 README 里的“开源”二字。AGPL、SSPL、BSL 都要单独标记。
- 第二步,查 OSI 认证状态:OSI 认证列表里没有的(如 SSPL、BSL),说明它不是标准开源协议,企业内控往往更严。
- 第三步,评估使用形态:是内网自用、嵌入产品、还是对外提供服务?对照前面章节的触发条件判断义务。
- 第四步,评估替换成本:如果协议风险高,问自己“换掉它要多久”,替换成本高的组件要格外谨慎。
- 第五步,走审批或采购:高风险组件要么走法务审批,要么直接买商业授权,把风险转成成本。
这套流程里,第三步和第四步最关键。很多团队栽在“先用着再说”,等产品做大了才发现替换成本高到无法承受,只能被动接受对方的商业条款。
5.2 对发起方:协议选择与社区信任的平衡
作为项目发起方,选协议本质是在“商业保护”和“社区信任”之间找平衡点。我的经验判断是这样的:如果你的项目是应用层工具,竞品拿去做服务的可能性低,宽松协议(Apache 2.0、MIT)最有利于扩散;如果是中间件、数据库这类“别人拿去做服务就能赚钱”的基础设施,AGPL 或 BSL 更合适;SSPL 除非你已经有足够的商业话语权,否则不建议,因为它对社区的劝退效果太强,很多采用者看到 SSPL 直接跳过。
还有一个常被忽略的点:协议选择要和融资、被收购的预期匹配。投资方做尽调时会看你的协议是否清晰、是否有潜在的法律风险。BSL 因为条款明确、有到期转换机制,在尽调中通常比 SSPL 更容易解释清楚。而 AGPL 项目如果商业模式依赖“卖例外授权”,需要提前把授权条款设计好,否则容易出现“开源版和商业版边界不清”的问题。
5.3 混合使用时的兼容性陷阱
现实项目里经常出现多种协议组件混用的情况,这里有几个兼容性陷阱要特别注意。AGPL 和 GPL 系组件可以共存,但组合后的整体仍受 AGPL 约束;AGPL 组件和 Apache 2.0 组件在同一进程内链接,整体要按 AGPL 处理,这会“污染”原本宽松的代码。SSPL 组件和任何 OSI 开源组件混用,由于 SSPL 本身不是 OSI 协议,组合后的分发条款会变得非常复杂,建议物理隔离。BSL 组件在变更日期之前,其限制条款可能与其他协议的义务冲突,混用前要逐条比对。
提示:混合协议场景下,最稳妥的做法是画一张“组件-协议-交互方式”的矩阵图,把每个组件放在独立进程或独立服务里,用 API 通信代替代码链接,这样每个组件的协议义务都能独立评估,不会互相牵连。
6. 常见误读与排查实录
6.1 “AGPL 只要不开源就没事”错在哪
这是流传最广的误读。AGPL 的义务触发点是“网络交互”,不是“你是否主动开源”。只要你修改了 AGPL 程序并让它对外提供网络服务,你就负有提供源码的义务,不提供就是违约,跟你想不想开源无关。实践中之所以很多服务没被追究,是因为上游作者没精力逐个排查,但这不代表风险不存在。一旦你的服务做大、被上游或竞争对手注意到,追责是分分钟的事。我处理过的一个案例是某团队把 AGPL 组件改了之后做成 API 服务,被上游发函要求开源,最后只能花钱买商业授权了事。
6.2 “BSL 就是闭源”的认知偏差
BSL 经常被简单归类为“闭源协议”,这不准确。BSL 的源码是完全公开的,你可以查看、修改、甚至用于非竞争性场景,它限制的只是特定用途(通常是竞品托管),而且有明确的到期转开源机制。把它和纯闭源商业软件混为一谈,会错过很多本可以安全采用的优秀项目。正确的理解是:BSL 是“带时间锁的源码可见协议”,在锁定期内按作者设定的规则使用,锁定期后彻底开放。
6.3 协议冲突排查速查表
| 现象 | 可能原因 | 排查动作 |
|---|---|---|
| 引入组件后被告知需开源自有代码 | 同进程链接了 AGPL/GPL 组件 | 检查依赖树,确认链接方式,改为进程隔离 |
| 发行版仓库里找不到某组件 | 该组件使用 SSPL 等非 OSI 协议 | 查协议类型,评估是否需自行构建或换替代品 |
| BSL 项目到期后仍显示限制条款 | LICENSE 文件未随版本更新 | 核对变更日期,更新 LICENSE 为变更协议 |
| 混用后分发条款说不清 | 多协议组件在同一分发单元内 | 画组件协议矩阵,拆分分发单元 |
这张表是我在多次合规审查中沉淀下来的,基本覆盖了最常见的几类问题。排查的核心思路永远是“先定位协议类型,再确认交互方式,最后判断义务边界”,顺序别乱。
6.4 几个实操中的避坑心得
第一个心得:把协议检查放进 CI。我们团队在依赖扫描环节加了协议白名单,新引入的依赖如果协议不在白名单内,流水线直接卡住,强制人工评审。这个机制上线后,再没出现过“不知不觉引入高风险协议”的情况。
第二个心得:商业授权谈判要趁早。如果你判断某个组件未来大概率要买商业授权,别等被追责了再谈,那时候议价能力最弱。在产品早期、用量还小的时候谈,往往能拿到更优惠的条款。
第三个心得:自研项目的协议要一次定对。协议变更对已有采用者是很大的困扰,尤其是从宽松改严格,几乎等于背刺社区。所以发起项目时就想清楚商业模式和协议策略,宁可一开始就选严格一点的协议,也别中途改。
第四个心得:别迷信“开源就等于免费”。AGPL、SSPL、BSL 都在提醒我们,开源和免费是两回事,协议条款决定了你在什么条件下能用、用了要承担什么义务。把协议当成技术选型的一等公民来对待,是每个成熟团队都该有的习惯。
这套判断框架我在多个项目里反复用过,从早期的“看功能就选”到现在的“先看协议再谈功能”,踩过的坑换来了这套相对稳妥的流程。协议这件事,平时不显山不露水,真出事的时候往往伤筋动骨,提前花半天时间搞清楚,比事后花几个月重构划算得多。