searchusermenu
点赞
收藏
评论
分享
原创

开源软件合规与风险基础

2025-12-23 01:24:38
37
0

前言:致每一位代码创作者

在当今的软件开发生态中,开源软件(Open Source Software, OSS)已经成为基础设施。正如搭积木一样,我们不再从零烧制砖块,而是引用成熟的开源组件来构建宏伟的数字大厦。

然而,“开源”不等于“免费”,更不等于“放弃版权”

每一行开源代码背后,都附带着一份法律契约——许可证(License)。作为公司的核心资产建设者,大家在引入外部代码时,实际上是在代表公司签署一份份法律合同。一旦违约,轻则导致公司核心代码被迫公开(GPL传染),重则面临巨额赔偿、产品下架甚至上市受阻。

本文摘旨在打破法律术语的壁垒,用开发者的语言,讲述开源合规的法律基础,许可证的内核。合规不是为了束缚手脚,而是为了让我们在安全的前提下,走得更快更稳!

第1部分:认知篇 —— 代码资产与法律基石

核心观念: 代码即资产,许可证即合同

1.1 从软件的版权(Copyright)说起

根据《伯尔尼公约》及各国著作权法,软件代码属于“文字作品”。代码一旦被写出来(固定在存储介质上),作者就自动拥有了版权(Copyright)。
这意味着:除非作者明确地授权给你,否则你没有任何权利去使用复制修改分发这些代码。
在中国,软件的版权更常见的称谓是:软件著作权

1.1.1 版权的自动保护原则

与专利权、商标权等需要显示申请注册不同,版权无需额为申请,而是当你完成开发时,就自动拥有了版权!与是否公开发表无关。

1.1.2 版权的归属

版权的归属因创作环境和过程不同而有所区别,常见的包括:

  1. 个人创作: 版权归个人所有
  2. 联合创作: 首先,遵循约定; 如果无约定,作品可分割使用,则按贡献划分各自占有贡献部分的版权;不可分割使用的,由合作开发者共同享有,通过协商一致行使。注意,我们在开源社区获取到的开源软件,大多属于这类版权归属。
  3. 劳务创作:在公司工作中开发的软件,版权属于公司。
  4. 委托创作:首先,遵循约定;如果未约定的,版权归受托人。
  5. 其他:例如由国家机关下达任务开发的软件,版权权归属与行使由项目任务书或合同约定;无约定,著作权属于接受任务的法人、组织、或个人。

注意:软件版权可以继承,转让。

1.1.3 软件侵权风险

如果涉嫌侵权其他软件,依据不同的场景和严重程度,可能涉及到民事责任、行政责任、刑事责任。

民事责任(赔钱、道歉、下架)

  • 停止侵害: 法院可下令立即停止使用、分发该软件(对于已上线的业务是毁灭性打击)。
  • 赔偿损失:按照权利人受到的实际损失计算;或者按照侵权人(我司)因此获得的违法所得计算;如果都算不出来,法院可判决 500 万元以下 的法定赔偿。
  • 惩罚性赔偿: 对于故意侵权且情节严重的,可以处以 1倍以上 5倍以下 的惩罚性赔偿。

行政责任(罚款、查封)

如果侵权行为同时损害了公共利益,版权行政管理部门(如版权局)可以:

  • 责令停止侵权行为。
  • 没收违法所得。
  • 没收、销毁侵权复制品。
  • 罚款。

刑事责任(坐牢)—— 侵犯著作权罪

这是达摩克利斯之剑。根据《刑法》第二百一十七条,以营利为目的,未经著作权人许可,复制发行其计算机软件:

  • 违法所得数额较大(>3万元) 或者有其他严重情节的:处 3年以下 有期徒刑。
  • 违法所得数额巨大(>25万元) 或者有其他特别严重情节的:处 3年以上 7年以下 有期徒刑,并处罚金。
  • 警示案例: 某公司为了赶进度,破解并使用了某商业软件库(或违规修改并闭源使用了 GPL 软件进行高额获利),不仅公司面临巨额罚款,公司的直接责任人(CTO或项目负责人)可能面临刑事指控。

当然,对于商业公司而言,隐形风险还包括: 产品发行受阻导致的资金问题、市场问题,公司品牌形象与公众形象问题,被迫开源导致的核心技术泄露问题等等!

对于开源软件,违反开源协议(如使用了 GPL 但不开源),在法律上不仅仅是违约(违反合同),更是侵犯著作权。后果可能比你想象的严重得多。

1.2 许可证(License)的法律本质

前面已明确,版权的作用是保护软件不被他人修改、复制、使用、分发等; 但为了发挥软件的价值,版权所有者可以通过某种**“契约”形式,授权给特定的人(或群体、组织)某些权利,如修改、使用、售卖、分发等,同时附加一定的限制条件。
对于商业软件而已,授权 通常是通过
采购合同**达成的!

对于开源软件,因版权所有者和使用者的物理位置和信息隔离,难以有效的达成正式合同性的契约。为解该问题,通用的做法是在软件发布时,附一份**许可证(License)**文件(或声明片段),用于指定授权给使用者的权益范围,同时对使用方式、使用范围、使用过程、权益再处置等做出限制。其规则为:你使用该软件,代表你认可该许可证中所有条款;同时,承诺在使用过程中严格遵守许可中的所有条款

换言之:

许可证,是版权持有者(Licensor)发给使用者(Licensee)的一个框架式合同,它授权给使用者某些版权保护范围内的权益,同时指定了一些使用规矩(义务条款和限制条款);
当使用者严格遵循许可证指定的规矩时,则可以获得许可证中给定的权益;反之,当使用者行使了权益缺未遵循这些使用规矩时,则认为是侵权。

这便是许可证的法律本质!
许可证中指定的规矩 则称为合规义务, 再后续章节中会深入探讨!

1.2.1 许可(Licensing) vs 转让(Assignment)

经常,我们引入开源组件,其中附带一份许可证文件。此情形下,我们获得了该软件的许可(Licensing)
但需要注意:我们获得的是使用许可,而非所有权/版权。原作者依然是老大, 依然不能“为所欲为”。

不同的许可证,在授予使用者权益时的范围和粒度有很大差别,大体分以下几种:

  1. 完全放弃版权,授权你“为所欲为” —— Public Domain 类型许可/零义务许可;
  2. 主要保留版权归属声明,基本不限制你的使用方式和范围 —— Permissive 类型许可/宽松许可;
  3. 强调软件自由,严格要求遵循相同的使用方式(开发源码,禁止调整许可条款) —— Copyleft类型许可/ 严格许可;
  4. 其他一些带领域限制、技术限制、定制化条款的许可 —— 专业领域许可、私有许可(含商业许可);

在后续章节中,本文会进一探讨不同许可的授权范围和限制条款,并讨论这些差异如何影响使用者...

1.2.2 默认的“保留所有权利”

这是一个值得强调的事情!

在 GitHub 或 GitLab 上,如果一个仓库没有任何 LICENSE 文件,这并不代表它是公有领域(Public Domain)的;恰恰相反,这代表作者 保留所有权利 (All Rights Reserved)
即使代码公开可见,你下载、复制、引用、修改、分发的行为在法律上均属于侵权。

因此:
严格禁止引入无 License 的“裸奔代码”

1.2.3 触发开源软件合规义务的“扳机” —— 分发(Distribution)

虽然版权明确了在未授权情况下复制、修改、使用、分发他人的软件作品均属于侵权,但在实践中却存在很多争议或灰色地带。国内,主要的法律依据是《著作权法》和《计算软件保护条例》。下表是对是否构成软件侵权的经典场景一个概览:

特征 侵犯著作权的情形 不侵犯著作权的情形
核心行为 未经许可的复制、分发、修改、商业使用、规避保护措施 合法使用、独立创作、为兼容的反向工程、合理使用
主观目的 通常具有商业目的或传播目的 个人使用、学习研究、实现兼容、执行公务
与权利冲突 直接对抗权利人的专有权利 属于法律明确规定的例外或限制
对市场影响 损害权利人的正当市场利益和收入 基本不影响,或影响微小且为法律所容忍
法律依据 《著作权法》、《计算机软件保护条例》禁止性条款 同上法律中的“权利限制”或“合理使用”条款

对于开源软件而言,侵权场景的认定会更为复杂。比如,“从某网站下载了一份软件源代码”,这似乎符合“复制”软件的定义,那么是否构成了软件侵权?如果进行侵权认定,那么以下问题能够准确回答么:谁下载的?存储在了哪里?它是被用于学习研究么?

相信读者能够理解,其实挺难回答清楚。

因此,在实践中,通常将 分发 作为行使了开源软件版权权益的典型代表,以便更清晰界定侵权行为 实际发生 了。

何为分发?

将软件从一个法律实体(如我们公司)转移到另一个法律实体(如客户、用户),称为分发
映射到生产生活中,几个例子:

  1. 代码发表到开源社区,其他人可浏览、可下载,是源码分发
  2. 软件编译成制品,交付执行程序或安装包(.exe、.apk、.rpm等),是制品分发
  3. 系统固件烧写到硬件中(IoT设备,便携式设备,路由器,智能穿戴设备等),是制品分发
  4. 前端 JavaScript 代码发送到用户浏览器,是源码/制品分发
  5. 将 Docker 镜像推送到公共 Registry ,是制品分发

分发 是判定是否违规的最核心动作。大多数开源协议的义务(如开源源码),只有在发生 分发 行为时才会被触发。

相对应的,什么是“未分发”?

SaaS / 后端服务: 代码运行在公司自己的服务器上,用户仅通过 API 或网页与其交互。这通常 不视为分发

  • 避风港: 这是为什么谷歌、亚马逊可以在服务端大量使用 GPL 软件而不开源的原因。
  • 填坑者: AGPL 协议 专门修补了这个漏洞(详见后文)。

第2部分:知识篇 —— 了解许可证的内核

核心观念:了解它、尊重它、你才能使用它

2.1 开源软件许可证的核心内容

任何开源许可证(License),剥去复杂的法律措辞外衣,其骨架都是由 权利(Rights)、义务(Obligations)、限制(Limitations) 三部分构成。它们是一个三角关系,理解了这个三角,就理解了合规的本质。

权利 (Rights) —— 你可以做什么

这是原作者授予你的自由。通常包括:

  • 使用权: 运行程序的权利(包括商业环境)。
  • 复制权: 拷贝代码的权利。
  • 修改权: 增删改查源代码的权利。
  • 分发权: 将代码(原版或修改版)传给第三方的权利。
  • 再许可权: 将获得的权利转授给他人的权利。

