保护存储库和管道

已完成

当使用自动化来部署基础结构时,你的管道和存储库将变得强大而重要。 因为它们现在代表了将更改应用于受控环境的唯一方法。

需要保护 Azure DevOps 组织、GitHub 存储库和管道的许多部分。 下表显示了需要保护的一些最重要的元素,以及如果不充分保护这些元素则可能出现的漏洞的示例。

要保护的元素 漏洞示例
你的 Azure DevOps 组织或 GitHub 存储库,包括谁有权访问它以及允许他们执行什么操作。 心怀不满的前雇员删除了你的代码存储库。
存储库中的重要分支,以及更改这些分支上的代码所需的内容。 有人意外地将一些不安全的 Bicep 代码提交到存储库的主分支。
存储库中的代码,包括基础结构定义、测试和应用程序代码。 如果用户忘记测试他们编写的代码,当这些代码发布到生产环境时,代码无法正常工作。
管道定义。 有人无意中添加了将数据库连接字符串写入管道日志的管道步骤。
运行管道的代理或运行程序。 针对草稿拉取请求运行的管道会在代理上安装安全漏洞,该漏洞随后将用于生产部署。
可能在管道中运行的任何第三方任务或组件。 第三方管道任务将服务主体的凭据发送到恶意网站。
管道用于访问 Azure 的服务主体。 非生产服务主体意外更改了生产环境。
管道用于访问外部系统的机密。 团队成员为原型编写了新的管道定义文件,并意外将其连接到生产环境。

现在,让我们了解一些可用于在 Azure DevOps 和 GitHub 中围绕代码存储库和部署管道应用治理和控制措施的方法。

管理用户和权限

考虑如何授予对 Azure DevOps 组织或 GitHub 存储库的访问权限。 考虑谁有权访问,以及他们能做什么。

最好使用组织的 Microsoft Entra 实例作为管道的标识提供者。 这样便可以确保每当有人加入或离开你的组织时,都会自动授予或撤销对管道的访问权限。 通过使用 Microsoft Entra ID,还可轻松实现条件访问和多重身份验证等保护。

注意

若要使用 Microsoft Entra 与 GitHub 的集成,组织需要 GitHub Enterprise 许可证。

还可以创建团队(GitHub 中)或群组(Azure DevOps 中),它们表示可以一起被授予权限的用户集。 这样就不需要单独分配权限了。 通过在团队或组中添加和删除用户,可以轻松更改用户的权限。

提示

Azure DevOps 使用最低特权权限模型,这与 Azure 使用的模型不同。 在 Azure DevOps 中,“拒绝”权限会替代“允许”权限。 这意味着如果被分配到具有不同权限集的多个组,则只能执行所有组都有权执行的操作。

确保了解如何分配权限,尤其是组权限分配。

保护重要的代码分支

管道和自动化应基于对特定代码分支的标识,例如主分支。 这些指定分支上的代码通常受到信任,并允许将它们部署到生产环境。 应用控件以确保重要分支上的代码已经过验证和审阅。

考虑使用分支保护规则(在 GitHub 中)或分支策略(在 Azure Repos 中)来防止直接提交到重要的代码分支。 然后可以要求团队使用拉取请求来合并任何更改。 可以应用自动检查和手动评审过程来验证更改在合并之前是否有效。

测试和查看代码

确保团队了解对评审和测试所有代码的预期,包括基础结构定义。

管道定义是 YAML 文件,因此是一种特定形式的代码。 需要查看和评估对管道定义的更改。 否则,有人可能会意外或恶意地创建管道步骤,该步骤会泄露服务主体的凭据或对 Azure 资产进行危险的更改。

需要彻底审查对管道定义文件所做的任何更改。 确保团队中的每个人都了解管道是高度特权化的,所有人需要特别注意。

保护管道代理和运行程序

管道在代理(Azure Pipelines)或运行程序(GitHub 操作)上运行。 可以将代理和运行程序视为虚拟机。 管道定义通过运行所提供的任务和脚本来控制这些虚拟机。

Azure Pipelines 和 GitHub Actions 提供由 Microsoft 或 GitHub 配置和维护的托管代理和运行程序。 平台所有者配置计算机使其符合建议的安全做法。 平台所有者的职责包括修补操作系统漏洞。

可以改为选择为代理和运行程序使用自己的物理或虚拟机。 这种类型的计算机称为自托管代理和运行器。 如果使用自托管代理和运行器,则需要负责确保正确配置计算机并防范威胁。

Microsoft 托管的代理和 GitHub 托管的运行程序是临时的。 管道运行结束时,将销毁对代理或运行程序的任何文件或配置更改。 如果自行托管代理或运行器,则同一台计算机可能会用于多个单独的管道或环境,包括生产和非生产环境。 假设有人创建了管道定义,该定义修改了代理操作系统上的一些重要文件,并从拉取请求运行管道。 下次针对生产环境运行部署时,它可能会重复使用代理。 现在,无法预测损坏的文件对生产环境的影响。

出于这些原因,最好随时使用 Microsoft 托管的代理和 GitHub 托管的运行程序。 如果必须使用自承载运行程序,请仔细评估其配置和使用所涉及的风险。

评估在管道中运行的第三方组件

如果使用社区提供的 GitHub Actions 或 Azure DevOps 扩展,应知晓生成它们的人员及其执行的操作。 第三方管道组件可能有权访问服务主体的凭据,也就可以访问 Azure 中的整个环境。

