ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

AGPL、SSPL、BSL开源许可证对比:商业项目合规指南

AGPL、SSPL、BSL开源许可证对比:商业项目合规指南

开源许可证这个话题,平时写业务代码的人很少主动去碰,可一旦踩到,往往就是项目上线前夜被法务叫停、或者融资尽调时被投资人追问的那种场面。我前后参与过几个混合了开源组件的商业项目,也在代码审计环节被 AGPL、SSPL、BSL 这几个词反复折磨过,慢慢才把它们的边界摸清楚。这篇就围绕这三种经常被放在一起比较的许可证,讲清楚它们各自到底在管什么、为什么这么设计、落到真实项目里会带来哪些商业影响,以及作为开发者该怎么判断自己手里的项目会不会被"传染"。不管你是刚接触开源合规的新手,还是已经在做架构选型和法务对接的老手,下面这些内容应该都能对上你的实际场景。

1. 先把三种许可证的"出身"和"脾气"讲明白

很多人一上来就背条款,结果记了一堆名词却不知道它们为什么长这样。我习惯先搞清楚每个许可证是被谁、为了解决什么问题造出来的,理解了动机,条款自然就顺了。

1.1 AGPL:GPL 的"网络补丁"

AGPL 全称是 Affero General Public License,本质上是 GPL 的一个变体,由 Affero 公司提出、后来由自由软件基金会维护。它出现的动机非常具体:GPL 有一个被广泛利用的"漏洞"——如果你只是把 GPL 软件部署在服务器上,用户通过网络访问服务,而并没有拿到软件副本,那么按照 GPL 的字面意思,你并不构成"分发",也就没有义务开放源码。云服务商正是靠这一点,把大量 GPL 组件包装成 SaaS 而不回馈社区。

AGPL 就是来堵这个口子的。它在 GPL 的基础上加了一条关键约束:如果用户通过网络与软件交互,你也必须向这些用户提供对应的源码。注意这里的措辞是"网络交互",不是"分发"。也就是说,哪怕你一个二进制文件都没发出去,只要别人能通过网络用上你的服务,触发条件就成立了。

这条改动看起来只是加了一句话,实际影响巨大。它把"分发"这个传统触发点,扩展成了"分发 + 网络提供服务"两个触发点。对于做 Web 服务、API 平台、SaaS 产品的团队来说,这是必须重点评估的一条。

1.2 SSPL:冲着云厂商去的"服务化"条款

SSPL 全称 Server Side Public License,由一家做数据库的公司提出,后来被用于其核心产品的社区版。它诞生的背景更直接:这家公司发现自己产品的开源版本被大型云厂商拿去托管,做成付费的数据库服务对外售卖,却几乎不回馈上游。传统的 copyleft 许可证管不住这种"只提供托管服务、不分发软件"的行为,AGPL 虽然堵了网络交互的口子,但对"把软件作为服务的一部分再包装出售"这种复杂场景,界定仍然不够细。

SSPL 的做法是把触发条件写得更"重":如果你把该软件作为服务提供给第三方,那么你不仅要开放该软件本身的源码,还要把为了让这个服务跑起来而涉及的所有配套组件的源码一并开放,包括管理软件、自动化脚本、监控、备份、存储层等等。换句话说,它要求你开放的是"整套服务栈",而不只是那个被许可的软件本身。

这个要求非常激进,也是它至今没有被主流开源促进组织认定为"开源许可证"的原因——因为它对使用场景施加了过度的限制,违背了开源定义里"不得歧视特定使用领域"的原则。但对提出方来说,这正是它想要的效果:你可以自己用、可以改,但想拿它做成对外售卖的服务,就得把家底都亮出来。

1.3 BSL:有"保质期"的商业保护伞

BSL 全称 Business Source License,由一家数据库公司主导设计,思路和前两者完全不同。它不追求成为严格意义上的开源许可证,而是走"源码可见 + 限时保护 + 到期转开源"的路线。