一些附加权利,如:

  • 商标使用权: 利用原作者的名义(如 Google、Apache)来为你的产品背书。
  • 专利使用权: 承诺代码中涉及到他的专利,他不会以此来起诉你。

义务 (Obligations) —— 你必须做什么

这是你获得上述自由的代价。通常包括:

  • 署名义务: 保留原作者的版权声明和许可证文本。
  • 告知义务: 在分发时包含一份《开源声明文档》(Notice)。
  • 修改声明义务: 如果你改了代码,必须明确标注“我改过”。
  • 开源义务: 在特定条件下(如分发),必须公开你的修改代码或链接的主程序代码。
  • 源码可获取: 在发行的时候,提供明确的源码获取路径。
  • 提供编译、安装说明文档: 分发时提供对应的指导文档。

一些附加义务,如:

  • 广告义务: 在你的广告宣传中,需要附上对原软件的权利人或组织的致谢

限制 (Limitations) —— 你绝对不能做什么

这是不可触碰的红线。通常包括:

  • 商标限制: 不能利用原作者的名义(如 Google、Apache)来为你的产品背书。
  • 责任限制(免责条款): 代码按“原样”提供,作者不对你的任何损失(如数据丢失、服务器爆炸)负责。
  • 专利限制: 禁止发起专利诉讼(在某些协议中)。

一些特殊限制,如:

  • 商业限制: 禁止用于商业用途。
  • 领域限制: 如,禁止用于军事领域。
  • 区域、法律限制: 如,需要受美国出口管制制约(需要获得EAR相关准许)。

许可合规的本质: 你达成许可的义务要求,并遵循许可的限制,那么你才能行使许可授予的权益

2.2 许可证关键条款详解

2.2.1 修改 (Modification)

定义:对源代码进行的任何更改,包括修复 Bug、增加功能、删除代码、代码格式化,甚至翻译注释

修改 行为通常会产生 衍生作品(Derivative Work)。在 Copyleft(GPL类)协议下,一旦你修改并分发,你就必须开源你修改后的部分(开源义务)。
Apache 2.0 和 GPL 等协议明确要求:如果你修改了文件,必须在该文件中添加显著的声明(如 State changes here),说明你改了什么(列明修改义务)。

企业合规建议
在对开源代码进行修改时,务必要关注这部分代码与产品代码的关系和结合方式(源码集成?静态库集成?动态库集成),并做好防传染性(后文阐述)隔离。
如果你修改了 LGPL/MPL 等组件的源码,必须建立机制将这部分修改单独剥离出来准备开源,千万别混在公司的核心业务代码里提交。

2.2.2 分发 (Distribution / Conveyance)

定义: 在开源法律语境下,分发(GPLv3 中称为 "Convey")是指将软件的副本(Copy)从一个法律实体转移到另一个法律实体的行为

前面已提到,在开源合规中, 分发 是触发器, 因此厘清项目、产品中相关软件是否满足 分发 条件,尤为重要!

判定 分发 的三个核心要素:

  1. 物理转移: 代码(无论是源码还是二进制)离开了你的控制范围,到了别人的设备上。
  2. 法律实体变更: 发送方和接收方是不同的法律主体(例如:公司 A -> 客户 B,或者 公司 A -> 子公司 B)。
  3. 主动性: 无论是有偿销售、免费赠送、还是作为硬件的附赠品,都算分发。

典型的 分发 场景(毫无争议):

  • 软件交付: 发送安装包(.exe, .dmg, .apk)、提供下载链接。
  • 硬件预装(嵌入式/IoT): 销售路由器、汽车、智能音箱,里面烧录了固件(这是 GPL 违规的重灾区)。
  • 物理介质: 给客户寄送光盘、U盘。
  • 镜像推送: 将 Docker 镜像推送到公共仓库(Docker Hub)或给客户提供镜像 Tar 包。
  • 前端代码: JavaScript/WebAssembly 代码被推送到用户的浏览器中运行(这在技术上属于下载/分发)。

2.2.2.1 关于分发界定的争议

在实际业务中,由于云计算、外包、集团架构的存在,分发 的边界往往变得模糊。

争议点一:SaaS 与云服务(The "SaaS Loophole")

  • 场景: 公司在自己的服务器上运行修改后的 GPL 软件,用户通过浏览器访问网页或 API 使用服务。
  • 判定: 通常不视为分发。
    • 因为代码副本始终在公司服务器上,并没有“转移”到用户电脑里。用户得到的是“服务的输出结果”,而不是软件本身。
    • 这就是著名的 “ASP/SaaS 漏洞”

合规风险:
AGPL的例外: AGPL 协议专门填补了这个漏洞。它规定:“通过网络与用户交互”等同于分发。如果你用了 AGPL 组件做后端,即使用户没下载代码,你也必须向其开源。

争议点二:前端代码(JavaScript)的分发属性

  • 场景: 网站使用了 GPL 协议的 JS 库(如某些 UI 组件),经过 Webpack 打包压缩(Minified)后传给用户浏览器。
  • 判定: 视为分发。
    • 浏览器为了运行页面,必须下载 JS 文件。这就是分发。

合规风险:
(1) 如果 JS 库是 GPL,你的整个前端代码(与该库紧密结合的部分)可能被传染为 GPL。
(2) 源码义务: 压缩混淆后的 JS 代码(Minified)通常被视为“二进制”,不是“源码”。合规要求你必须提供未压缩的原始源码和 Source Map。

争议点三:集团内部流转(父子公司)

  • 场景: 母公司 A 开发了代码,传给全资子公司 B 使用或部署。
  • 争议:
    • 严格法律视角: 母公司和子公司是两个独立的法人实体。A 给 B,算分发。
    • 实际操作视角: 如果 B 只是拿来用,不对外发布,通常没人追究。但如果 B 把这个软件卖给了客户 C,那么 B 就成为了“分发者”,B 必须持有源码并承担合规义务。

合规风险:
如果子公司被出售、分拆,或者集团内部出现纠纷,这个“内部流转”可能变成法律把柄。

争议点四:外包与代工(Contractors)

  • 场景: 公司 A 雇佣外包公司 B 开发软件,公司 A 将包含开源组件的代码发给 B。
  • 判定:
    • 如果 B 签署了严格的保密协议(NDA)和“代工/雇佣作品(Work for Hire)”协议,B 通常被视为 A 的一部分(代理人),不视为分发
    • 但如果 B 同时为多家公司服务,且没有明确的权属约定,这可能被视为分发。

争议点五:容器镜像(Docker Images)

  • 场景: 交付给客户一个 Docker 镜像,里面包含 Linux 发行版(GPL)和公司自研应用。
  • 判定: 视为分发。
    • 整个镜像就是一个文件包。

合规风险:
你不仅要对自己代码负责,还要为镜像里打包的操作系统基础层(如 Alpine, Debian, Bash, Glibc)负责。通常需要提供这些 GPL 组件的源码或 Written Offer。

2.2.2.2 针对“分发”的合规建议 (SOP)

基于上述界定和争议,在使用中,可以参考一下策略

策略A:针对 SaaS/后端业务

  • 红线防御: 严禁引入 AGPL 组件,除非它是作为独立的、未修改的进程运行(如标准数据库)。
  • GPL 安全区: 在后端服务中,可以使用 GPL/LGPL 组件,前提是确保软件不交付给客户(不私有化部署)。
  • 混合云警示: 如果业务模式从“公有云 SaaS”转变为“帮大客户私有化部署”,原本安全的 GPL 组件会立刻变成“定时炸弹”。建议架构设计初期就假设未来会分发,尽量避免核心逻辑依赖 GPL。

策略B:针对 客户端/前端/IoT/嵌入式

  • 绝对白名单: 客户端(App、PC端)、嵌入式固件、前端 JS 代码,优先只使用 MIT、Apache、BSD 等宽松协议。
  • 隔离策略(针对 LGPL):
    • 如果是 PC 端/安卓:必须使用动态链接(调用 .dll / .so)。
    • 如果是 前端 JS:避免将 LGPL 的 JS 库打包进主 bundle.js。建议通过 CDN 独立加载,或保留其独立文件形式,并在《开源声明》中明确。
  • 源码准备: 对于必须使用的 GPL/LGPL 组件,必须在构建系统中建立自动化机制,归档对应的源码包(Source Code Tarball),以便随时应对用户的索取请求。

策略C:针对 Docker/容器交付

  • 最小化镜像: 尽量使用 Distroless 或极简的基础镜像,减少引入不必要的 GPL 系统工具(如 bash, grep 等)。
  • 分层合规: 明确客户获得的只是 Application Layer 的授权,Base OS Layer 遵循其原有的开源协议。在说明文档中提供 Base OS 的源码获取方式(通常指向发行版官网即可,但最严谨的做法是自己托管一份)。

策略 D:合同防御(针对外包/子公司)

  • 法律文件完善: 与外包商、子公司签署明确的《保密与知识产权转让协议》,明确其作为“受托开发方”的身份,避免代码流转被认定为公开分发。

2.2.3 商业使用 (Commercial Use)

定义:以营利为目的使用软件,或将软件作为商业产品的一部分

OSI 认证的开源软件,要求必须允许商业使用。
但有部分软件,明确限制了使用用途(如仅限于研究)禁止商业用途(如CC-BY-NC等),则应该划归在合规黑名单中。

2.2.4 商标授权 (Trademark Grant)

定义: 许可方是否允许你使用其商标(Logo、品牌名)

该权利,默认是保留的: 没有明确授权即禁止!绝大多数开源协议(包括 Apache 2.0, MIT)虽然授权了代码,但明确保留商标权。
你可以用 Android 的开源代码(AOSP)做一个手机系统,但你不能在开机画面打上 Google 的 Logo,也不能叫它 "Google Phone"。

合规风险:
在产品宣传、UI 界面中,切勿随意使用开源项目的 Logo,否则会收到商标侵权律师函。

2.2.5 专利授权 (Patent Grant)

定义: 贡献者承诺,如果你使用该代码,他们不会利用手里的专利起诉你

专利,是企业知识产权保护的核心之一;同时,也是知识产权纠纷最突出的领域。需要格外谨慎。
开源license中,对于专利授权的界定也存在一些模糊地带。几个关键点:

  • 显式授权(Apache 2.0 / GPLv3): 条款里写得清清楚楚,授予专利许可。这是大企业、注重合规的企业最看重的条款。
  • 隐式授权(大部分license): 条款没明写,但法律界普遍认为隐含了授权(因为你让我用代码,如果又用专利告我,属于欺诈)。
  • 明确排除或无专利保障(cc0,json):这类协议明确表示“我不授予专利权”,或者属于放弃所有权利进入公有领域,导致专利状态完全真空。

