AGPL-3.0商用合规指南:SaaS场景源码开放边界与实操
1. 从一次代码审计说起AGPL-3.0到底管什么去年帮一个做企业内部工具的朋友看代码他们用了一个基于AGPL-3.0协议的开源组件做二次开发然后打包成SaaS服务卖给客户。我当时就问了一句你们的源码对外公开了吗他一脸茫然地说我们又没分发软件只是放在自己服务器上跑为什么要公开这个问题其实非常典型。很多开发者对GPL系列协议的理解停留在开源软件不能商用这个层面而AGPL-3.0恰恰是GPL家族里最容易被误解、也最容易踩雷的一个。它的全称是GNU Affero General Public License version 3由自由软件基金会FSF发布核心目标是堵住GPL在云服务场景下的一个漏洞——你可以不分发软件但只要你通过网络提供服务就必须把源码交出来。这篇文章适合三类人看一是正在做技术选型、纠结要不要引入AGPL组件的后端和架构同学二是准备把开源项目商业化的独立开发者三是需要给团队做开源合规培训的技术负责人。我会从协议的核心条款拆起把商用边界、合规操作、常见误区和实际案例都讲透让你看完能直接判断自己手里的项目到底能不能用、怎么用。先说结论AGPL-3.0不是不能商用而是商用之后你要承担源码开放的义务。这个义务的触发条件、覆盖范围、执行方式才是真正需要搞清楚的东西。2. AGPL-3.0的核心条款拆解它和GPL到底差在哪2.1 第13条网络交互触发的源码开放义务AGPL-3.0和GPL-3.0的正文几乎一模一样唯一的实质性差异就是新增的第13条。这一条的核心意思是如果你修改了AGPL授权的程序并且让用户通过网络与这个程序交互那么你必须向这些用户提供你修改后的完整源码。注意这里的几个关键词。修改是触发条件之一但并不是唯一条件——即使你没有修改只是原样部署第13条同样要求你提供源码。这一点很多人搞错了以为只要不改代码就没问题。实际上只要你通过网络向用户提供了服务用户就有权获取你运行的这个版本的源码。通过网络交互的定义也比较宽泛。用户通过浏览器访问你的Web应用算通过API调用算甚至通过移动端App间接调用后端服务也算。FSF在官方FAQ里明确说过如果用户能通过网络与程序进行交互就满足触发条件。这意味着SaaS场景几乎全覆盖。2.2 与GPL-3.0的继承关系copyleft的传染性AGPL-3.0继承了GPL-3.0的强copyleft特性。所谓copyleft就是以相同方式共享——你基于AGPL代码做的衍生作品必须以AGPL协议发布。这里的衍生作品在法律上的界定比较复杂但技术社区普遍接受的标准是如果你的代码和AGPL代码形成了紧密的耦合关系比如链接同一个进程、共享数据结构、互相调用函数那就构成衍生作品。反过来如果你的程序只是通过命令行调用AGPL工具、通过HTTP请求访问AGPL服务、或者通过标准输入输出传递数据通常被认为是聚合而非衍生不受copyleft约束。这个边界在实际操作中经常引发争议后面我会专门用一节来讲怎么判断。2.3 专利授权与终止条款比GPL-2.0更现代的设计AGPL-3.0还包含明确的专利授权条款。任何贡献者通过提交代码默示授予用户使用其专利的权利。如果用户对贡献者发起专利诉讼授权自动终止。这个设计比GPL-2.0更完善对商用企业来说其实是一种保护——你不用担心用了某个AGPL组件之后被原作者用专利卡脖子。终止条款方面AGPL-3.0给了30天的补救期。如果你违反了协议在收到通知后30天内完成整改授权可以恢复。这个缓冲期对商用团队比较友好不至于因为一次疏忽就永久失去使用权。对比维度GPL-3.0AGPL-3.0源码开放触发条件分发软件分发软件或网络提供服务适用场景桌面软件、嵌入式SaaS、Web服务、API服务专利授权有有违约补救期30天30天与GPL-2.0兼容性不兼容不兼容3. 商用场景下的边界判定什么情况下你必须开源3.1 SaaS部署最典型的触发场景假设你用了一个AGPL-3.0的前端框架或者后端服务组件部署在自己的云服务器上用户通过浏览器访问。这种情况下你几乎肯定需要向用户提供源码。具体来说你需要提供的是 Corresponding Source——包括你修改过的部分、以及用来编译、安装、运行该程序所需的所有脚本和配置文件。这里有个细节容易被忽略你不需要把源码公开到GitHub上让全世界看到只需要向通过网络与你交互的用户提供。理论上你可以只在用户请求时通过邮件发送源码包。但实际操作中大多数团队会选择直接公开仓库因为维护一个按需提供的流程成本更高而且容易遗漏。3.2 内部使用不触发开放义务如果你的AGPL组件只在内网使用用户仅限于公司员工且不对外提供服务那么不触发第13条。因为通过网络交互的用户范围是有限的内部人员FSF认为这不构成对外提供服务。但要注意如果内网系统后来对外开放了或者被集成到了对外产品中义务就产生了。我见过一个案例某公司用AGPL组件做内部报表系统后来业务部门把报表功能开放给了合作伙伴访问结果就踩线了。所以判断标准不是部署在哪里而是谁在通过网络使用它。3.3 工具链使用通常不构成衍生作品如果你只是用AGPL授权的编译器、构建工具、代码生成器来处理你的代码通常不构成衍生作品。比如你用某个AGPL的代码生成工具生成了代码生成的代码本身不受AGPL约束。但如果生成工具把自身的运行时代码嵌入了输出结果那就另当别论。这个边界在FSF的FAQ里有说明使用GPL工具运行程序不会使程序的输出受GPL约束除非工具把自身的一部分复制到了输出中。AGPL同理。3.4 动态链接与静态链接技术细节决定法律风险动态链接AGPL库通常被认为构成衍生作品需要开源。静态链接更是明确构成衍生作品。但如果是通过进程间通信IPC、RPC、消息队列等方式调用独立的AGPL服务一般被认为是聚合不需要开源你的调用方代码。这个判断标准不是绝对的最终还是要看具体的耦合程度。我的经验是如果你不确定就假设需要开源然后找法律顾问确认。开源合规这件事宁可保守一点。提示AGPL-3.0的源码开放义务只针对你修改后的AGPL程序本身不要求你公开整个应用的所有代码。但如果你把AGPL代码和自有代码编译进了同一个二进制文件那整个二进制文件的源码都需要开放。4. 合规实操从引入到发布的完整流程4.1 引入前的许可证审查清单在把任何AGPL组件引入项目之前我建议走一遍这个清单确认组件的确切许可证版本。有些项目写的是GPL但实际是AGPL或者双协议授权。看LICENSE文件和package.json里的license字段。确认是否有商业授权选项。很多AGPL项目采用双协议模式比如MySQL、MongoDB早期、Grafana等你可以购买商业许可证来规避AGPL义务。评估使用方式。是链接调用、独立部署、还是仅作为开发工具不同方式的风险等级不同。确认团队能否接受开源义务。如果这个项目是公司的核心产品开源源码可能不现实那就需要考虑替代方案。记录审查结论。把组件名称、版本、许可证、使用方式、审查人、审查日期记录下来形成合规档案。这个清单看起来简单但实际执行中经常发现遗漏。我见过一个团队用了某个AGPL的JavaScript库以为前端代码不算分发结果被原作者发邮件要求开源。前端代码通过网络传输到用户浏览器本身就是一种分发形式。4.2 源码开放的边界哪些代码必须给哪些可以保留这是商用团队最关心的问题。根据AGPL-3.0的原文你需要提供的是Corresponding Source具体包括你修改过的AGPL代码部分与AGPL代码链接、合并、共享数据结构的自有代码用于生成、安装、运行目标代码的脚本和配置文件接口定义文件、编译脚本、安装脚本可以保留不开源的部分独立运行的、通过标准协议与AGPL服务通信的客户端代码与AGPL代码没有编译级耦合的独立模块你自有的、不包含AGPL代码的业务逻辑前提是能清晰分离实际操作中最稳妥的做法是把AGPL组件隔离成独立的微服务通过HTTP或gRPC对外提供服务。这样你的主应用代码就不构成衍生作品只需要开源你对AGPL服务本身的修改。4.3 隔离架构的设计模式如果你确实需要用AGPL组件但又不想开源主应用隔离架构是唯一可行的技术方案。具体做法把AGPL组件部署为独立进程或独立容器通过定义良好的API接口与主应用通信主应用不链接AGPL库不共享内存不直接调用其内部函数AGPL服务的修改部分单独维护按AGPL协议开源主应用代码保持闭源这种架构的代价是增加了网络开销和运维复杂度但换来了合规安全。我帮一个团队做过这种改造把一个AGPL的报表引擎从主应用里拆出来单独部署主应用通过REST API调用。改造花了两周但避免了整个产品开源的风险。注意隔离架构的有效性取决于隔离的彻底程度。如果两个进程之间传递的是复杂的数据结构或者存在紧密的调用关系法院可能仍然认定构成衍生作品。建议在架构设计阶段就咨询法律意见。4.4 发布时的合规检查步骤当你准备发布一个包含AGPL组件的产品时按这个顺序检查确认所有AGPL组件的版本和修改记录准备Corresponding Source包包括修改后的AGPL代码和构建脚本在产品的关于页面或文档中放置源码获取链接确保源码包可以通过网络下载且下载链接长期有效在源码包中保留原始版权声明和许可证文本如果修改了AGPL代码在文件头添加修改说明和日期记录发布版本与源码版本的对应关系这套流程看起来繁琐但一旦建立起来后续维护成本并不高。关键是要在CI/CD流程中固化这些检查点避免人为遗漏。5. 常见误区与真实踩坑案例5.1 我们没分发软件所以不用开源这是最常见的误解。AGPL-3.0第13条专门针对网络服务场景就是为了堵住这个漏洞。只要用户能通过网络与你的服务交互你就需要提供源码。SaaS模式恰恰是AGPL重点覆盖的场景。我见过一个创业团队用AGPL的数据库中间件做了一套数据查询服务对外提供API。他们一直以为软件没离开我们的服务器就不算分发。后来被社区发现收到了律师函最后不得不把整个查询服务的源码开源包括他们自研的查询优化模块。5.2 我们只是内部用不对外内部使用的边界在于用户范围。如果只有公司员工通过内网访问通常没问题。但如果外部合作伙伴、客户、甚至通过公开网络访问的任何人能用就触发了义务。有个案例是某公司的运维平台用了AGPL组件后来把监控面板的只读权限开放给了客户客户可以通过浏览器查看。这个开放给客户的动作就让内部系统变成了对外服务。5.3 我们改了代码但没发布所以不用开源修改与否不影响第13条的触发。即使你原样使用只要通过网络提供服务就需要提供源码。修改只是让你需要额外提供修改部分。5.4 我们用Docker部署不算分发Docker镜像的分发确实是分发但AGPL第13条管的是网络交互不是镜像分发。即使你不分发镜像只在服务器上跑容器用户通过网络访问服务同样触发义务。Docker在这里不是避风港。5.5 真实案例从收到通知到完成合规的完整过程去年有个做在线文档协作的团队找到我他们用了一个AGPL的富文本编辑器组件产品已经上线运营了一年多。原作者通过邮件联系他们指出他们没有遵守AGPL协议。他们的处理过程是这样的第一步确认事实。他们确实用了AGPL组件确实通过网络提供服务确实没有开源。事实清楚没有争议。第二步评估影响范围。他们梳理了代码发现AGPL组件只用于编辑器部分与主应用通过iframe隔离通信通过postMessage。这个隔离程度比较好意味着只需要开源编辑器相关的修改不需要开源整个产品。第三步制定整改方案。他们决定把编辑器的修改部分开源到GitHub同时在产品文档中添加源码链接。主应用代码保持闭源。第四步与原作者沟通。他们回复了邮件说明了整改计划并询问是否有其他要求。原作者表示接受但要求他们在源码包中保留原始版权声明。第五步执行整改。他们花了一周时间整理代码、添加许可证声明、建立源码仓库、更新产品文档。第六步确认合规。整改完成后他们再次联系原作者确认对方确认没有问题。整个过程从收到通知到完成整改大约用了三周。关键是他们没有拖延也没有试图狡辩而是积极沟通、快速行动。这个案例说明AGPL违规并不是世界末日但前提是你得认真对待。6. 替代方案与选型建议什么时候该避开AGPL6.1 宽松许可证的替代品如果你的项目确实无法接受AGPL的开源义务可以考虑以下替代方案MIT许可证最宽松几乎没有任何限制只需保留版权声明。适合大多数商业项目。Apache-2.0宽松包含明确的专利授权适合企业级项目。BSD系列同样宽松条款简单。MPL-2.0弱copyleft修改的文件需要开源但与自有代码链接不触发传染。适合想保留部分开源的场景。LGPL弱copyleft动态链接不触发传染适合库类组件。选型时的判断逻辑如果你的项目需要闭源商用优先选MIT或Apache-2.0。如果需要专利保护选Apache-2.0。如果希望修改部分回馈社区但不想开源全部选MPL-2.0。6.2 双协议授权的商业版本很多AGPL项目提供商业授权选项。你可以购买商业许可证在闭源条件下使用。常见的双协议项目包括项目开源协议商业授权MySQLGPL-2.0有GrafanaAGPL-3.0有MongoDBSSPL有RedisRSALv2/SSPLv1有ElasticsearchSSPL/Elastic License有购买商业授权的成本需要和自研成本、合规成本做对比。对于核心业务依赖的组件商业授权往往是更省心的选择。6.3 自研替代的成本评估如果既不想开源又不想买商业授权那就只能自研替代。自研的成本包括开发成本、测试成本、维护成本、以及功能差距带来的业务损失。我一般建议团队先算一笔账自研需要多少人月这些人月的成本是多少对比商业授权的年费哪个更划算。很多时候商业授权的费用远低于自研成本。但如果是非核心组件自研一个简化版可能更经济。6.4 选型决策树我总结了一个简单的决策流程这个组件是不是核心业务依赖如果是进入第2步如果不是考虑用宽松协议的替代品。能否接受开源义务如果能直接用AGPL版本如果不能进入第3步。有没有商业授权如果有评估费用是否可接受如果没有进入第4步。能否通过隔离架构规避如果能设计隔离方案如果不能进入第5步。自研替代的成本是否可接受如果可接受自研如果不可接受重新评估需求或寻找其他方案。这个决策树不是绝对的但能帮你快速理清思路。7. 团队协作中的AGPL合规管理7.1 建立开源组件准入流程合规不是一个人的事需要流程保障。我建议在团队中建立这样的准入流程任何新引入的开源组件必须经过许可证审查审查结果记录在案包括组件名、版本、许可证、使用方式、风险等级高风险组件如AGPL需要技术负责人和法律顾问双重确认准入流程嵌入到代码审查环节没有审查记录的PR不予合并这个流程的关键是嵌入现有工作流而不是另起一套。开发同学最反感额外的流程但如果把许可证检查做成CI的一个步骤大家接受度会高很多。7.2 自动化工具的使用手动审查容易遗漏建议用自动化工具辅助FOSSA商业工具支持许可证扫描和合规管理Black Duck商业工具功能全面ScanCode Toolkit开源工具可以集成到CI中license-checkerNode.js生态的许可证检查工具pip-licensesPython生态的许可证检查工具这些工具能自动识别依赖树中的许可证类型标记出AGPL、GPL等高风险许可证。但工具不是万能的它只能识别标准许可证文本对于自定义许可证或双协议授权还是需要人工判断。7.3 定期审计与文档维护开源合规不是一次性的工作需要定期审计。我建议每季度做一次全量扫描检查是否有新增的AGPL依赖是否有许可证变更是否有未记录的修改。文档维护方面至少要保留以下记录开源组件清单SBOM每个组件的许可证和审查记录AGPL组件的修改记录源码开放的记录如果有与原作者或社区的沟通记录这些文档在遇到合规问题时能帮你快速定位和响应。7.4 与法务团队的协作要点技术团队和法务团队的沟通经常存在障碍。技术人员觉得法务不懂技术法务觉得技术人员不重视风险。我的经验是技术人员应该主动做两件事第一把技术问题翻译成法律语言。不要说我们动态链接了AGPL库而要说我们的代码和AGPL代码编译在同一个二进制文件中构成了衍生作品。第二提供明确的选项和后果。不要只问这个能不能用而要给出方案A需要开源方案B需要购买授权方案C需要自研各自的成本和风险是什么。这样法务团队才能给出有效的建议而不是笼统地说有风险建议不用。8. 我个人的几条实操心得踩过几次坑之后我总结了几个比较实用的经验。第一把AGPL组件当成需要付费的组件来对待。要么付商业授权的钱要么付开源的成本要么付自研的代价。天下没有免费的午餐AGPL的免费是有条件的。第二隔离架构要早做。如果项目初期就决定用AGPL组件一开始就把隔离架构设计好后期改造的成本会低很多。我见过太多团队后期被迫重构花的钱比一开始买商业授权还多。第三源码开放不等于核心泄露。很多人把源码看得太重实际上大多数产品的竞争力不在代码本身而在运营、数据、生态。开源一部分代码有时候反而能带来社区贡献和品牌曝光。第四保留证据。无论是商业授权的购买记录还是源码开放的记录还是与作者的沟通记录都要保存好。万一出现争议这些证据能帮你省很多事。第五不要心存侥幸。AGPL社区虽然不像某些商业公司那样积极维权但一旦被发现处理起来很麻烦。主动合规的成本永远低于被动整改的成本。最后分享一个判断技巧如果你不确定某个用法是否触发AGPL义务就问自己一个问题——用户能不能通过网络使用到这个AGPL程序的功能如果答案是能那就假设需要开源然后找专业人士确认。这个简单的判断标准能帮你避开大部分坑。