本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
通过部署角色自动分配机器解决方案,预调配最低权限 IAM 角色
Benjamin Morris、Nima Fotouhi、Aman Kaur Gandhi 和 Chad Moon,Amazon Web Services
Summary
管道的超范围 AWS Identity and Access Management (IAM)角色权限可能会给组织带来不必要的风险。开发人员有时会在开发过程中授予广泛的权限,但在对代码进行问题排查后却忘记缩小权限范围。这导致了一个问题:存在一些强大的角色,它们在业务上没有必要,而且可能从未经过安全工程师的审查。
此模式提供了可解决这个问题的方案:角色自动分配机器(RVM)。RVM 使用安全的集中式部署模型,演示了如何以最少的开发人员努力为各个 GitHub 仓库的管道配置权限最低的 IAM 角色。由于 RVM 是集中式解决方案,您可以将安全团队配置为必要的审核人员,负责审批变更。此方法允许安全机制拒绝权限过高的管道角色请求。
RVM 将 Terraform 代码作为输入,生成可用于管道的 IAM 角色作为输出。所需的输入是 AWS 账户 ID、 GitHub 存储库名称和权限策略。RVM 使用这些输入来创建角色的信任策略和权限策略。由此产生的信任策略允许指定的 GitHub 存储库担任该角色并将其用于管道操作。
RVM 使用 IAM 角色(在引导期间配置)。该角色有权在组织 role-provisioning-role中的每个账户中扮演一个。该角色可通过 Account Factor AWS Control Tower y for Terraform (AFT) 或。 AWS CloudFormation StackSets role-provisioning-roles这些角色实际上是为开发人员创建管道角色。
先决条件和限制
先决条件
活跃 AWS 账户的.
一种用于通过 GitHub 操作部署基础设施即代码 (IaC) 的 GitHub 组织。 (GitHub Enterprise/Premium/Ultimate不是必填项。)
多账户 AWS 环境。这个环境不一定是其中的一部分 AWS Organizations。
一种用于在所有角色中部署 IAM 角色的机制 AWS 账户 (例如,AFT 或 CloudFormation StackSets)。
已安装并配置
Terraform 版本 1.3 或更高版本。
限制
此模式的代码特定于 Actions 和 Terraform。 GitHub 但是,此模式的一般概念可以在其他持续集成和交付(CI/CD)框架中重复使用。
有些 AWS 服务 并非全部可用 AWS 区域。有关区域可用性,请参阅按区域划分的AWS 服务
。有关特定端点,请参阅服务端点和配额,然后选择相应服务的链接。
架构
下图说明了此模式的工作流。