合规指引:
(1)引入代码时: 优先选择 Apache 2.0 或 MIT。如果涉及核心算法(如视频编解码、加密算法),尽量避免使用 CC0 或未明确专利授权的冷门协议,因为这些领域是专利战的重灾区。
(2)防御性: 如果公司担心被专利流氓起诉,Apache 2.0 的反制条款是很好的盾牌(见后续章节)。
(3)注意GPL的版本: GPL v2 和 GPL v3 在专利条款上有巨大差异。GPL v3 对专利授权有非常严格的“穿透”要求(见一下小节)。

2.2.5.1 专利穿透机制

背景
在 GPL v2 时代(1991-2007),关于专利的规定比较模糊(依赖第7条的隐式限制)。这留下了一个法律漏洞,被微软利用了,称为The Microsoft-Novell Deal事件:
2006年,微软声称 Linux 侵犯了其多项专利;微软与 Linux 发行商 Novell(SUSE Linux 的母公司)签署了一份协议,内容为: Novell 向微软付钱,微软承诺不予起诉 Novell 的客户;其结果是,使用 SUSE Linux 的客户是安全的(交了保护费),而使用 Red Hat 或 Debian 的客户则面临微软的专利诉讼威胁。

FSF(自由软件基金会)认为这种 歧视性专利交易 将开源社区分裂成了“付费贵族”和“免费平民”,不仅破坏了自由软件的平等性,还变相承认了软件专利对开源代码的控制权!
为了堵住这个漏洞,GPL v3 在第 11 条引入了极其严厉的规定。所谓的 穿透,指的是专利授权会自动穿透分发者,延伸到整个社区。

核心逻辑
如果你(分发者)向第三方(如微软)采购了专利保护(授权),并且这个保护只覆盖你自己的客户(歧视性),那么根据 GPL v3,这份专利保护必须自动、免费地扩展到所有获得该软件副本的人(包括你的竞争对手的客户)。

场景举例
假设你是一家手机厂商 Company A,你使用了 GPL v3 的组件 XappLib;你把这个组件预装在手机里卖给用户(分发事实);你担心 Patent Holder B(专利大鳄)起诉你,于是你给 B 付了一笔钱(结盟);B 承诺:“我不告 Company A 的用户,但我保留告其他人的权利”。
触发穿透(The Trap): 一旦你这样做了,Patent Holder B 对你的“不予起诉承诺”,在法律上自动转化为对全球所有该软件用户的专利授权(不仅限于你公司,而是基于该软件副本及其衍生作品的所有人)。
结果: Patent Holder B 原本想挨家收保护费,结果因为你用了 GPL v3 代码,导致他手里的专利对全世界都失效了(针对该软件)。

这一条款的杀伤力太大,导致了严重的“副作用”,使得大量商业公司和 Linux 内核社区坚决停留在 GPL v2。Linus 本人拒绝将 Linux 内核升级到 GPL v3,除了反对反 Tivoization(反硬件锁定)外,对专利条款也有异议:

  • “代码换代码” vs “代码换政治”: Linus 认为开源协议的核心是“我给你代码,你修改了也要回馈代码”(对等原则)。
  • 越界: 他认为 GPL v3 试图利用软件许可证来解决整个软件专利体系的法律问题,这超出了版权许可证的范畴,把许可证变成了“政治武器”。他希望内核保持中立,只关注代码共享本身。

合规风险:
(1) 专利穿透,对“交叉许可”(Cross-Licensing)具有毁灭性打击能力,需要格外谨慎。 如果不小心,让某个 GPL v3 软件的分发行为与现有的专利协议产生了关联,可能会意外地将公司核心的专利库免费授权给全世界。
(2) 专利穿透也是并购(M&A)中的“毒药”:大公司收购一家小创业公司。小公司分发过 GPL v3 软件,且小公司曾与某些专利持有者有过协议;收购完成后,大公司可能被视为继承了这些义务,导致大公司原本的专利库面临风险。

2.2.6 专利反制 (Patent Retaliation)

定义: 如果你因为专利侵权起诉我(或本项目),那么我也收回对你的代码使用授权

专利反制,是一种针对“专利流氓”(见下一小节)防御措施。Apache 2.0, MPL, GPL v3 都有此条款。

合规指引:
(1) 在共享开源项目时,选择具有专利反制的协议能够有效避免被专利流氓钻空子
(2) 如果公司计划发起专利战,法务必须先核查对手是否使用了带有反制条款的开源代码,否则可能导致自家产品立刻失去授权,被迫下架

2.2.5.2 专利流氓(Patent Troll)与NPE威胁

专利流氓,学名“非实施实体”(NPE, Non-Practicing Entity)。

他们自己不生产产品,不写代码,只收购大量专利;他们盯着大公司或热门开源项目,一旦发现你在用某种技术,就跳出来说:“你侵犯了我的专利,给钱(许可费)或者法庭见。”
开源软件代码公开,极其容易被专利持有者进行反向工程分析,从而成为专利诉讼的靶子。

另一种场景时,拥有专利的公司,参与到开源项目中,将涉及到专利的代码贡献到项目;待开源软件被大规模被使用后,再从中选取用户进行专利侵权起诉,以获取高额赔偿或收专利授权费用 —— 养猪模式(养肥了再杀)。

2.2.7 左权 (Copyleft)

Copyright (版权) 是“保留所有权利”,Copyleft (左权) 是“保留所有自由”。但这份自由是有代价的:你必须把这份自由传递下去

Copyleft,这是理查德·斯托曼(Richard Stallman)对Copyright的一次调侃,通过文字游戏,将 Right(权利/右)翻转为 Left(左), 与版权要求形成鲜明对比:
Copyright (版权) 的逻辑是:“保留所有权利”。作者说:“这是我的,你不准动,除非我同意。”
Copyleft (左权) 的逻辑是:“保留所有‘授予自由’的权利” 。作者说:“我允许你自由使用、修改、分发我的代码,但有一个前提:你分发出来的衍生作品,必须继承相同的条款(必须开源)”。

Copyleft的核心关键词有以下几个:

  • 互惠性 (Reciprocity): 你从社区索取了代码,你必须向社区回馈你的修改。
  • 传染性 (Viral): 这种权利和义务会像病毒一样,附着在代码上,传给下一个用户,再传给下下个用户,无穷无尽。
  • 自由的不可剥夺性: 它的目的不是限制开发者,而是限制“限制者”。它禁止中间商(包括商业公司)剥夺最终用户的自由。

为了更好的理解左权,下面简单介绍一下左权的诞生背景。

2.2.7.1 左权的诞生与解决的问题

在 70 年代(Unix 早期),软件通常是硬件的附赠品。MIT 人工智能实验室(AI Lab)的黑客们习惯于自由分享源代码,“代码”就像菜谱一样,大家互相传阅、改进。那时没有“开源”这个词,因为分享是天经地义的。

1980 年左右,MIT AI Lab 收到了一台施乐(Xerox)激光打印机。这台打印机经常卡纸。理查德·斯托曼(RMS)想修改打印机的驱动程序,加入一个功能:当打印机卡纸时,给用户发个通知。但当RMS 向施乐公司索要驱动源码,被拒绝了;他向持有源码的卡内基梅隆大学的一位教授索要,也因为对方签署了 保密协议 (NDA) 而被拒绝。
RMS 意识到,私有软件(Proprietary Software) 和 NDA正在摧毁黑客社区的协作精神。软件变成了商业秘密,邻居之间不能互相帮助。

打印机事件时Copyleft的导火索。而后的Emacs是Copyleft诞生的催生剂...

RMS 早期曾开发了 Emacs 编辑器。James Gosling(后来的 Java 之父)写了一个 Gosling Emacs,并允许大家自由分发(类似公有领域)。但随后,Gosling 将版权卖给了一家商业公司(UniPress),而该公司立刻停止了源码分发,并开始向用户收费。
RMS 意识到,仅仅把代码扔进“公有领域”(Public Domain)是不够的。因为商业公司会拿走公有领域的代码,做一点修改,然后闭源卖钱。 这样,原作者的贡献变成了别人剥削用户的工具。

为了防止这种“拿来主义”,RMS 创造了 GPL (General Public License),确立了 Copyleft 机制。Copyleft主要为了解决下面三个核心问题:

“不对等掠夺”问题

  • 问题: 如果使用宽松协议(如 MIT/BSD),大公司(如微软、苹果)可以免费拿走开源代码,改进后封装成闭源产品(macOS 就使用了大量的 BSD 代码)。社区付出了劳动,却没能享受到大公司的改进成果。
  • 解决: Copyleft 强制要求:如果你用了我的代码,你的改进必须回馈给社区。 这保证了贡献是对等的,防止大公司“白嫖”。

“代码分叉与私有化”问题

  • 问题: 商业公司倾向于将开源项目分叉(Fork),变成自己的私有版本,导致统一的开源生态分裂。
  • 解决: Copyleft 使得私有化分叉在法律上变得不可能(或者成本极高)。这迫使商业公司必须在主分支(Upstream)上进行协作,从而维护了生态的统一性(比如 Linux 内核,虽然有无数发行版,但核心依然只有一个)。

“最终用户自由被剥夺”问题

  • 问题: 软件最终到达用户手中时,往往是二进制文件。用户无法研究、无法修改、无法修复 Bug,完全被厂商锁定。
  • 解决: Copyleft 就像一条锁链,锁住了中间的分发者,确保不管代码经过多少手分发,最终用户(End User)永远拥有获取源代码的权利。

为了更形象的理解左权的本质,与私有软件、宽松许可软件做一个类比:

  • 私有软件(EULA): “这瓜是我的,你想吃得付钱,而且不准留种”。
  • 宽松开源(MIT): “这瓜免费给你,你想吃就吃,想留种就留种,想拿去卖钱也行,别说瓜是我种的就行。”
  • Copyleft(GPL): “这瓜免费给你,种子也给你。你可以改良这个品种,但你改良后的瓜和种子,必须也免费分给所有人。不能私藏!”

2.2.7.2 左权的传染性

在合规领域,我们常把 Copyleft 类许可证(特别是 GPL)称为“病毒式许可证”。
当你的专有代码(Proprietary Code)与 Copyleft 代码以某种方式“结合”在一起形成一个整体并进行分发时,Copyleft 许可证的条款会像病毒一样“感染”你的专有代码。
其结果是:被感染后,法律上要求你的专有代码也必须开源,且必须使用相同的 Copyleft 许可证。

