安全最佳做法

Azure DevOps Services | Azure DevOps Server 2022 - Azure DevOps Server 2019

处理信息和数据时,尤其是在基于云的解决方案(如 Azure DevOps Services)中,安全性应是首要任务。 虽然Microsoft确保底层云基础结构的安全性,但需负责在 Azure DevOps 中配置安全性。

虽然不是强制性的,但整合最佳做法可以显著增强你的体验并增强安全性。 以下建议旨在帮助维护安全的 Azure DevOps 环境。

保护 Azure DevOps 环境

使用以下最佳做法 删除用户查看审核事件以及 与 Microsoft Entra ID 集成。

删除用户

  • 从 MSA 帐户中删除非活动用户:
    • 如果组织使用 MSA 帐户, 请直接从组织中删除非活动用户。
    • 遗憾的是,没有其他方法可以阻止这些用户访问。
    • 请记住,无法为分配给已删除 MSA 帐户的工作项创建查询。
  • 禁用或删除Microsoft Entra 用户帐户:
    • 如果组织已连接到 Microsoft Entra ID,则可以禁用或删除 Microsoft Entra 用户帐户,同时使 Azure DevOps 用户帐户保持活动状态。
    • 使用此方法,可以使用 Azure DevOps 用户 ID 继续查询工作项历史记录。
  • 撤销用户 PAT
    • 定期查看和撤销任何现有用户 PAT。
    • PAT 是关键的身份验证令牌,安全管理令牌至关重要。
  • 撤销授予单个用户的特殊权限:
    • 审核和撤销授予单个用户帐户的任何特殊权限。
    • 确保权限符合最低特权原则。
  • 从已删除的用户重新分配工作:
    • 删除用户之前,请重新分配他们正在处理的任何工作项。
    • 在当前团队成员之间分配工作负荷。

使用 Microsoft Entra ID

  • 标识的单平面:
    • 通过将 Azure DevOps 连接到 Microsoft Entra ID,可以建立统一的标识系统。
    • 服务之间的一致性可降低混淆,并最大限度地减少手动配置错误带来的安全风险。
  • 端到端治理:
    • 利用 Microsoft Entra ID,可以实现精细治理。
    • 将不同的角色和权限分配给跨各种资源范围的特定Microsoft Entra 组。
    • 此方法可确保受控访问并与安全最佳做法保持一致。
  • 安全功能:
    • Microsoft Entra ID 支持其他安全功能,例如:
      • 多重身份验证(MFA): 通过要求多种因素(例如密码和电话验证)增强用户身份验证。
      • 条件访问策略: 根据条件(例如位置、设备或风险级别)定义访问规则。

有关详细信息,请参阅以下文章:

查看审核事件

组织由 Microsoft Entra 提供支持后,请执行以下任务来增强安全性和监视使用模式:

  • 启用审核:
    • 在安全策略中,启用审核。
    • 审核有助于跟踪和记录与用户操作、权限和更改相关的事件。
  • 定期查看审核事件
    • 定期查看审核日志。
    • 查找意外的使用模式,尤其是管理员和其他用户。

保护网络

以下函数是使用 Azure DevOps 时增强网络安全性的有效方法。

  • IP 允许列表:
    • 设置 允许列表 以限制对特定 IP 地址的访问。
    • 仅允许来自受信任源的流量,从而减少攻击面。
  • 加密
    • 始终对传输中的数据和静态数据使用加密。
    • 使用 HTTPS 等协议保护信道的安全。
  • 证书验证:
    • 建立连接时验证证书。
    • 确保证书有效且由受信任的颁发机构颁发。
  • Web 应用程序防火墙(WAF):
    • 实现 WAF 来筛选、监视和阻止基于 Web 的恶意流量。
    • WAF 提供了针对常见攻击的附加保护层。

有关详细信息,请参阅 应用程序管理最佳做法


限定范围的权限