它的典型结构是这样的:软件源码公开可见,你可以阅读、修改、用于非生产环境;但在约定的"变更日期"之前,你不能把它用于和许可方构成商业竞争的生产用途。到了变更日期之后,该版本会自动转换成一个真正的开源许可证(通常是 Apache 2.0 或 GPL 之类)。变更日期一般设定在版本发布后的若干年,具体由许可方在许可证文本里写明。

这种设计的巧妙之处在于:它给了商业公司一个"窗口期",在这段时间里靠先发优势和产品能力赚钱,同时又向社区承诺"迟早会完全开源",避免了纯闭源带来的信任问题。对使用者来说,它意味着你需要仔细看变更日期和"商业竞争"的具体定义,而不是简单判断"这是不是开源"。

1.4 三者放在一张表里对比

光看文字容易混,我把三者的核心差异整理成一张表,方便对照:

维度AGPLSSPLBSL
性质被广泛认可的开源许可证未被主流开源组织认定为开源源码可见,非严格开源
触发条件分发 + 网络交互作为服务提供给第三方生产用途 + 商业竞争
开放范围软件本身及其衍生作品整套服务栈组件到期后转为指定开源许可证
时间维度无期限无期限有变更日期,到期转开源
主要防范对象SaaS 白嫖云厂商托管售卖商业竞争对手
对商业项目的影响需评估网络服务是否触发需评估是否对外提供服务需评估用途与竞争关系

这张表建议收藏,做选型评估时对着看,比翻许可证全文快得多。但要提醒一句,表格是简化版,真正落到合同和尽调层面,还是得回到许可证原文和具体版本。

2. 触发条件才是要害:为什么"用"和"分发"差别这么大

许可证的条款再长,真正决定你义务的往往就那一两个触发条件。我见过太多团队把精力花在"这个许可证严不严"的争论上,却没搞清楚自己的使用方式到底有没有触发义务。这一节专门拆触发条件。

2.1 AGPL 的"网络交互"到底怎么界定

AGPL 的触发点是"用户通过网络与修改后的软件交互"。这里有几个关键词需要逐个抠:

  • 修改后的软件:如果你原封不动地用,理论上义务较轻;但只要你改了、或者基于它构建了衍生作品,义务就明确了。实践中"衍生作品"的边界很模糊,链接、动态加载、进程间通信算不算,法律上并没有全球统一的答案。
  • 网络交互:用户通过浏览器、API、移动端访问你的服务,都算。哪怕只是内部系统,只要"用户"能通过网络用上,就可能触发。
  • 提供源码:义务是向这些网络用户提供源码,不是向全世界公开。但实操中你很难只给一部分人,通常的做法是提供一个源码获取入口。

我个人的经验判断是:只要你的产品是面向外部用户的在线服务,并且用到了 AGPL 组件,就默认按"会触发"来评估,别抱侥幸心理。内部工具、纯离线分发的场景可以再具体分析,但边界案例一定要让法务介入,不要自己拍脑袋。

2.2 SSPL 的"服务栈"范围为什么争议大

SSPL 最让人头疼的是"所有配套组件"这个表述。什么叫配套?数据库跑起来需要操作系统、需要容器运行时、需要编排工具、需要监控,这些算不算?许可证文本里列举了一些例子,但列举本身就不可能穷尽。

这种模糊性带来两个后果:一是使用者很难自证合规,因为你永远不确定自己漏了哪个组件;二是它实质上把义务扩大到了"整个服务的技术栈",这已经超出了传统 copyleft 对"衍生作品"的理解范围。这也是它被开源定义拒之门外的核心原因——限制过于宽泛,构成了对特定使用领域(云服务)的歧视。

对商业项目来说,这意味着:如果你打算基于 SSPL 软件对外提供托管服务,合规成本可能高到不现实。很多团队评估后的结论是"要么不用,要么只用在不对外服务的内部场景"。

2.3 BSL 的"商业竞争"是个需要读定义的词

BSL 的触发条件里,"商业竞争"是最需要逐字读的部分。不同项目对它的定义不一样,有的写得比较宽,把"提供类似功能的服务"都算进去;有的写得比较窄,只针对"直接替代品"。变更日期也要看清楚,是固定日期还是"发布后 N 年",以及到期后转成哪个具体许可证。