对于商业公司而已,其显而易见的风险是: 你的专有代码因连接的左权软件而被迫开源,核心技术可能拱手让人

当然,传染不是无缘无故发生的,它基于著作权法中**“衍生作品(Derivative Work)”**的判定。核心逻辑链条:

  • 结合(Combination): 你的代码调用了 Copyleft 代码(如引用库、复制代码片段、静态链接等)。
  • 整体性(Unity): 法律视角认为,结合后的程序是一个单一的“衍生作品”。
  • 分发(Distribution): 你将这个产品交付给了第三方(比如卖给客户、放在应用商店下载、嵌入硬件销售)。
  • 触发条款: 满足上述三条时,Copyleft 许可证生效,要求整个“衍生作品”必须开源。

概括而言: 如果你的产品被认定为是基于Copyleft的软件的衍生作品, 那么就必须遵守Copyright的条款(开源、保持相同许可),否则不合规(侵权)

这里牵扯出另一个核心概念衍生作品,我们先对其简单解释...

2.2.7.3 衍生作品定义和界定

在著作权法中,衍生作品是指**“基于一个或多个已有作品创作的作品**”。比如,把《哈利波特》小说翻译成中文、改编成电影、缩写成儿童读物,都属于衍生作品。
其核心特征: 必须包含了原作品的实质性表达(Substantial Expression),并进行了改编、转换或重塑

在代码的世界里,衍生作品的边界在一些常见中是明确的,但也存在一些模糊地带。

无争议场景(100%属于衍生作品)

  • 修改源代码: 下载了源码,修改了几个函数,加了几个功能。
  • 代码翻译: 把一个 C++ 的开源库重写成 Java 版本。
  • 复制粘贴: 从开源项目中复制几十行核心算法代码到自己的项目中。
  • 打补丁(Patching): 即使你只分发补丁文件,但补丁本身依赖于原代码,通常也被视为衍生工作的一部分。

基本认可场景(普遍共识属于衍生作品)

  • 高级语言编译型组件: golang、rust等高级语言,在编译过程自动下载软件源码参与编译,最终在呈现在制品中。
  • 静态链接:几乎公认为是衍生作品。因为编译后,你的代码和开源代码在二进制层面已经物理“融为一体”了。

争议较大的场景

  • 动态链接库调用:争议很大。FSF(自由软件基金会)观点:软件是一个整体。如果你通过链接(Linking)(无论是静态还是动态)将你的代码与 GPL 代码组合,它们共享内存空间、共享数据结构,功能上互相依赖;因此,链接 = 衍生作品。商业抗辩观点:著作权保护的是“表达”(Expression),不是“功能”(Function)。我调用你的函数(API),就像是用插头插进插座。我没有复制插座内部的线路设计(源码),我只是使用了它的接口;因此,动态链接 ≠ 衍生作品(只要它们是独立文件)。
  • Java/Python 等解释型语言的 Classpath 调用: 通常视为动态链接库。
  • 插件(Plugins)与主程序(主程序是闭源的,加载了一个 左权的插件):争议较大,边界模糊。如果插件只是通过主程序提供的标准、公开 API 通信,主程序通常不被视为被传染(例如 Windows 运行 GPL 软件,Windows 不会被传染)。但是,如果插件和主程序之间交互极其紧密,交换了复杂的内部数据结构,FSF 认为这依然可能构成传染。
  • 包装器(Wrapper)/ 垫片(Shim):为了隔离 GPL 库,开发者写了一个中间层(Wrapper,用宽松协议如 MIT),主程序调用 Wrapper,Wrapper 再调用 GPL 库。如果 Wrapper 仅仅是简单的透传(Pass-through),在法律上可能被视为“规避措施”或“虚假隔离”,无法阻断传染性。除非 Wrapper 提供了实质性的抽象层。

合规指引:
(1) 严格禁止在闭源代码中把左权协议代码复制、粘贴进项目,严格禁止静态链接左权协议软件库,严格禁止编译时混入左权软件源码。
(2) 面对争议场景,黄金法则:默认视为“会传染”。在企业合规策略中,为了稳健经营,不要去挑战 FSF 的定义。
(3) 在商业(专有)软件中,避免动态链接 GPL(Strong Copyleft)组件。
(4) 安全的隔离方法——进程隔离:将 GPL 代码封装成一个独立运行的可执行文件(Service/Daemon),商业主程序通过 Socket (TCP/IP), Pipe, REST API, gRPC, 命令行参数 (CLI) 与其通信。这种方式被公认为阻断了传染性。因为两者内存空间独立,仅仅是数据交换。
(5) 协议替代:寻找功能类似的,但使用 MIT, Apache 2.0, BSD 或 LGPL 协议的库进行替代

2.2.7.4 强左权与弱左权

强 Copyleft (如 GPL): 传染性极强。只要主程序静态链接或在同一进程空间内深度调用了 GPL 库,整个主程序通常都被视为衍生作品,必须开源。
弱 Copyleft (如 LGPL, MPL): 传染性有限。

  • LGPL: 允许动态链接。只要你只是动态调用它,不修改库本身,你的主程序可以不开源。
  • MPL/CDDL: 文件级传染。只要求你修改过的那个开源文件及其派生文件开源,你自己写的文件(即使在同一个项目中)不受影响。

合规指引:
严格禁止将LGPL的代码复制到闭源项目中,严格禁止静态链接LGPL软件库,必须保持LGPL动态链接方式
MPL/CDDL虽然是文件级隔离,但合规检测难度较大;推荐按动态库的方式进行隔离维护,不要以源码的方式引入到项目中

2.2.8 网络左权 (Network Copyleft / AGPL)

定义: 专门针对云服务设计的传染机制

哪怕没有分发(不给安装包),只要用户通过网络(Web/API)使用了该软件的功能,就必须向用户提供源码。
AGPL 为了堵住GPL等传统强左权协议在 分发认定上,被云平台服务商钻空子。

合规指引:
后端开发、SaaS 产品严禁引入 AGPL 库(如某些 PDF 处理库、数据库中间件),除非你是作为独立进程且完全不修改它(满足隔离要求,满足开源要求)。

2.2.9 商业限制 / 源码可用 (Business Source / Commons Clause)

定义: 源码公开,但禁止特定商业行为

这不是开源(Open Source),而是“源码可用”(Source Available)。
典型条款例如:

  • SSPL (MongoDB): 如果你把这个数据库做成云服务卖给别人(Database-as-a-Service),你必须把你的云管平台源码也开源。
  • BSL (MariaDB / HashiCorp): 在生产环境只能运行特定节点以下,或者不能提供竞争性服务。

合规指引:
这类许可禁止引入商业产品中

第三部分:实操篇 —— 开发者的合规 SOP

核心观念: 合规不是最后一步,而是贯穿开发全生命周期。

3.1 选型与引入(Inbound)——进门检

在决定使用某个开源组件前,必须执行以下检查:

步骤一:License 识别
不要只看 GitHub 首页的简介,要点开根目录下的 LICENSE 文件或 package.json / pom.xml 确认。

步骤二:对照黑白名单

  • 直接可用:宽松类许可,如 MIT, Apache-2.0, BSD-3-Clause, ISC.
  • 需隔离使用(仅动态链接):弱左权类许可,如 LGPL, MPL(禁止复制源码到项目里)。
  • 谨慎分析后决定(需CTO+法务审核范围和风险应对):强左权类许可,如 GPL, AGPL(做好进程隔离,或评估遵从开源要求)。
  • 禁止引入: 商业限制许可或病毒许可,如CC-BY-NC,JSON。禁止引入无许可软件。

步骤三:依赖扫描
你引入的包 A (MIT) 可能依赖了包 B (GPL)。这叫“依赖传染”。

  • 操作: 必须运行公司的 SCA(软件成分分析)工具扫描整个依赖树。

步骤四:代码处理

  • 禁止裸抄: 严禁从 StackOverflow 或 博客 复制粘贴几十行以上的代码片段,除非确认其协议。
  • 保留头部: 如果引入源代码文件,绝对不能删除文件头部的 Copyright 和 License 声明块。

3.2 开发与修改(Development)

场景 A:我修改了开源组件的源码

  • 宽松协议(Apache/MIT): 建议在文件头部添加注释 // Modified by [Company Name] at [Date],说明修改点。这是免责也是礼貌。
  • 弱传染协议(MPL/LGPL):
    • 切记: 将修改后的文件或库单独存放,不要与公司的私有业务逻辑代码混淆。
    • 准备: 做好随时将这部分修改后的源码公开的准备。

场景 B:我只是调用(Link/Import)

  • 对于 LGPL 组件,确保构建脚本(Maven/Gradle/Webpack)将其打包为独立文件(如 .jar, .so),而不是将其代码合并混淆到主程序中。

3.3 发布与输出(Outbound)——出门检

当产品(App、固件、安装包)准备对外发布时:

步骤一:生成《开源许可声明》(Open Source Notice)
这是法律强制要求。必须在软件的“关于”页面、设置页面或安装包根目录下,提供一份文档。

  • 内容包括: 所有使用的开源组件名称、版本、License 全文、Copyright 信息。
  • 工具: 使用自动化插件生成(如 license-maven-plugin 或前端的 license-checker)。

步骤二:源码合规包(针对 GPL/LGPL)
如果产品中包含了 GPL/LGPL 组件且进行了分发:

  • 必须在 Written Offer(书面要约)中告知用户:“您可以联系我们索取相关开源组件的源代码”
  • 或者直接在官网提供源码下载链接。

3.4 对外贡献与开源(Contributing)

场景:员工想给开源社区提 PR

  • 原则: 工作时间的产出归公司。提 PR 代表公司对外授权。
  • CLA 审查: 如果项目要求签署 CLA (Contributor License Agreement),必须由法务审核。
    • 风险: 某些 CLA 会要求你放弃专利权,或者允许项目方将你的代码闭源商用。

结语

开源合规的目标不是“为了不被起诉”,而是为了建立可持续的软件交付能力

当每一位开发者都具备了基础的合规意识,我们就建立了一道无形的防火墙,保护了公司的知识产权,也尊重了社区的贡献。

如果在实际开发中遇到拿捏不准的 License,请务必遵循一个原则:“先咨询,后行动。”

0条评论
0 / 1000
huskar
22文章数
3粉丝数
huskar
22 文章 | 3 粉丝
原创