角色自动分配机器的典型使用工作流包含以下步骤:
开发人员将包含新请求的 IAM 角色的 Terraform 代码的代码推送到 R GitHub VM 存储库。此操作会触发 RVM GitHub 操作管道。
管道使用 OpenID Connect(OIDC)信任策略来担任 RVM 角色假设角色。
当 RVM 管道运行时,在预调配开发人员新 IAM 角色的账户中担任 RVM 工作流角色。(RVM 工作流程角色是使用 AFT 或 CloudFormation StackSets配置的。)
RVM 创建具有适当权限和信任的开发人员 IAM 角色,以便其他应用程序管道可以担任该角色。
应用程序开发人员可以配置其应用程序管道,以承担这个 RVM 预调配的角色。
创建的角色包括开发人员请求的权限和 ReadOnlyAccess 策略。只有针对开发人员指定存储库 main 分支运行的管道才能担任该角色。这种方法有助于确保必须完成分支保护和审查,才能使用该角色。
自动化和扩展
根据最低权限机制,我们必须注意正在预调配的每个角色的细节。此模型降低了创建这些角色所需的复杂性,使得开发人员无需额外学习或付出太多努力,即可创建所需角色。
工具
AWS 服务
AWS Identity and Access Management (IAM) 通过控制谁经过身份验证并有权使用 AWS 资源,从而帮助您安全地管理对资源的访问权限。
AWS Organizations是一项账户管理服务,可帮助您将多个账户整合 AWS 账户 到一个由您创建和集中管理的组织中。
其他工具
代码存储库
此模式的代码可在 GitHub role-vending-machine
最佳实践
让正确的路易走,让错误的路难行 – 让做正确的事变得容易。如果开发人员在 RVM 预调配过程中遇到困难,可能会尝试通过其他方式创建角色,这会削弱 RVM 的核心价值。请确保您的安全团队就如何安全有效地使用 RVM 提供明确指导。
您还应该让开发人员难做错事。使用服务控制策略 (SCPs) 或权限边界来限制哪些角色可以创建其他角色。这种方法可帮助将角色创建权限仅限于 RVM 和其他可信来源。
提供良好范例 – 不可避免地,有些开发人员会将 RVM 存储库中的现有角色作为非正式模板,用于为其新角色授予权限。若能提供可供参考的最低权限示例,便能降低开发人员申请范围过广、包含大量通配符权限的风险。如果一开始就使用权限很高的角色和大量的通配符,随着时间的推移,这个问题会成倍增长。
使用命名约定和条件 – 即使开发人员不知道其应用程序将创建的所有资源名称,他们仍然应该通过使用命名约定来限制角色权限。例如,当他们创建 Amazon S3 存储桶时,其资源键的值可能设置为
arn:aws:s3:::myorg-myapp-dev-*,这样该角色的权限就仅限于匹配该名称的存储桶。通过 IAM 策略强制执行命名规范,还具有增强命名规范合规性的额外优势。之所以出现这种改进,是因为系统不允许创建不匹配的资源。需要拉取请求(PR)审查 – RVM 解决方案的价值在于,它创建了一个中心位置,可以在此审查新的管道角色。但是,仅当有护栏帮助确保将安全、高质量的代码提交到 RVM 时,这种设计才有用。保护用于部署代码的分支(例如
main),禁止直接推送操作,并要求所有针对这些分支的合并请求必须经过审批。配置只读角色 – 默认情况下,RVM 会为每个请求的角色预调配一个
readonly版本。此角色可以在不写入数据的 CI/CD 管道中使用,例如terraform plan管道工作流。如果只读工作流出现异常,这种方法有助于防止发生不必要的更改。默认情况下, AWS 托管
ReadOnlyAccess策略同时附加到只读角色和读写角色。在确定所需权限时,此策略减少了迭代需求,但对某些组织而言可能过于宽松。如果需要,可以从 Terraform 代码中移除该策略。授予最低权限 – 遵循最低权限原则,并授予执行任务所需的最低权限。有关详情,请参阅 IAM 文档中的授予最低权限和安全最佳实践。
操作说明
| Task | 说明 | 所需技能 |
|---|---|---|
将示例存储库复制到您的 GitHub 组织。 | 克隆
| DevOps 工程师 |
确定 R AWS 账户 VM 的。 | 确定 AWS 账户 要为 RVM 使用哪种基础架构部署。请勿使用管理账户或根账户。 | 云架构师 |
(可选)允许组织创建管道 PRs。 | 注意只有在要允许创建 要允许贵组织的管道创建 PRs,请使用以下步骤:
有关更多信息,请参阅 GitHub 文档中的管理存储库的 GitHub 操作设置 | DevOps 工程师 |
授予 RVM 账户的只读权限。 | 在您的管理账户中创建授予 RVM 账户只读权限的委托策略。这允许你的 RVM GitHub 工作流程在 使用以下代码并
| 云管理员 |
更新示例存储库中的默认值。 | 要将 RVM 配置为在您的特定环境中运行 AWS 区域,请执行以下操作:
| DevOps 工程师 |
| Task | 说明 | 所需技能 |
|---|---|---|
引导 RVM 存储库。 | 此步骤对于创建 RVM 管道本身使用的 OIDC 信任和 IAM 角色非常必要,这样才能开始运行并分配其他角色。 在您的 RVM 账户环境中,请从 | DevOps 工程师 |
| Task | 说明 | 所需技能 |
|---|---|---|
将 | 选择符合组织实践的部署方法,例如 AFT 或 StackSets。使用该方法将 这些 IAM 角色具有信任策略,允许 RVM 账户的角色承担角色(或其 | AWS 管理员 |
运行 | 要配置 RVM 以使其准备好创建管道角色,请执行以下操作:
工作流完成后,RVM 已准备好:
| DevOps 工程师 |
问题排查
| 问题 | 解决方案 |
|---|---|
我使用 RVM 创建了一个角色,但 GitHub 无法假设。 | 验证 GitHub 存储库的名称是否与提供给 同样,请验证 GitHub 管道中使用的分支是否与提供给 |
我的只读角色无法运行管道,因其缺乏读取特定资源的权限。 | 尽管该 可以使用 |
相关资源
附加信息
使用 GitHub 环境
GitHub 环境是替代基于分支的角色访问限制的另一种方法。如果您更喜欢使用 GitHub 环境,以下是 IAM 信任策略中附加条件的语法示例。此语法指定只有在Production环境中运行 GitHub 操作时才能使用该角色。
"StringLike": { "token.actions.githubusercontent.com:sub": "repo:octo-org/octo-repo:environment:Production" }
示例语法使用以下占位符值:
octo-org是 GitHub 组织名称。octo-repo是存储库名称。Production是特定的 GitHub 环境名称。