这里有个容易忽略的点:BSL 通常允许你把软件用于非生产环境,比如开发、测试、内部评估。但"生产环境"和"非生产环境"的界线,在有些团队里并不清晰,尤其是预发布环境、灰度环境算不算生产,最好提前和许可方的 FAQ 或法务确认。

2.4 一个判断流程,帮你快速定位风险

我把实际评估时的思路整理成一个简单流程,你可以照着走一遍:

  1. 确认组件清单:先把项目依赖里所有 AGPL、SSPL、BSL 的组件列出来,包括间接依赖。这一步用依赖分析工具跑一遍最靠谱,人工翻 lock 文件容易漏。
  2. 判断使用方式:是原样使用、修改后使用,还是作为服务对外提供?分别对应不同的义务等级。
  3. 判断是否对外:服务是否面向外部用户?是否收费?是否作为产品的一部分售卖?
  4. 判断竞争关系(仅 BSL):你的用途是否落在许可证定义的"商业竞争"范围内?
  5. 确认时间窗口(仅 BSL):当前是否在变更日期之前?到期后你的使用方式是否仍然合规?
  6. 法务复核:边界模糊的,一律交给法务,别自己下结论。

这个流程不复杂,但每一步都不能跳。我见过有团队在第 1 步就漏了间接依赖,结果上线后才发现问题,返工成本很高。

3. 落到商业项目上:三种许可证各自会咬到哪里

理解了条款和触发条件,接下来要回答的是每个做产品的人最关心的问题:这东西到底会不会影响我的商业模式?下面按许可证分别说。

3.1 AGPL 对 SaaS 产品的实际约束

对纯 SaaS 产品来说,AGPL 是最需要认真对待的一个。因为 SaaS 的典型形态就是"用户通过网络使用服务",几乎天然落在 AGPL 的触发条件里。如果你的服务里用了 AGPL 组件,并且做了修改或基于它构建了衍生作品,那么你需要向网络用户提供源码。

这里有几个实操层面的细节值得说:

  • "提供源码"不等于"公开到 GitHub":义务是向使用服务的用户提供,你可以做一个源码下载页面,或者随服务条款附上获取方式。但很多团队为了省事直接公开,这也可以,只是要评估是否愿意。
  • 修改的界定:如果你只是调用 AGPL 库的 API,没有改它的源码,是否构成衍生作品?这个在法律上有争议,不同司法辖区的理解可能不同。保守做法是假设构成,激进做法是找法务出意见。我的建议是:核心业务逻辑不要和 AGPL 组件深度耦合,降低风险。
  • 隔离架构可以降低风险:把 AGPL 组件放在独立的服务里,通过进程边界或网络接口通信,而不是链接进主程序,是一种常见的风险缓解手段。但这不是万能药,是否构成衍生作品仍要看具体情况。

我参与过的一个项目,早期为了快速上线用了一个 AGPL 的组件做后台任务调度,后来产品要融资,尽调时被问到这块,最后是把该组件替换成了 Apache 2.0 的替代方案才过。教训是:早期选型时多花半天看许可证,比后期返工便宜得多。

3.2 SSPL 对托管服务模式的直接冲击

SSPL 的矛头指向很明确:把软件托管起来对外提供服务。如果你的商业模式正好是这个,那 SSPL 基本等于"此路不通",除非你愿意开放整套服务栈。

实际影响体现在几个方面:

  • 合规成本极高:开放整套服务栈意味着你的运维体系、自动化脚本、监控配置都要公开,这些往往是团队的隐性资产。
  • 商业机密暴露:服务栈里可能包含你的调度策略、容量规划逻辑,这些公开后竞争优势会被削弱。
  • 生态接受度低:很多企业在做技术选型时,会把 SSPL 组件直接排除在候选之外,因为合规不确定性太高。这意味着基于 SSPL 的软件在商业生态里的采用面会受限。

所以对大多数做托管服务的团队来说,SSPL 组件的现实选择是:要么不用,要么只用在不对外提供服务的内部工具场景,并且做好隔离。

3.3 BSL 的"窗口期"怎么用才不吃亏