开源软件合规与风险基础

2025-12-23 01:24:38
37
0

前言:致每一位代码创作者

在当今的软件开发生态中,开源软件(Open Source Software, OSS)已经成为基础设施。正如搭积木一样,我们不再从零烧制砖块,而是引用成熟的开源组件来构建宏伟的数字大厦。

然而,“开源”不等于“免费”,更不等于“放弃版权”

每一行开源代码背后,都附带着一份法律契约——许可证(License)。作为公司的核心资产建设者,大家在引入外部代码时,实际上是在代表公司签署一份份法律合同。一旦违约,轻则导致公司核心代码被迫公开(GPL传染),重则面临巨额赔偿、产品下架甚至上市受阻。

本文摘旨在打破法律术语的壁垒,用开发者的语言,讲述开源合规的法律基础,许可证的内核。合规不是为了束缚手脚,而是为了让我们在安全的前提下,走得更快更稳!

第1部分:认知篇 —— 代码资产与法律基石

核心观念: 代码即资产,许可证即合同

1.1 从软件的版权(Copyright)说起

根据《伯尔尼公约》及各国著作权法,软件代码属于“文字作品”。代码一旦被写出来(固定在存储介质上),作者就自动拥有了版权(Copyright)。
这意味着:除非作者明确地授权给你,否则你没有任何权利去使用复制修改分发这些代码。
在中国,软件的版权更常见的称谓是:软件著作权

1.1.1 版权的自动保护原则

与专利权、商标权等需要显示申请注册不同,版权无需额为申请,而是当你完成开发时,就自动拥有了版权!与是否公开发表无关。

1.1.2 版权的归属

版权的归属因创作环境和过程不同而有所区别,常见的包括:

  1. 个人创作: 版权归个人所有
  2. 联合创作: 首先,遵循约定; 如果无约定,作品可分割使用,则按贡献划分各自占有贡献部分的版权;不可分割使用的,由合作开发者共同享有,通过协商一致行使。注意,我们在开源社区获取到的开源软件,大多属于这类版权归属。
  3. 劳务创作:在公司工作中开发的软件,版权属于公司。
  4. 委托创作:首先,遵循约定;如果未约定的,版权归受托人。
  5. 其他:例如由国家机关下达任务开发的软件,版权权归属与行使由项目任务书或合同约定;无约定,著作权属于接受任务的法人、组织、或个人。

注意:软件版权可以继承,转让。

1.1.3 软件侵权风险

如果涉嫌侵权其他软件,依据不同的场景和严重程度,可能涉及到民事责任、行政责任、刑事责任。

民事责任(赔钱、道歉、下架)

  • 停止侵害: 法院可下令立即停止使用、分发该软件(对于已上线的业务是毁灭性打击)。
  • 赔偿损失:按照权利人受到的实际损失计算;或者按照侵权人(我司)因此获得的违法所得计算;如果都算不出来,法院可判决 500 万元以下 的法定赔偿。
  • 惩罚性赔偿: 对于故意侵权且情节严重的,可以处以 1倍以上 5倍以下 的惩罚性赔偿。

行政责任(罚款、查封)

如果侵权行为同时损害了公共利益,版权行政管理部门(如版权局)可以:

  • 责令停止侵权行为。
  • 没收违法所得。
  • 没收、销毁侵权复制品。
  • 罚款。

刑事责任(坐牢)—— 侵犯著作权罪

这是达摩克利斯之剑。根据《刑法》第二百一十七条,以营利为目的,未经著作权人许可,复制发行其计算机软件:

  • 违法所得数额较大(>3万元) 或者有其他严重情节的:处 3年以下 有期徒刑。
  • 违法所得数额巨大(>25万元) 或者有其他特别严重情节的:处 3年以上 7年以下 有期徒刑,并处罚金。
  • 警示案例: 某公司为了赶进度,破解并使用了某商业软件库(或违规修改并闭源使用了 GPL 软件进行高额获利),不仅公司面临巨额罚款,公司的直接责任人(CTO或项目负责人)可能面临刑事指控。

当然,对于商业公司而言,隐形风险还包括: 产品发行受阻导致的资金问题、市场问题,公司品牌形象与公众形象问题,被迫开源导致的核心技术泄露问题等等!

对于开源软件,违反开源协议(如使用了 GPL 但不开源),在法律上不仅仅是违约(违反合同),更是侵犯著作权。后果可能比你想象的严重得多。

1.2 许可证(License)的法律本质

前面已明确,版权的作用是保护软件不被他人修改、复制、使用、分发等; 但为了发挥软件的价值,版权所有者可以通过某种**“契约”形式,授权给特定的人(或群体、组织)某些权利,如修改、使用、售卖、分发等,同时附加一定的限制条件。
对于商业软件而已,授权 通常是通过
采购合同**达成的!

对于开源软件,因版权所有者和使用者的物理位置和信息隔离,难以有效的达成正式合同性的契约。为解该问题,通用的做法是在软件发布时,附一份**许可证(License)**文件(或声明片段),用于指定授权给使用者的权益范围,同时对使用方式、使用范围、使用过程、权益再处置等做出限制。其规则为:你使用该软件,代表你认可该许可证中所有条款;同时,承诺在使用过程中严格遵守许可中的所有条款

换言之:

许可证,是版权持有者(Licensor)发给使用者(Licensee)的一个框架式合同,它授权给使用者某些版权保护范围内的权益,同时指定了一些使用规矩(义务条款和限制条款);
当使用者严格遵循许可证指定的规矩时,则可以获得许可证中给定的权益;反之,当使用者行使了权益缺未遵循这些使用规矩时,则认为是侵权。

这便是许可证的法律本质!
许可证中指定的规矩 则称为合规义务, 再后续章节中会深入探讨!

1.2.1 许可(Licensing) vs 转让(Assignment)

经常,我们引入开源组件,其中附带一份许可证文件。此情形下,我们获得了该软件的许可(Licensing)
但需要注意:我们获得的是使用许可,而非所有权/版权。原作者依然是老大, 依然不能“为所欲为”。

不同的许可证,在授予使用者权益时的范围和粒度有很大差别,大体分以下几种:

  1. 完全放弃版权,授权你“为所欲为” —— Public Domain 类型许可/零义务许可;
  2. 主要保留版权归属声明,基本不限制你的使用方式和范围 —— Permissive 类型许可/宽松许可;
  3. 强调软件自由,严格要求遵循相同的使用方式(开发源码,禁止调整许可条款) —— Copyleft类型许可/ 严格许可;
  4. 其他一些带领域限制、技术限制、定制化条款的许可 —— 专业领域许可、私有许可(含商业许可);

在后续章节中,本文会进一探讨不同许可的授权范围和限制条款,并讨论这些差异如何影响使用者...

1.2.2 默认的“保留所有权利”

这是一个值得强调的事情!

在 GitHub 或 GitLab 上,如果一个仓库没有任何 LICENSE 文件,这并不代表它是公有领域(Public Domain)的;恰恰相反,这代表作者 保留所有权利 (All Rights Reserved)
即使代码公开可见,你下载、复制、引用、修改、分发的行为在法律上均属于侵权。

因此:
严格禁止引入无 License 的“裸奔代码”

1.2.3 触发开源软件合规义务的“扳机” —— 分发(Distribution)

虽然版权明确了在未授权情况下复制、修改、使用、分发他人的软件作品均属于侵权,但在实践中却存在很多争议或灰色地带。国内,主要的法律依据是《著作权法》和《计算软件保护条例》。下表是对是否构成软件侵权的经典场景一个概览:

特征 侵犯著作权的情形 不侵犯著作权的情形
核心行为 未经许可的复制、分发、修改、商业使用、规避保护措施 合法使用、独立创作、为兼容的反向工程、合理使用
主观目的 通常具有商业目的或传播目的 个人使用、学习研究、实现兼容、执行公务
与权利冲突 直接对抗权利人的专有权利 属于法律明确规定的例外或限制
对市场影响 损害权利人的正当市场利益和收入 基本不影响,或影响微小且为法律所容忍
法律依据 《著作权法》、《计算机软件保护条例》禁止性条款 同上法律中的“权利限制”或“合理使用”条款

对于开源软件而言,侵权场景的认定会更为复杂。比如,“从某网站下载了一份软件源代码”,这似乎符合“复制”软件的定义,那么是否构成了软件侵权?如果进行侵权认定,那么以下问题能够准确回答么:谁下载的?存储在了哪里?它是被用于学习研究么?

相信读者能够理解,其实挺难回答清楚。

因此,在实践中,通常将 分发 作为行使了开源软件版权权益的典型代表,以便更清晰界定侵权行为 实际发生 了。

何为分发?

将软件从一个法律实体(如我们公司)转移到另一个法律实体(如客户、用户),称为分发
映射到生产生活中,几个例子:

  1. 代码发表到开源社区,其他人可浏览、可下载,是源码分发
  2. 软件编译成制品,交付执行程序或安装包(.exe、.apk、.rpm等),是制品分发
  3. 系统固件烧写到硬件中(IoT设备,便携式设备,路由器,智能穿戴设备等),是制品分发
  4. 前端 JavaScript 代码发送到用户浏览器,是源码/制品分发
  5. 将 Docker 镜像推送到公共 Registry ,是制品分发

分发 是判定是否违规的最核心动作。大多数开源协议的义务(如开源源码),只有在发生 分发 行为时才会被触发。

相对应的,什么是“未分发”?

SaaS / 后端服务: 代码运行在公司自己的服务器上,用户仅通过 API 或网页与其交互。这通常 不视为分发

  • 避风港: 这是为什么谷歌、亚马逊可以在服务端大量使用 GPL 软件而不开源的原因。
  • 填坑者: AGPL 协议 专门修补了这个漏洞(详见后文)。

第2部分:知识篇 —— 了解许可证的内核

核心观念:了解它、尊重它、你才能使用它

2.1 开源软件许可证的核心内容

任何开源许可证(License),剥去复杂的法律措辞外衣,其骨架都是由 权利(Rights)、义务(Obligations)、限制(Limitations) 三部分构成。它们是一个三角关系,理解了这个三角,就理解了合规的本质。

权利 (Rights) —— 你可以做什么

这是原作者授予你的自由。通常包括:

  • 使用权: 运行程序的权利(包括商业环境)。
  • 复制权: 拷贝代码的权利。
  • 修改权: 增删改查源代码的权利。
  • 分发权: 将代码(原版或修改版)传给第三方的权利。
  • 再许可权: 将获得的权利转授给他人的权利。