系统处理各个级别(单个、集合、项目和对象)的权限,并默认将其分配给一个或多个内置组。 若要增强安全性,请执行以下操作:

  • 提供最低特权访问权限: 为用户和服务提供执行其业务功能所需的最低访问权限。
  • 禁用继承:
    • 尽可能禁用继承。
    • 由于默认允许的性质,继承可能会无意中向意外用户授予访问权限或权限。
    • 有关详细信息,请参阅 有关权限继承的部分

有关权限的详细信息,请参阅以下文章:

项目级别的权限

  • 限制对项目和存储库的访问:
    • 若要降低泄露敏感信息并将不安全代码部署到生产的风险,请限制对项目和存储库的访问。
    • 使用内置安全组或自定义安全组来管理权限。 有关详细信息,请参阅 授予或限制对特定任务的权限。
  • 禁用 “允许公共项目”
    • 在组织的策略设置中,禁用用于创建公共项目的选项。
    • Azure DevOps Services 允许你将项目可见性从公共切换到专用(反之亦然)。
    • 尚未登录到组织的用户对公共项目具有只读访问权限。
    • 可以向已登录用户授予对专用项目的访问权限,并进行更改。
  • 限制项目创建:
    • 防止用户创建新项目,以保持对环境的控制。

外部来宾访问

  • 阻止外部来宾访问:
  • 对个人和企业帐户使用不同的电子邮件或 UPN:
    • 尽管允许,但对个人和业务帐户使用不同的电子邮件地址或用户主体名称(UPN)。
    • 在消除与个人与工作相关的帐户之间的歧义时,这种做法消除了歧义。
  • 对外部来宾用户进行分组:
    • 将所有外部来宾用户放在单个Microsoft Entra 组中。
    • 适当地管理此组的权限。
    • 删除直接分配,确保组规则适用于这些用户。 有关详细信息,请参阅 添加组规则以分配访问级别
    • 定期重新评估“用户”页的“组规则”选项卡上的规则。 请考虑Microsoft可能影响组织的 Entra ID 中的任何组成员身份更改。 Microsoft Entra ID 最多可能需要 24 小时才能更新动态组成员身份。 规则每 24 小时自动重新评估一次,每当组规则发生更改时。

有关详细信息,请参阅 Microsoft Entra ID 中的 B2B 来宾。


管理安全组

安全和用户组

下表显示了向安全组和用户组分配权限的建议。

不要
在管理大量用户时,请使用 Microsoft Entra ID、Active Directory 或 Windows 安全组。 请勿更改 “项目有效用户组 ”的默认权限。 此组可以访问和查看项目信息。
添加团队时,请考虑要为需要创建和修改区域路径、迭代路径和查询的团队成员分配哪些权限。 不要将用户添加到包含不同权限级别的多个安全组。 在某些情况下, “拒绝” 权限级别可能会覆盖 “允许” 权限级别。
添加多个团队时,请考虑创建 一个团队管理员 自定义组,在其中分配可供 项目管理员使用的权限子集。 不要更改对 “项目有效用户组” 进行的默认分配。 如果删除某个项目有效用户组“查看实例级信息”或将其设置为“拒绝”,则组中的任何用户都无法访问你设置权限的任何项目、集合或部署。
考虑向需要为项目创建和共享工作项查询的用户或组授予工作项查询文件夹 “参与参与 ”权限。 不要将标记为 “仅分配给服务帐户”的权限分配给 用户帐户。
使组尽可能小。 应限制访问,并且应经常审核组。
利用内置角色,并且开发人员的角色默认为参与者。 管理员会被分配到项目管理员安全组以获得提升的权限,使他们能够配置安全权限。

有关详细信息,请参阅 “有效用户组”。

管理员组的实时访问

如果具有 项目集合管理员项目管理员 访问权限,则可以修改组织或项目的配置。 若要增强这些内置管理员组的安全性,请考虑使用 Microsoft Entra Privileged Identity Management (PIM) 组实现实时访问。 此方法允许仅在需要时授予提升的权限,从而减少与永久访问相关的风险。

配置访问权限

  1. 在 Microsoft Entra ID 中创建可分配角色的组。
  2. 将Microsoft Entra 组添加到 Azure DevOps 组

注意