BSL 对商业项目的影响相对温和,但需要你主动管理时间维度。核心是两点:变更日期和竞争定义。

  • 变更日期之前:你可以用于非生产环境,生产用途要看是否构成商业竞争。如果你的用途和许可方不冲突,通常没问题;如果冲突,就要么等变更日期,要么谈商业授权。
  • 变更日期之后:该版本转为开源许可证,义务按新许可证执行。注意是"该版本",不是"所有版本",新发布的版本可能有新的变更日期。
  • 商业授权选项:很多 BSL 项目同时提供商业授权,如果你等不及变更日期,可以付费获得豁免。这也是 BSL 设计的一部分——它本质上是一种"先试用后付费或等开源"的机制。

我见过有团队把 BSL 组件的变更日期记在项目文档里,到期前评估是否要升级版本或切换方案,这个习惯值得学。时间维度是 BSL 最容易被忽略的部分,很多人只看了"源码可见"就以为随便用,结果踩在竞争定义上。

3.4 混合依赖场景下的组合风险

真实项目很少只用一个许可证的组件,往往是 Apache、MIT、GPL、AGPL、BSL 混在一起。这时候风险不是简单叠加,而是可能产生组合效应。

举个典型场景:你的主程序是 MIT,依赖了一个 Apache 2.0 的库,这个库又间接依赖了一个 AGPL 的组件。这时候 AGPL 的义务会不会传导到你的主程序?取决于依赖关系和调用方式。如果 AGPL 组件是独立进程,风险较低;如果是链接进来的,风险就高。

处理混合依赖,我的经验是:

  • 用工具生成完整的依赖许可证清单,不要只看直接依赖。
  • 对每个 copyleft 类组件单独评估触发条件,不要一刀切。
  • 在架构上尽量把高风险组件隔离到独立服务。
  • 建立许可证准入清单,新引入依赖时先查清单。

这套做法不复杂,但需要制度化,靠人肉记忆迟早出事。

4. 实操:怎么给项目做一次许可证体检

前面讲的都是判断逻辑,这一节给一套可以直接落地的体检流程。我按步骤写,你可以照着在自己项目里跑一遍。

4.1 第一步:生成依赖许可证清单

不同语言生态工具不同,思路一致:把依赖树展开,输出每个包的许可证标识。

以 Node.js 生态为例,可以用 license-checker 这类工具:

npx license-checker --summary

它会输出依赖包里各种许可证的统计。要看明细,去掉--summary,加上--json输出结构化结果,方便后续筛选。

Python 生态可以用 pip-licenses:

pip install pip-licenses pip-licenses --format=json --with-urls

Java 生态用 Maven 的 license 插件,Go 生态可以用 go-licenses。工具选哪个不重要,重要的是把间接依赖也覆盖到,这是最容易漏的地方。

生成清单后,重点筛出 AGPL、SSPL、BSL 三类,单独列一张表跟踪。

4.2 第二步:逐个确认使用方式和触发条件

对筛出来的每个组件,回答几个问题:

  • 是直接依赖还是间接依赖?
  • 是原样使用还是修改过?
  • 是链接进主程序,还是独立进程/独立服务?
  • 是否对外提供服务?是否收费?
  • 如果是 BSL,变更日期是什么?当前用途是否构成商业竞争?

把答案填进表格,触发条件不明确的标记出来,交给法务。这一步不要追求一次到位,先把明显的风险点找出来。

4.3 第三步:设计隔离或替换方案

对确认有风险的组件,两条路:隔离或替换。

隔离的常见手段:

  • 独立进程部署,通过 HTTP/gRPC 等网络接口通信,避免链接。
  • 独立服务部署,明确服务边界,避免共享内存或动态加载。
  • 容器化隔离,把组件放在单独容器里,网络调用。

替换的思路:

  • 找同类功能的宽松许可证替代品(Apache 2.0、MIT、BSD)。
  • 自研核心逻辑,只保留必要的宽松组件。
  • 商业授权,如果替代成本太高且许可方提供商业授权。