一些附加权利,如:

  • 商标使用权: 利用原作者的名义(如 Google、Apache)来为你的产品背书。
  • 专利使用权: 承诺代码中涉及到他的专利,他不会以此来起诉你。

义务 (Obligations) —— 你必须做什么

这是你获得上述自由的代价。通常包括:

  • 署名义务: 保留原作者的版权声明和许可证文本。
  • 告知义务: 在分发时包含一份《开源声明文档》(Notice)。
  • 修改声明义务: 如果你改了代码,必须明确标注“我改过”。
  • 开源义务: 在特定条件下(如分发),必须公开你的修改代码或链接的主程序代码。
  • 源码可获取: 在发行的时候,提供明确的源码获取路径。
  • 提供编译、安装说明文档: 分发时提供对应的指导文档。

一些附加义务,如:

  • 广告义务: 在你的广告宣传中,需要附上对原软件的权利人或组织的致谢

限制 (Limitations) —— 你绝对不能做什么

这是不可触碰的红线。通常包括:

  • 商标限制: 不能利用原作者的名义(如 Google、Apache)来为你的产品背书。
  • 责任限制(免责条款): 代码按“原样”提供,作者不对你的任何损失(如数据丢失、服务器爆炸)负责。
  • 专利限制: 禁止发起专利诉讼(在某些协议中)。

一些特殊限制,如:

  • 商业限制: 禁止用于商业用途。
  • 领域限制: 如,禁止用于军事领域。
  • 区域、法律限制: 如,需要受美国出口管制制约(需要获得EAR相关准许)。

许可合规的本质: 你达成许可的义务要求,并遵循许可的限制,那么你才能行使许可授予的权益

2.2 许可证关键条款详解

2.2.1 修改 (Modification)

定义:对源代码进行的任何更改,包括修复 Bug、增加功能、删除代码、代码格式化,甚至翻译注释

修改 行为通常会产生 衍生作品(Derivative Work)。在 Copyleft(GPL类)协议下,一旦你修改并分发,你就必须开源你修改后的部分(开源义务)。
Apache 2.0 和 GPL 等协议明确要求:如果你修改了文件,必须在该文件中添加显著的声明(如 State changes here),说明你改了什么(列明修改义务)。

企业合规建议
在对开源代码进行修改时,务必要关注这部分代码与产品代码的关系和结合方式(源码集成?静态库集成?动态库集成),并做好防传染性(后文阐述)隔离。
如果你修改了 LGPL/MPL 等组件的源码,必须建立机制将这部分修改单独剥离出来准备开源,千万别混在公司的核心业务代码里提交。

2.2.2 分发 (Distribution / Conveyance)

定义: 在开源法律语境下,分发(GPLv3 中称为 "Convey")是指将软件的副本(Copy)从一个法律实体转移到另一个法律实体的行为

前面已提到,在开源合规中, 分发 是触发器, 因此厘清项目、产品中相关软件是否满足 分发 条件,尤为重要!

判定 分发 的三个核心要素:

  1. 物理转移: 代码(无论是源码还是二进制)离开了你的控制范围,到了别人的设备上。
  2. 法律实体变更: 发送方和接收方是不同的法律主体(例如:公司 A -> 客户 B,或者 公司 A -> 子公司 B)。
  3. 主动性: 无论是有偿销售、免费赠送、还是作为硬件的附赠品,都算分发。

典型的 分发 场景(毫无争议):

  • 软件交付: 发送安装包(.exe, .dmg, .apk)、提供下载链接。
  • 硬件预装(嵌入式/IoT): 销售路由器、汽车、智能音箱,里面烧录了固件(这是 GPL 违规的重灾区)。
  • 物理介质: 给客户寄送光盘、U盘。
  • 镜像推送: 将 Docker 镜像推送到公共仓库(Docker Hub)或给客户提供镜像 Tar 包。
  • 前端代码: JavaScript/WebAssembly 代码被推送到用户的浏览器中运行(这在技术上属于下载/分发)。

2.2.2.1 关于分发界定的争议

在实际业务中,由于云计算、外包、集团架构的存在,分发 的边界往往变得模糊。

争议点一:SaaS 与云服务(The "SaaS Loophole")

  • 场景: 公司在自己的服务器上运行修改后的 GPL 软件,用户通过浏览器访问网页或 API 使用服务。
  • 判定: 通常不视为分发。
    • 因为代码副本始终在公司服务器上,并没有“转移”到用户电脑里。用户得到的是“服务的输出结果”,而不是软件本身。
    • 这就是著名的 “ASP/SaaS 漏洞”

合规风险:
AGPL的例外: AGPL 协议专门填补了这个漏洞。它规定:“通过网络与用户交互”等同于分发。如果你用了 AGPL 组件做后端,即使用户没下载代码,你也必须向其开源。

争议点二:前端代码(JavaScript)的分发属性

  • 场景: 网站使用了 GPL 协议的 JS 库(如某些 UI 组件),经过 Webpack 打包压缩(Minified)后传给用户浏览器。
  • 判定: 视为分发。
    • 浏览器为了运行页面,必须下载 JS 文件。这就是分发。

合规风险:
(1) 如果 JS 库是 GPL,你的整个前端代码(与该库紧密结合的部分)可能被传染为 GPL。
(2) 源码义务: 压缩混淆后的 JS 代码(Minified)通常被视为“二进制”,不是“源码”。合规要求你必须提供未压缩的原始源码和 Source Map。

争议点三:集团内部流转(父子公司)

  • 场景: 母公司 A 开发了代码,传给全资子公司 B 使用或部署。
  • 争议:
    • 严格法律视角: 母公司和子公司是两个独立的法人实体。A 给 B,算分发。
    • 实际操作视角: 如果 B 只是拿来用,不对外发布,通常没人追究。但如果 B 把这个软件卖给了客户 C,那么 B 就成为了“分发者”,B 必须持有源码并承担合规义务。

合规风险:
如果子公司被出售、分拆,或者集团内部出现纠纷,这个“内部流转”可能变成法律把柄。

争议点四:外包与代工(Contractors)

  • 场景: 公司 A 雇佣外包公司 B 开发软件,公司 A 将包含开源组件的代码发给 B。
  • 判定:
    • 如果 B 签署了严格的保密协议(NDA)和“代工/雇佣作品(Work for Hire)”协议,B 通常被视为 A 的一部分(代理人),不视为分发
    • 但如果 B 同时为多家公司服务,且没有明确的权属约定,这可能被视为分发。

争议点五:容器镜像(Docker Images)

  • 场景: 交付给客户一个 Docker 镜像,里面包含 Linux 发行版(GPL)和公司自研应用。
  • 判定: 视为分发。
    • 整个镜像就是一个文件包。

合规风险:
你不仅要对自己代码负责,还要为镜像里打包的操作系统基础层(如 Alpine, Debian, Bash, Glibc)负责。通常需要提供这些 GPL 组件的源码或 Written Offer。

2.2.2.2 针对“分发”的合规建议 (SOP)

基于上述界定和争议,在使用中,可以参考一下策略

策略A:针对 SaaS/后端业务

  • 红线防御: 严禁引入 AGPL 组件,除非它是作为独立的、未修改的进程运行(如标准数据库)。
  • GPL 安全区: 在后端服务中,可以使用 GPL/LGPL 组件,前提是确保软件不交付给客户(不私有化部署)。
  • 混合云警示: 如果业务模式从“公有云 SaaS”转变为“帮大客户私有化部署”,原本安全的 GPL 组件会立刻变成“定时炸弹”。建议架构设计初期就假设未来会分发,尽量避免核心逻辑依赖 GPL。

策略B:针对 客户端/前端/IoT/嵌入式

  • 绝对白名单: 客户端(App、PC端)、嵌入式固件、前端 JS 代码,优先只使用 MIT、Apache、BSD 等宽松协议。
  • 隔离策略(针对 LGPL):
    • 如果是 PC 端/安卓:必须使用动态链接(调用 .dll / .so)。
    • 如果是 前端 JS:避免将 LGPL 的 JS 库打包进主 bundle.js。建议通过 CDN 独立加载,或保留其独立文件形式,并在《开源声明》中明确。
  • 源码准备: 对于必须使用的 GPL/LGPL 组件,必须在构建系统中建立自动化机制,归档对应的源码包(Source Code Tarball),以便随时应对用户的索取请求。

策略C:针对 Docker/容器交付

  • 最小化镜像: 尽量使用 Distroless 或极简的基础镜像,减少引入不必要的 GPL 系统工具(如 bash, grep 等)。
  • 分层合规: 明确客户获得的只是 Application Layer 的授权,Base OS Layer 遵循其原有的开源协议。在说明文档中提供 Base OS 的源码获取方式(通常指向发行版官网即可,但最严谨的做法是自己托管一份)。

策略 D:合同防御(针对外包/子公司)

  • 法律文件完善: 与外包商、子公司签署明确的《保密与知识产权转让协议》,明确其作为“受托开发方”的身份,避免代码流转被认定为公开分发。

2.2.3 商业使用 (Commercial Use)

定义:以营利为目的使用软件,或将软件作为商业产品的一部分

OSI 认证的开源软件,要求必须允许商业使用。
但有部分软件,明确限制了使用用途(如仅限于研究)禁止商业用途(如CC-BY-NC等),则应该划归在合规黑名单中。

2.2.4 商标授权 (Trademark Grant)

定义: 许可方是否允许你使用其商标(Logo、品牌名)

该权利,默认是保留的: 没有明确授权即禁止!绝大多数开源协议(包括 Apache 2.0, MIT)虽然授权了代码,但明确保留商标权。
你可以用 Android 的开源代码(AOSP)做一个手机系统,但你不能在开机画面打上 Google 的 Logo,也不能叫它 "Google Phone"。

合规风险:
在产品宣传、UI 界面中,切勿随意使用开源项目的 Logo,否则会收到商标侵权律师函。

2.2.5 专利授权 (Patent Grant)

定义: 贡献者承诺,如果你使用该代码,他们不会利用手里的专利起诉你

专利,是企业知识产权保护的核心之一;同时,也是知识产权纠纷最突出的领域。需要格外谨慎。
开源license中,对于专利授权的界定也存在一些模糊地带。几个关键点:

  • 显式授权(Apache 2.0 / GPLv3): 条款里写得清清楚楚,授予专利许可。这是大企业、注重合规的企业最看重的条款。
  • 隐式授权(大部分license): 条款没明写,但法律界普遍认为隐含了授权(因为你让我用代码,如果又用专利告我,属于欺诈)。
  • 明确排除或无专利保障(cc0,json):这类协议明确表示“我不授予专利权”,或者属于放弃所有权利进入公有领域,导致专利状态完全真空。