使用 Microsoft Entra Privileged Identity Management (PIM) 组配置实时访问时,请确保具有提升访问权限的任何用户也会保留对组织的标准访问权限。 这样,他们就可以查看所需的页面并根据需要刷新其权限。

使用访问权限

  1. 激活访问权限
  2. 在 Azure DevOps 中刷新权限
  3. 执行需要管理员访问权限的操作。

注意

用户在其 PIM 组访问停用后,在 Azure DevOps 中提升访问权限长达 1 小时。

作用域服务帐户

  • 了解 服务帐户
  • 创建单用途服务帐户:
    • 每个服务都应有其专用帐户来最大程度地降低风险。
    • 避免使用常规用户帐户作为服务帐户。
  • 遵循命名和文档约定:
    • 为服务帐户使用清晰的描述性名称。
    • 记录其用途和关联服务。
  • 识别和禁用未使用的服务帐户:
    • 定期查看和标识不再使用的帐户。
    • 在考虑删除之前禁用未使用的帐户。
  • 限制特权:
    • 将服务帐户特权限制为所需的最低权限。
    • 避免服务帐户的交互式登录权限。
  • 对报表读取者使用单独的标识:
    • 如果对服务帐户使用域帐户,请对报表读取者使用不同的标识。
    • 隔离权限以防止不必要的访问。 有关详细信息,请参阅 服务帐户和依赖项
  • 对工作组安装使用本地帐户:
    • 在工作组中安装组件时,对用户帐户使用本地帐户。
    • 避免在此方案中使用域帐户。 有关详细信息,请参阅 服务帐户要求
  • 利用 服务连接
    • 尽可能使用服务连接。
    • 它们提供了一种安全的方式来连接到服务,而无需将机密变量直接传递给生成。
    • 限制与特定用例的连接。
  • 监视服务帐户活动:

有关详细信息,请参阅 常见服务连接类型

范围服务连接

  • 将 Azure 资源管理器服务连接范围
    • 若要限制访问权限,请将服务连接范围限定为特定的资源和组。 避免在整个 Azure 订阅中授予广泛的参与者权限。
    • 使用工作负荷标识联合身份验证进行身份验证。 这允许 Azure Pipelines 中的无机密服务连接。
  • 使用工作负荷标识联合
    • 工作负荷标识联合使用 OpenID Connect(OIDC)在不使用机密的情况下使用 Azure 资源进行身份验证。
    • 可以自动或手动创建工作负荷标识联合。 如果:
      • 你拥有 Azure 订阅的所有者角色。
      • 你未连接到 Azure Stack 或 Azure 美国政府环境。
      • 使用支持工作负荷标识联合身份验证的任何市场扩展任务。
  • 资源组范围:
    • 确保资源组仅包含生成过程所需的虚拟机(VM)或资源。
  • 避免 Azure 经典服务连接:
    • 经典服务连接缺少范围选项。 改为选择新式 Azure 资源管理器服务连接。
  • 使用特定于用途的团队服务帐户:
    • 使用特定于用途的团队服务帐户对服务连接进行身份验证,以维护安全性和控制。

有关详细信息,请参阅 常见服务连接类型


选择正确的身份验证方法

从以下源中选择 身份验证方法

考虑服务主体

探索服务主体和托管标识等 替代项

  • 服务主体:
    • 表示Microsoft Entra 应用程序中的安全对象。
    • 定义应用程序可在给定租户中执行的操作。
    • 在Azure 门户中的应用程序注册期间设置。
    • 配置为访问 Azure 资源,包括 Azure DevOps。
    • 适用于需要特定访问和控制的应用。
  • 托管标识:
    • 类似于应用程序的服务主体。
    • 提供 Azure 资源的标识。
    • 允许支持Microsoft Entra 身份验证的服务共享凭据。
    • Azure 会自动处理凭据管理和轮换。
    • 理想情况下需要无缝登录详细信息管理。