隔离不是绝对安全,是否构成衍生作品仍要看具体法律解释,但能显著降低风险。替换是更彻底的方案,成本也更高,需要权衡。

4.4 第四步:建立准入清单和复查机制

体检不是一次性工作,依赖会变,版本会升级。建议做两件事:

  • 准入清单:列出团队允许使用的许可证白名单,新依赖引入前先查。AGPL、SSPL 默认不进白名单,需要单独审批。
  • 定期复查:每个迭代或每个季度跑一次依赖清单,对比上次结果,看有没有新增高风险组件。

这两件事听起来像流程负担,但实际执行下来成本很低,收益是避免上线前夜被叫停。我见过太多团队在融资尽调或大客户采购时才想起查许可证,那时候返工成本是平时的好几倍。

5. 几个真实场景里的判断经验

条款和流程讲完了,最后分享几个我在实际项目里遇到的判断场景,都是那种"文档里不会写、但真会碰到"的情况。

5.1 内部系统和对外系统的界线

有个项目早期把 AGPL 组件用在了内部管理后台,团队觉得"内部用不对外,应该没事"。后来这个后台开放了一部分功能给外部合作方登录使用,触发条件就变了。这类情况的关键是:触发条件看的是"谁在用",不是"系统叫什么名字"。内部系统一旦对外开口,就要重新评估。

我的做法是给每个系统标注"服务对象"字段,内部、合作方、公众三档,任何一档变化都触发许可证复查。这个字段维护成本很低,但能避免很多意外。

5.2 预发布环境算不算生产

BSL 里"生产用途"的界定,在预发布、灰度、演示环境上经常模糊。有的团队把演示环境当生产用(给客户演示),有的把灰度环境当生产用(真实流量)。我的建议是:只要环境里有真实用户数据或真实交易,就按生产对待,别在定义上抠字眼。真要和许可方确认,也比事后解释强。

5.3 间接依赖的"隐形"风险

间接依赖是最容易漏的。有个项目直接依赖全是 MIT 和 Apache,团队以为很干净,结果依赖树深处有一个 AGPL 组件,是通过某个中间库带进来的。这种风险靠人工翻 lock 文件很难发现,必须用工具展开完整依赖树。

工具跑出来的结果里,注意看那些"传递依赖"标记,别只看顶层。发现高风险间接依赖后,要么升级中间库到不带该依赖的版本,要么用依赖覆盖机制排除,要么换中间库。

5.4 许可证版本差异不能忽略

同一个许可证不同版本,条款可能差很多。比如 GPL v2 和 v3 在专利授权、反规避条款上有明显差异;AGPL 也有版本差异。评估时一定要确认具体版本号,不能只说"这是 AGPL"。依赖清单里通常带版本信息,别把它当噪音忽略掉。

5.5 和法务协作的正确姿势

很多开发者觉得法务不懂技术,沟通效率低。我的经验是:带着结构化信息去找法务,而不是带着问题去。具体做法是准备一张表,列出组件名、版本、许可证、使用方式、是否对外、你的初步判断,法务基于这些信息给意见,效率高很多。空手去问"这个能不能用",得到的往往是"要看情况",对推进项目没帮助。

另外,法务的意见要落到文档里,形成团队可复用的判断依据,别每次重新问一遍。时间长了,团队自己就能处理大部分常规判断,只把真正的边界案例交给法务。

5.6 选型阶段就把许可证纳入评估维度

最后一条经验,也是最值钱的一条:许可证应该是技术选型的固定维度,而不是事后补课。评估一个组件时,除了看功能、性能、社区活跃度,顺手看一眼许可证,成本几乎为零,但能避免后期大返工。

我现在的习惯是,任何新组件进入候选名单,先在准入清单里查许可证,高风险的一律标注,需要用的走审批。这个习惯坚持下来,项目里基本不会再出现"上线前才发现许可证问题"的情况。

许可证这件事,说到底不是法律条文背诵,而是对自己项目使用方式的清醒认知。搞清楚触发条件,做好依赖清单,建立准入机制,大部分风险都能提前化解。真正难的不是条款本身,而是团队有没有把它当成一件需要持续管理的事。

返回列表