合规指引:
(1)引入代码时: 优先选择 Apache 2.0 或 MIT。如果涉及核心算法(如视频编解码、加密算法),尽量避免使用 CC0 或未明确专利授权的冷门协议,因为这些领域是专利战的重灾区。
(2)防御性: 如果公司担心被专利流氓起诉,Apache 2.0 的反制条款是很好的盾牌(见后续章节)。
(3)注意GPL的版本: GPL v2 和 GPL v3 在专利条款上有巨大差异。GPL v3 对专利授权有非常严格的“穿透”要求(见一下小节)。

2.2.5.1 专利穿透机制

背景
在 GPL v2 时代(1991-2007),关于专利的规定比较模糊(依赖第7条的隐式限制)。这留下了一个法律漏洞,被微软利用了,称为The Microsoft-Novell Deal事件:
2006年,微软声称 Linux 侵犯了其多项专利;微软与 Linux 发行商 Novell(SUSE Linux 的母公司)签署了一份协议,内容为: Novell 向微软付钱,微软承诺不予起诉 Novell 的客户;其结果是,使用 SUSE Linux 的客户是安全的(交了保护费),而使用 Red Hat 或 Debian 的客户则面临微软的专利诉讼威胁。

FSF(自由软件基金会)认为这种 歧视性专利交易 将开源社区分裂成了“付费贵族”和“免费平民”,不仅破坏了自由软件的平等性,还变相承认了软件专利对开源代码的控制权!
为了堵住这个漏洞,GPL v3 在第 11 条引入了极其严厉的规定。所谓的 穿透,指的是专利授权会自动穿透分发者,延伸到整个社区。

核心逻辑
如果你(分发者)向第三方(如微软)采购了专利保护(授权),并且这个保护只覆盖你自己的客户(歧视性),那么根据 GPL v3,这份专利保护必须自动、免费地扩展到所有获得该软件副本的人(包括你的竞争对手的客户)。

场景举例
假设你是一家手机厂商 Company A,你使用了 GPL v3 的组件 XappLib;你把这个组件预装在手机里卖给用户(分发事实);你担心 Patent Holder B(专利大鳄)起诉你,于是你给 B 付了一笔钱(结盟);B 承诺:“我不告 Company A 的用户,但我保留告其他人的权利”。
触发穿透(The Trap): 一旦你这样做了,Patent Holder B 对你的“不予起诉承诺”,在法律上自动转化为对全球所有该软件用户的专利授权(不仅限于你公司,而是基于该软件副本及其衍生作品的所有人)。
结果: Patent Holder B 原本想挨家收保护费,结果因为你用了 GPL v3 代码,导致他手里的专利对全世界都失效了(针对该软件)。

这一条款的杀伤力太大,导致了严重的“副作用”,使得大量商业公司和 Linux 内核社区坚决停留在 GPL v2。Linus 本人拒绝将 Linux 内核升级到 GPL v3,除了反对反 Tivoization(反硬件锁定)外,对专利条款也有异议:

  • “代码换代码” vs “代码换政治”: Linus 认为开源协议的核心是“我给你代码,你修改了也要回馈代码”(对等原则)。
  • 越界: 他认为 GPL v3 试图利用软件许可证来解决整个软件专利体系的法律问题,这超出了版权许可证的范畴,把许可证变成了“政治武器”。他希望内核保持中立,只关注代码共享本身。

合规风险:
(1) 专利穿透,对“交叉许可”(Cross-Licensing)具有毁灭性打击能力,需要格外谨慎。 如果不小心,让某个 GPL v3 软件的分发行为与现有的专利协议产生了关联,可能会意外地将公司核心的专利库免费授权给全世界。
(2) 专利穿透也是并购(M&A)中的“毒药”:大公司收购一家小创业公司。小公司分发过 GPL v3 软件,且小公司曾与某些专利持有者有过协议;收购完成后,大公司可能被视为继承了这些义务,导致大公司原本的专利库面临风险。

2.2.6 专利反制 (Patent Retaliation)

定义: 如果你因为专利侵权起诉我(或本项目),那么我也收回对你的代码使用授权

专利反制,是一种针对“专利流氓”(见下一小节)防御措施。Apache 2.0, MPL, GPL v3 都有此条款。

合规指引:
(1) 在共享开源项目时,选择具有专利反制的协议能够有效避免被专利流氓钻空子
(2) 如果公司计划发起专利战,法务必须先核查对手是否使用了带有反制条款的开源代码,否则可能导致自家产品立刻失去授权,被迫下架

2.2.5.2 专利流氓(Patent Troll)与NPE威胁

专利流氓,学名“非实施实体”(NPE, Non-Practicing Entity)。

他们自己不生产产品,不写代码,只收购大量专利;他们盯着大公司或热门开源项目,一旦发现你在用某种技术,就跳出来说:“你侵犯了我的专利,给钱(许可费)或者法庭见。”
开源软件代码公开,极其容易被专利持有者进行反向工程分析,从而成为专利诉讼的靶子。

另一种场景时,拥有专利的公司,参与到开源项目中,将涉及到专利的代码贡献到项目;待开源软件被大规模被使用后,再从中选取用户进行专利侵权起诉,以获取高额赔偿或收专利授权费用 —— 养猪模式(养肥了再杀)。

2.2.7 左权 (Copyleft)

Copyright (版权) 是“保留所有权利”,Copyleft (左权) 是“保留所有自由”。但这份自由是有代价的:你必须把这份自由传递下去

Copyleft,这是理查德·斯托曼(Richard Stallman)对Copyright的一次调侃,通过文字游戏,将 Right(权利/右)翻转为 Left(左), 与版权要求形成鲜明对比:
Copyright (版权) 的逻辑是:“保留所有权利”。作者说:“这是我的,你不准动,除非我同意。”
Copyleft (左权) 的逻辑是:“保留所有‘授予自由’的权利” 。作者说:“我允许你自由使用、修改、分发我的代码,但有一个前提:你分发出来的衍生作品,必须继承相同的条款(必须开源)”。

Copyleft的核心关键词有以下几个:

  • 互惠性 (Reciprocity): 你从社区索取了代码,你必须向社区回馈你的修改。
  • 传染性 (Viral): 这种权利和义务会像病毒一样,附着在代码上,传给下一个用户,再传给下下个用户,无穷无尽。
  • 自由的不可剥夺性: 它的目的不是限制开发者,而是限制“限制者”。它禁止中间商(包括商业公司)剥夺最终用户的自由。

为了更好的理解左权,下面简单介绍一下左权的诞生背景。

2.2.7.1 左权的诞生与解决的问题

在 70 年代(Unix 早期),软件通常是硬件的附赠品。MIT 人工智能实验室(AI Lab)的黑客们习惯于自由分享源代码,“代码”就像菜谱一样,大家互相传阅、改进。那时没有“开源”这个词,因为分享是天经地义的。

1980 年左右,MIT AI Lab 收到了一台施乐(Xerox)激光打印机。这台打印机经常卡纸。理查德·斯托曼(RMS)想修改打印机的驱动程序,加入一个功能:当打印机卡纸时,给用户发个通知。但当RMS 向施乐公司索要驱动源码,被拒绝了;他向持有源码的卡内基梅隆大学的一位教授索要,也因为对方签署了 保密协议 (NDA) 而被拒绝。
RMS 意识到,私有软件(Proprietary Software) 和 NDA正在摧毁黑客社区的协作精神。软件变成了商业秘密,邻居之间不能互相帮助。

打印机事件时Copyleft的导火索。而后的Emacs是Copyleft诞生的催生剂...

RMS 早期曾开发了 Emacs 编辑器。James Gosling(后来的 Java 之父)写了一个 Gosling Emacs,并允许大家自由分发(类似公有领域)。但随后,Gosling 将版权卖给了一家商业公司(UniPress),而该公司立刻停止了源码分发,并开始向用户收费。
RMS 意识到,仅仅把代码扔进“公有领域”(Public Domain)是不够的。因为商业公司会拿走公有领域的代码,做一点修改,然后闭源卖钱。 这样,原作者的贡献变成了别人剥削用户的工具。

为了防止这种“拿来主义”,RMS 创造了 GPL (General Public License),确立了 Copyleft 机制。Copyleft主要为了解决下面三个核心问题:

“不对等掠夺”问题

  • 问题: 如果使用宽松协议(如 MIT/BSD),大公司(如微软、苹果)可以免费拿走开源代码,改进后封装成闭源产品(macOS 就使用了大量的 BSD 代码)。社区付出了劳动,却没能享受到大公司的改进成果。
  • 解决: Copyleft 强制要求:如果你用了我的代码,你的改进必须回馈给社区。 这保证了贡献是对等的,防止大公司“白嫖”。

“代码分叉与私有化”问题

  • 问题: 商业公司倾向于将开源项目分叉(Fork),变成自己的私有版本,导致统一的开源生态分裂。
  • 解决: Copyleft 使得私有化分叉在法律上变得不可能(或者成本极高)。这迫使商业公司必须在主分支(Upstream)上进行协作,从而维护了生态的统一性(比如 Linux 内核,虽然有无数发行版,但核心依然只有一个)。

“最终用户自由被剥夺”问题

  • 问题: 软件最终到达用户手中时,往往是二进制文件。用户无法研究、无法修改、无法修复 Bug,完全被厂商锁定。
  • 解决: Copyleft 就像一条锁链,锁住了中间的分发者,确保不管代码经过多少手分发,最终用户(End User)永远拥有获取源代码的权利。

为了更形象的理解左权的本质,与私有软件、宽松许可软件做一个类比:

  • 私有软件(EULA): “这瓜是我的,你想吃得付钱,而且不准留种”。
  • 宽松开源(MIT): “这瓜免费给你,你想吃就吃,想留种就留种,想拿去卖钱也行,别说瓜是我种的就行。”
  • Copyleft(GPL): “这瓜免费给你,种子也给你。你可以改良这个品种,但你改良后的瓜和种子,必须也免费分给所有人。不能私藏!”

2.2.7.2 左权的传染性

在合规领域,我们常把 Copyleft 类许可证(特别是 GPL)称为“病毒式许可证”。
当你的专有代码(Proprietary Code)与 Copyleft 代码以某种方式“结合”在一起形成一个整体并进行分发时,Copyleft 许可证的条款会像病毒一样“感染”你的专有代码。
其结果是:被感染后,法律上要求你的专有代码也必须开源,且必须使用相同的 Copyleft 许可证。