在 Azure DevOps 中,组织管理员通常需要先批准每个扩展,然后使用者才能使用。 如果你是组织的管理员,请考虑使用的每个组件中涉及的安全风险。 你负责验证这些组件是否可信和安全。

每当使用第三方操作或任务时,需要指定版本。 请考虑指定你查看过的确切版本。 允许管道自动使用更高版本可能会带来未查看的风险。

保护管道的服务主体

管道使用服务主体访问 Azure 和其他服务。 保护服务主体并确保其凭据不会被不当使用,这一点很重要。 请考虑应用多层保护。

首先,可以考虑保护服务主体的凭据:

  • 尽可能使用托管标识或工作负载标识来避免完全存储凭据。 尽管不能对所有管道使用托管标识或工作负载标识,但尽量在可行时执行此操作。
  • 规划服务主体凭据的定期更改或轮换方式。 例如,组织可能设置一个策略,每 90 天或 120 天轮换凭据。 考虑谁将负责轮换,以及如何更新使用凭据的所有位置。
  • 请考虑指定一个机密保管人,其角色是管理机密、密钥和证书,确保不向组织的其他部分公开机密。

接下来,考虑要向服务主体授予的权限:

  • 将 Microsoft Entra 条件访问策略应用到管道的服务主体。 这些策略有助于识别有风险的登录和行为。 例如,如果管道服务主体始终从一个地理区域登录,条件访问可以检测和防止来自意外位置的登录,因为这可能表示凭据已泄露。
  • 仔细考虑要向每个服务主体授予的权限。 例如,假设有一个用于读取共享资源的配置的服务主体。 请考虑是否只向该服务主体授予读取者访问权限,因为服务主体不需要执行任何需要更多特权的操作。
  • 对分配给服务主体的每个权限使用“最小范围”。 例如,如果服务主体只需要部署到单个资源组,则将角色分配范围限定为该资源组而不是整个订阅。
  • 对每个环境使用单独的服务主体。 这样即使主体的凭据遭到入侵,或者有人访问一个环境,他们也无法访问其他环境。

保护服务连接和机密

服务连接(在 Azure Pipelines 中)或机密(在 GitHub 中)包含管道用于访问 Azure 环境的服务主体的凭据。 请务必保护服务连接和机密,并控制哪些管道使用哪个服务连接和机密。 否则,可能会意外地使非生产环境能够使用对生产资源拥有访问权限的服务主体。

在 Azure DevOps 中创建服务连接时,可以将其配置为要求你批准后新管道或环境才能使用它。

Azure DevOps 还使你能够将检查与特定服务连接相关联。 检查会添加额外一层保护。 例如,可以配置对生产服务连接的检查,以验证它是否仅在存储库主分支的代码上使用。 此检查有助于防止未经授权的代码部署到生产环境。

在 GitHub 中,可以配置环境特定的机密,以便在 GitHub Actions 工作流使用该环境时,它仅提供机密值。 通过使用环境特定的机密和环境控制措施(如审批),可以降低使用非生产部署来部署到生产环境的风险。 还可以使用工作负载标识来避免在 GitHub Actions 工作流中使用任何凭据,并消除凭据公开的可能性。

使用 GitHub 安全功能

GitHub 提供你需要评估和使用的安全功能。 这些功能包括:

  • Dependabot,用于扫描源代码依赖项是否存在已知漏洞。
  • 机密扫描,用于标识存储库中类似于密钥或凭据的文本。 在存储库中存储机密是一种糟糕的做法。 如果收到有关存储库中某个机密的警报,应考虑机密的值遭到入侵,然后撤销或更改它。
  • 审核,了解谁对 GitHub 配置进行了更改。
  • 安全概述,它汇总了组织存储库中的所有安全警报。

使用 Azure DevOps 审核日志

Azure DevOps 提供审核日志,帮助你了解谁对管道、分支策略、存储库和其他资源进行了更改。 启用审核并定期查看审核日志是一种很好的做法。

保护存储库和管道

我们已经讨论了可以应用于存储库和管道的重要控制措施。 现在,让我们考虑可以使用哪些控制措施来保护本单元前面列出的每个重要元素:

要保护的元素 要应用的控件
你的 Azure DevOps 组织或 GitHub 存储库,包括谁有权访问它以及允许他们执行什么操作。
  • 使用 Microsoft Entra ID 进行身份验证
  • 使用团队和组分配权限。
  • 启用审核日志记录,并定期查看审核日志。
存储库中的重要分支,以及更改这些分支上的代码所需的内容。 应用分支保护规则或分支策略。
存储库中的代码,包括基础结构定义、测试和应用程序代码。
  • 强制实施代码评审要求。
  • 添加自动或手动测试。
  • 在 GitHub 上使用 Dependabot 和机密扫描。
管道定义。 强制实施代码评审要求。
运行管道的代理或运行程序。
  • 在 Azure Pipelines 上使用 Microsoft 托管的代理。
  • 在 GitHub Actions 上使用 GitHub 托管的运行程序。
可能在管道中运行的任何第三方任务或组件。 查看与所有第三方扩展和任务关联的安全风险。
管道用于访问 Azure 的服务主体。
  • 在 GitHub Actions 中使用工作负载标识。 对于 Azure Pipelines,使用服务主体并定期轮换其凭据。
  • 为每个环境使用单独的服务主体。
  • 应用条件访问策略。
管道用于访问外部系统的机密。
  • 在 Azure DevOps 上审批和检查服务连接。
  • 在 GitHub 上使用特定于环境的机密和工作负载标识。