请谨慎使用 PAT

  • 将 PAT 的范围限定为特定角色:
    • 仅分配特定任务所需的必要权限。 避免向多个组织或存储库授予全局访问权限。
    • 确定 PAT 的范围可确保它们具有所需的最低权限,从而减少意外滥用的风险。
  • 避免 对生成和发布写入管理 权限:
    • PAT 不应对生成、发布或其他关键资源具有写入或管理权限。
    • 限制这些权限有助于防止可能影响管道或部署的意外操作。
  • 设置过期日期并保留 PAT 机密:
    • 始终为 PAT 设置到期日期。 根据需要定期查看和续订它们。
    • 将 PAT 视为关键密码。 将它们保密,避免在应用程序代码中公开或硬编码它们。
  • 避免在应用程序代码中硬编码 PAT:
    • 虽然看起来可能很方便,但避免直接在代码中嵌入 PAT。
    • 请改用安全配置文件或环境变量来动态存储和检索 PAT。
  • 定期审核和撤销未使用的 PAT:
    • 管理员应定期使用 REST API 查看所有 PAT。
    • 撤销不再需要或不符合建议条件的任何 PAT。

有关详细信息,检查以下文章:


保护 Azure Artifacts

保护 Azure Boards

保护 Azure Pipelines

策略

  • 要求原始请求者外部的审阅者:
    • 在原始请求者之外至少有一个审阅者可确保更彻底的评审过程。
    • 审批者共享更改的共同所有权,应同样追究任何潜在影响的责任。
  • 要求 CI 生成通过:
    • 在合并 PR 之前,要求持续集成 (CI) 生成为代码质量建立基线。
    • CI 检查包括代码 linting、单元测试和安全扫描(例如病毒和凭据检查)。
  • 禁止原始请求者自行批准:
    • 阻止原始 PR 请求者批准自己的更改。
    • 此操作可确保无偏见的审查过程,并避免潜在的利益冲突。
  • 即使“等待”或“拒绝”投票,也不允许 PR 完成:
    • 即使某些审阅者投票等待或拒绝,也阻止 PR 完成。
    • 此操作鼓励在合并之前解决所有反馈。
  • 重置代码审阅者对推送的更改进行投票:
    • 将最近的更改推送到 PR 时,重置审阅者投票。
    • 此操作可确保审阅者重新评估更新的代码。
  • 将发布管道锁定到特定的生产分支:
    • 将发布管道限制为特定分支(通常是生产或主分支)。
    • 避免从其他分支意外部署。
  • 在队列时强制实施可设置变量:
    • 为管道变量启用“在队列时强制设置”选项。
    • 此操作可防止用户在管道执行期间重写变量值。
  • 禁止编辑器中的变量重写:
    • 对于管道编辑器中设置的变量,禁止用户替代。
    • 此操作保持一致性,并防止意外更改。

代理

  • 谨慎授予权限:
    • 将权限限制为最小必需的帐户集。
    • 避免过度宽松的访问,减少攻击面。
  • 可用代理的限制性防火墙:
    • 将防火墙配置为尽可能限制,同时仍允许代理正常运行。
    • 在安全性和可用性之间取得平衡。
  • 定期更新代理池:
    • 定期更新代理,使代理群保持最新状态。
    • 此操作可确保易受攻击的代码未运行,从而减少漏洞利用的风险。
  • 生产项目的单独代理池:
    • 使用不同的代理池生成目标为生产的项目。
    • 隔离生产项目有助于防止意外部署非生产分支。
  • 细分敏感池:
    • 为敏感和非敏感工作负荷创建单独的池。
    • 仅允许与相应池关联的生成定义中的凭据。

定义

  • 将 YAML 用于管道定义:
    • YAML(又一种标记语言)是用于定义管道的建议方法。
    • 它为更改提供可跟踪性,使跟踪一段时间内的修改更容易。
    • 此外,YAML 管道可以遵循审批准则和版本控制做法。
  • 限制 对管道定义的编辑 访问:
    • 将编辑管道定义的访问权限限制为所需的最低帐户。
    • 这样做可以降低意外或未经授权的更改的风险。

