本文档介绍了保护 build 的最佳实践。构建代码可以引用不同类型的操作,例如:
- 优化或混淆代码:例如,Google 开源工具 Closure Compiler 会解析和分析 JavaScript、移除无效代码,并重写和缩减剩余代码。它还会检查代码是否存在常见的 JavaScript 陷阱。
- 将代码编译为中间代码:例如,您可以将 Java 代码编译为 Java 类文件 (
.class
),或将 C++ 代码编译为对象文件 (.obj
)。 - 编译代码和链接、创建库或可执行文件:例如,
将 C++ 代码编译到共享库 (
.so
) 或 Windows 可执行文件中 文件 (.exe
)。 - 将代码打包为可分发或可部署的格式:例如:
从 Java 类文件创建 Java WAR (
.war
) 文件、创建 Docker 映像,或 创建 Python 构建的发行版 (.whl
)。
根据您使用的编程语言和要部署到的环境, 您的 build 可能包含这些操作的不同组合。例如,构建过程可能会将 Python 代码打包到构建的分发版中,并将其上传到 Artifact Registry 或 PyPI 等工件存储库,以便您在 Cloud Run 函数中将其用作依赖项。您还可以将 Python 代码容器化,并将容器映像部署到 Cloud Run 或 Google Kubernetes Engine。
本文档中的实践重点是构建代码以进行打包或部署到运行时环境,而不是编译代码。
使用自动构建
自动构建或脚本化构建在构建脚本中定义所有构建步骤 或 build 配置,包括检索源代码的步骤以及 构建代码。唯一的手动命令(如果有)是运行 build 的命令。
例如,构建脚本可以是:
- Cloud Build
cloudbuild.yaml
。 - 您使用
make
工具运行的 Makefile。 - 存储在
.github/workflows/
目录中的 YAML 格式的 GitHub Actions 工作流文件。
自动化构建可确保构建步骤的一致性。不过,在一致且可信的环境中运行 build 也很重要。
虽然本地 build 对调试很有用,但通过本地 build 发布软件可能会在构建流程中引入许多安全问题、不一致性和低效率。
- 允许本地构建会为有恶意意图的攻击者提供修改构建流程的方法。
- 开发者本地环境和开发者做法不一致的问题 难以重现构建和诊断构建问题。
手动构建会利用更多基础架构,导致流程效率低下 计算、存储和网络等资源。在 SLSA 框架要求,自动化构建是 SLSA 级别 1 的要求,并使用构建服务,而不是开发者 SLSA 级别 2 的要求。
Cloud Build 是 Google Cloud 上的托管式构建服务。它使用“构建配置”文件提供构建作业 Cloud Build 的步骤您可以配置构建以提取依赖项,运行单元测试、静态分析和集成测试,并使用 Docker、Gradle、Maven、Go 和 Python 等构建工具创建工件。Cloud Build 与 Google Cloud 上的其他 CI/CD 服务(例如 Artifact Registry 和 Cloud Deploy)以及 GKE 和 Cloud Run 等运行时环境完全集成。它还支持与 GitHub 和 Bitbucket 等主要源代码管理系统集成。
生成 build 出处
build 出处是一个集合 关于 build 的可验证数据。
出处元数据包括构建映像的摘要、 输入源位置、构建工具链以及构建时长。
生成 build 来源有助于您:
- 验证构建工件是否从可信来源位置创建,并 是由可信的构建系统提供的
- 识别从不受信任的源代码位置或构建系统注入的代码。
您可以使用提醒和政策机制主动使用 build 来源数据。例如,您可以创建仅允许部署从经过验证的来源构建的代码的政策。
对于 SLSA 级别 1,build 出处必须可供构建的 工件对于 SLSA 级别 2,构建源数据还必须:
- 由构建服务生成,或直接从构建服务读取。
- 真实性和完整性,可由消费者验证。这应使用创建 build 历史记录数据的服务生成的数字签名来完成。
对于 SLSA 3 级,来源内容还必须包括:
- 构建定义的入口点。
- 用户控制的所有 build 参数。
Cloud Build 可以为提供 SLSA 3 级 build 保证的容器映像生成 build 来源。如需了解详情,请参阅 查看构建来源。
使用临时构建环境
临时环境是指 单一构建调用。构建后,系统会擦除或删除环境。 临时构建可确保构建服务和构建步骤 可在临时环境中运行,例如容器或虚拟机。构建服务不会重复使用现有构建环境,而是为每个 build 预配一个新环境,并在构建流程完成后销毁该环境。
临时环境可确保干净 build,因为没有残留文件 或先前 build 中可能会干扰构建的环境设置 过程。非短暂环境为攻击者注入恶意文件和内容提供了机会。临时环境还可以降低 维护开销,并减少构建环境中的不一致问题。
Cloud Build 为 并在构建之后销毁它
限制对 build 服务的访问
遵循最小权限安全原则,向 build 服务和 build 资源授予所需的最小权限。您应该 还会使用非人类身份运行构建并与其他 来代表构建作业。
如果您使用的是 Cloud Build:
- 向组织成员授予所需的最低权限。
- 为代表 Cloud Build 执行操作的服务账号自定义权限,使其仅具有您使用所需的权限。修改默认 Cloud Build 服务账号的权限,或考虑改用自定义服务账号。
- 使用 Cloud Build 允许的集成 组织政策,以控制允许访问 调用构建触发器。
使用 VPC Service Controls 将 Cloud Build 放置在服务边界中。边界允许边界内的 Google Cloud 服务之间自由通信,但会根据您指定的规则限制跨边界的通信。通过 边界的数据渗漏风险也在降低。
Cloud Build 仅支持对您自己创建的 build 使用 VPC Service Controls 在专用池中运行。
保护凭据
build 通常包括与其他系统的连接,例如版本控制、 工件存储区和部署环境保护您在 build 中使用的凭据有助于防止对软件供应链中的系统进行未经授权的访问以及数据渗漏。
避免将硬编码凭据直接存储在版本控制系统中或 build 配置。请改为将凭据存储在安全的密钥库中。
在 Google Cloud 中,以安全的方式使用 Secret Manager 存储 API 密钥、密码和其他敏感数据。您可以将 Cloud Build 配置为使用存储在 Secret Manager 中的 Secret。
管理依赖项
应用的完整性依赖于代码的完整性 以及您使用的所有依赖项您还需要考虑 您发布依赖项后,该依赖项就有权访问 工件代码库以及适用于构建工件的可信来源的政策 您可以部署到运行时环境中。
如需详细了解依赖项管理,请参阅管理依赖项。
在 Cloud Build 中,您可以使用Cloud Build 构建器来运行 命令。构建器是安装有常用语言和工具的容器映像。您可以使用公共注册表中的公共容器映像 例如 Docker Hub、Cloud Build 提供的构建器 社区提供的构建器和您创建的自定义构建器。您还可以将 buildpack 用作构建器,包括 Google Cloud 的 buildpack。
查看您在 Cloud Build 构建中使用的构建器, 了解他们的软件由谁提供,并决定是否信任他们的软件 或供应链如需更好地控制构建器中的代码,您可以创建自定义构建器,而不是使用公共来源中的构建器。
减少更改 build 的机会
影响 build 的其他因素也有很多,包括:
- 并发运行且能够相互影响的 build,或持久存在且会影响后续 build。
- 接受除 build 入口点和 顶级源代码位置
- 指定依赖项的范围或依赖项
可变(例如,使用带有
latest
标记的映像)。这些 会给构建使用不良或不想要版本的 依赖项
以下做法有助于降低这些风险:
- 请在临时环境中运行每个构建。
- 避免运行带有额外参数的 build,以免用户 影响构建脚本中定义的变量。
- 限制对 build 服务和 build 资源的访问权限。
- 引用依赖项的不可变版本,而不是标识符,例如 未来可能指向其他版本的工件的标记。 如需详细了解依赖项,请参阅 依赖项管理。
Software Delivery Shield
Software Delivery Shield 是一种全代管式端到端软件供应链安全解决方案。它在 Google Cloud 服务中提供了一组全面且模块化的功能和工具,开发者、DevOps 团队和安全团队可以使用这些工具来改善软件供应链的安全状况。它 会显示安全性数据分析 Cloud Build 界面的“构建的应用”部分 Google Cloud 控制台。其中包括:
- SLSA 级别,用于确定软件的成熟度级别 供应链安全。
- build 工件的漏洞、软件物料清单 (SBOM) 和漏洞可利用性交流 (VEX) 语句。
- build 出处,这是关于 build。其中包括已构建映像的摘要、输入源位置、构建工具链、构建步骤和构建时长等详细信息。
如需了解如何查看构建的应用的安全数据分析,请参阅构建应用并查看安全数据分析。
后续步骤
- 了解保护源代码的最佳实践。
- 了解保护依赖项的最佳实践。
- 了解保护部署的最佳实践。