对于商业公司而已,其显而易见的风险是: 你的专有代码因连接的左权软件而被迫开源,核心技术可能拱手让人

当然,传染不是无缘无故发生的,它基于著作权法中**“衍生作品(Derivative Work)”**的判定。核心逻辑链条:

  • 结合(Combination): 你的代码调用了 Copyleft 代码(如引用库、复制代码片段、静态链接等)。
  • 整体性(Unity): 法律视角认为,结合后的程序是一个单一的“衍生作品”。
  • 分发(Distribution): 你将这个产品交付给了第三方(比如卖给客户、放在应用商店下载、嵌入硬件销售)。
  • 触发条款: 满足上述三条时,Copyleft 许可证生效,要求整个“衍生作品”必须开源。

概括而言: 如果你的产品被认定为是基于Copyleft的软件的衍生作品, 那么就必须遵守Copyright的条款(开源、保持相同许可),否则不合规(侵权)

这里牵扯出另一个核心概念衍生作品,我们先对其简单解释...

2.2.7.3 衍生作品定义和界定

在著作权法中,衍生作品是指**“基于一个或多个已有作品创作的作品**”。比如,把《哈利波特》小说翻译成中文、改编成电影、缩写成儿童读物,都属于衍生作品。
其核心特征: 必须包含了原作品的实质性表达(Substantial Expression),并进行了改编、转换或重塑

在代码的世界里,衍生作品的边界在一些常见中是明确的,但也存在一些模糊地带。

无争议场景(100%属于衍生作品)

  • 修改源代码: 下载了源码,修改了几个函数,加了几个功能。
  • 代码翻译: 把一个 C++ 的开源库重写成 Java 版本。
  • 复制粘贴: 从开源项目中复制几十行核心算法代码到自己的项目中。
  • 打补丁(Patching): 即使你只分发补丁文件,但补丁本身依赖于原代码,通常也被视为衍生工作的一部分。

基本认可场景(普遍共识属于衍生作品)

  • 高级语言编译型组件: golang、rust等高级语言,在编译过程自动下载软件源码参与编译,最终在呈现在制品中。
  • 静态链接:几乎公认为是衍生作品。因为编译后,你的代码和开源代码在二进制层面已经物理“融为一体”了。

争议较大的场景

  • 动态链接库调用:争议很大。FSF(自由软件基金会)观点:软件是一个整体。如果你通过链接(Linking)(无论是静态还是动态)将你的代码与 GPL 代码组合,它们共享内存空间、共享数据结构,功能上互相依赖;因此,链接 = 衍生作品。商业抗辩观点:著作权保护的是“表达”(Expression),不是“功能”(Function)。我调用你的函数(API),就像是用插头插进插座。我没有复制插座内部的线路设计(源码),我只是使用了它的接口;因此,动态链接 ≠ 衍生作品(只要它们是独立文件)。
  • Java/Python 等解释型语言的 Classpath 调用: 通常视为动态链接库。
  • 插件(Plugins)与主程序(主程序是闭源的,加载了一个 左权的插件):争议较大,边界模糊。如果插件只是通过主程序提供的标准、公开 API 通信,主程序通常不被视为被传染(例如 Windows 运行 GPL 软件,Windows 不会被传染)。但是,如果插件和主程序之间交互极其紧密,交换了复杂的内部数据结构,FSF 认为这依然可能构成传染。
  • 包装器(Wrapper)/ 垫片(Shim):为了隔离 GPL 库,开发者写了一个中间层(Wrapper,用宽松协议如 MIT),主程序调用 Wrapper,Wrapper 再调用 GPL 库。如果 Wrapper 仅仅是简单的透传(Pass-through),在法律上可能被视为“规避措施”或“虚假隔离”,无法阻断传染性。除非 Wrapper 提供了实质性的抽象层。

合规指引:
(1) 严格禁止在闭源代码中把左权协议代码复制、粘贴进项目,严格禁止静态链接左权协议软件库,严格禁止编译时混入左权软件源码。
(2) 面对争议场景,黄金法则:默认视为“会传染”。在企业合规策略中,为了稳健经营,不要去挑战 FSF 的定义。
(3) 在商业(专有)软件中,避免动态链接 GPL(Strong Copyleft)组件。
(4) 安全的隔离方法——进程隔离:将 GPL 代码封装成一个独立运行的可执行文件(Service/Daemon),商业主程序通过 Socket (TCP/IP), Pipe, REST API, gRPC, 命令行参数 (CLI) 与其通信。这种方式被公认为阻断了传染性。因为两者内存空间独立,仅仅是数据交换。
(5) 协议替代:寻找功能类似的,但使用 MIT, Apache 2.0, BSD 或 LGPL 协议的库进行替代

2.2.7.4 强左权与弱左权

强 Copyleft (如 GPL): 传染性极强。只要主程序静态链接或在同一进程空间内深度调用了 GPL 库,整个主程序通常都被视为衍生作品,必须开源。
弱 Copyleft (如 LGPL, MPL): 传染性有限。

  • LGPL: 允许动态链接。只要你只是动态调用它,不修改库本身,你的主程序可以不开源。
  • MPL/CDDL: 文件级传染。只要求你修改过的那个开源文件及其派生文件开源,你自己写的文件(即使在同一个项目中)不受影响。

合规指引:
严格禁止将LGPL的代码复制到闭源项目中,严格禁止静态链接LGPL软件库,必须保持LGPL动态链接方式
MPL/CDDL虽然是文件级隔离,但合规检测难度较大;推荐按动态库的方式进行隔离维护,不要以源码的方式引入到项目中

2.2.8 网络左权 (Network Copyleft / AGPL)

定义: 专门针对云服务设计的传染机制

哪怕没有分发(不给安装包),只要用户通过网络(Web/API)使用了该软件的功能,就必须向用户提供源码。
AGPL 为了堵住GPL等传统强左权协议在 分发认定上,被云平台服务商钻空子。

合规指引:
后端开发、SaaS 产品严禁引入 AGPL 库(如某些 PDF 处理库、数据库中间件),除非你是作为独立进程且完全不修改它(满足隔离要求,满足开源要求)。

2.2.9 商业限制 / 源码可用 (Business Source / Commons Clause)

定义: 源码公开,但禁止特定商业行为

这不是开源(Open Source),而是“源码可用”(Source Available)。
典型条款例如:

  • SSPL (MongoDB): 如果你把这个数据库做成云服务卖给别人(Database-as-a-Service),你必须把你的云管平台源码也开源。
  • BSL (MariaDB / HashiCorp): 在生产环境只能运行特定节点以下,或者不能提供竞争性服务。

合规指引:
这类许可禁止引入商业产品中

第三部分:实操篇 —— 开发者的合规 SOP

核心观念: 合规不是最后一步,而是贯穿开发全生命周期。

3.1 选型与引入(Inbound)——进门检

在决定使用某个开源组件前,必须执行以下检查:

步骤一:License 识别
不要只看 GitHub 首页的简介,要点开根目录下的 LICENSE 文件或 package.json / pom.xml 确认。

步骤二:对照黑白名单

  • 直接可用:宽松类许可,如 MIT, Apache-2.0, BSD-3-Clause, ISC.
  • 需隔离使用(仅动态链接):弱左权类许可,如 LGPL, MPL(禁止复制源码到项目里)。
  • 谨慎分析后决定(需CTO+法务审核范围和风险应对):强左权类许可,如 GPL, AGPL(做好进程隔离,或评估遵从开源要求)。
  • 禁止引入: 商业限制许可或病毒许可,如CC-BY-NC,JSON。禁止引入无许可软件。

步骤三:依赖扫描
你引入的包 A (MIT) 可能依赖了包 B (GPL)。这叫“依赖传染”。

  • 操作: 必须运行公司的 SCA(软件成分分析)工具扫描整个依赖树。

步骤四:代码处理

  • 禁止裸抄: 严禁从 StackOverflow 或 博客 复制粘贴几十行以上的代码片段,除非确认其协议。
  • 保留头部: 如果引入源代码文件,绝对不能删除文件头部的 Copyright 和 License 声明块。

3.2 开发与修改(Development)

场景 A:我修改了开源组件的源码

  • 宽松协议(Apache/MIT): 建议在文件头部添加注释 // Modified by [Company Name] at [Date],说明修改点。这是免责也是礼貌。
  • 弱传染协议(MPL/LGPL):
    • 切记: 将修改后的文件或库单独存放,不要与公司的私有业务逻辑代码混淆。
    • 准备: 做好随时将这部分修改后的源码公开的准备。

场景 B:我只是调用(Link/Import)

  • 对于 LGPL 组件,确保构建脚本(Maven/Gradle/Webpack)将其打包为独立文件(如 .jar, .so),而不是将其代码合并混淆到主程序中。

3.3 发布与输出(Outbound)——出门检

当产品(App、固件、安装包)准备对外发布时:

步骤一:生成《开源许可声明》(Open Source Notice)
这是法律强制要求。必须在软件的“关于”页面、设置页面或安装包根目录下,提供一份文档。

  • 内容包括: 所有使用的开源组件名称、版本、License 全文、Copyright 信息。
  • 工具: 使用自动化插件生成(如 license-maven-plugin 或前端的 license-checker)。

步骤二:源码合规包(针对 GPL/LGPL)
如果产品中包含了 GPL/LGPL 组件且进行了分发:

  • 必须在 Written Offer(书面要约)中告知用户:“您可以联系我们索取相关开源组件的源代码”
  • 或者直接在官网提供源码下载链接。

3.4 对外贡献与开源(Contributing)

场景:员工想给开源社区提 PR

  • 原则: 工作时间的产出归公司。提 PR 代表公司对外授权。
  • CLA 审查: 如果项目要求签署 CLA (Contributor License Agreement),必须由法务审核。
    • 风险: 某些 CLA 会要求你放弃专利权,或者允许项目方将你的代码闭源商用。

结语

开源合规的目标不是“为了不被起诉”,而是为了建立可持续的软件交付能力

当每一位开发者都具备了基础的合规意识,我们就建立了一道无形的防火墙,保护了公司的知识产权,也尊重了社区的贡献。

如果在实际开发中遇到拿捏不准的 License,请务必遵循一个原则:“先咨询,后行动。”

文章来自个人专栏
文章 | 订阅
0条评论
0 / 1000
请输入你的评论
1
0