Input

  • 在生成脚本中包含变量的健全性检查:
    • 在生成脚本中实现健全性检查,以通过可设置的变量缓解潜在的命令注入攻击。
    • 这些检查可以验证输入值并防止意外或恶意命令。
  • 限制“发布时可设置”生成变量的数量:
    • 将尽可能少的生成变量设置为“在发布时可设置”。
    • 最大程度地减少此类变量的数量可减少攻击面并简化配置管理。

任务

  • 避免远程提取的资源:
    • 尽可能避免在生成过程中从外部 URL 提取资源。
    • 如果需要远程资源,请使用版本控制和哈希检查来确保完整性。
  • 避免记录机密:
    • 切勿在生成日志中记录敏感信息,例如机密或凭据。
    • 日志记录机密可能会无意中公开它们并损害安全性。
  • 对机密使用 Azure 密钥库:
    • 使用 Azure 密钥库,而不是直接将机密存储在管道变量中。
    • 密钥库提供了一种安全的方式来集中管理和检索机密。
  • 根据任意分支或标记限制正在运行的生成:
    • 对于安全关键管道,请限制用户针对任何分支或标记运行生成。
    • 定义特定的授权分支或标记,以防止意外或未经授权的执行。
  • 禁用管道权限的继承:
    • 继承的权限可能过于广泛,可能无法准确反映你的需求。
    • 禁用继承并显式设置权限,以符合安全要求。
  • 限制作业授权范围:
    • 始终将作业授权范围限制为所需的最低范围。
    • 根据每个作业执行的特定任务微调权限。

存储库和分支

  • 需要最少数量的审阅者:
    • 启用“需要最少数量的审阅者”策略,以确保每个拉取请求至少接收两个审批者的评审。
    • 这将促进彻底的代码审查和责任。
  • 配置特定于存储库的安全策略:
    • 而不是项目范围的策略,而是为每个存储库或分支定制安全策略。
    • 自定义策略可降低风险,强制实施变更管理标准,并提高代码质量。
  • 在单独的密钥保管库中隔离生产机密:
    • 将生产机密单独存储在 Azure 密钥库中。
    • 限制对需要了解的基础的访问,以保持与非生产版本的分离。
  • 将测试环境与生产隔离:
    • 避免将测试环境与生产环境混合使用。
    • 确保非生产上下文中不使用凭据和机密。
  • 禁用分叉:
    • 禁用分叉有助于管理安全性。
    • 分支可以激增,这使得跟踪所有副本的安全性具有挑战性。
  • 避免向分叉生成提供机密:
    • 不要与分叉生成共享机密。
    • 机密应保持机密,不会向分支公开。
  • 请考虑手动触发分叉生成
    • 手动触发分叉生成,而不是允许自动触发器。
    • 这样可以更好地控制安全检查。
  • 使用分支版本的Microsoft托管代理:
    • 利用Microsoft托管的代理分支生成。
    • 这些代理是维护和安全的。
  • 扫描 Git 存储库中的生产生成定义:
    • 定期检查存储在项目的 Git 存储库中的生产生成定义。
    • 扫描任何凭据或敏感信息。
  • 为生产上下文配置分支控制检查:
    • 设置分支控制检查,将敏感连接(例如 prod-connection)的使用限制为在生产分支上下文中运行的管道。
    • 这可确保适当的授权并防止意外滥用。

有关详细信息,请参阅 其他安全注意事项

保护 Azure Repos

保护 Azure Test Plans

安全 GitHub 集成

  • 使用 OAuth 流而不是 PAT:
    • 为 GitHub 服务连接禁用基于 PAT 的身份验证。
    • 选择 OAuth 流,从而提供更好的安全性和集成。
  • 避免管理员或所有者标识:
    • 切勿使用任何存储库的管理员或所有者的标识对 GitHub 服务连接进行身份验证。
    • 将权限限制为必要的级别。
  • 避免使用完整范围的 GitHub PAT:
    • 不要使用完整的 GitHub PAT 对服务连接进行身份验证。
    • 使用具有最低所需权限的令牌。
  • 避免将个人 GitHub 帐户用作服务连接:
    • 请勿在 Azure DevOps 中使用个人 GitHub 帐户作为服务连接。
    • 而是创建专用服务帐户或使用组织级帐户。