Google Cloud Workload Identity Federation 和 IAM 策略
- 层级:免费版、高级版、旗舰版
- 提供:GitLab.com
要使用 Google Cloud 集成,如 Google Artifact Management 集成, 你必须创建并配置一个 工作负载身份池和提供者。 Google Cloud 集成使用 Workload Identity Federation, 通过使用 JSON Web Token (JWT) 令牌,通过 OpenID Connect (OIDC) 授予 GitLab 工作负载访问 Google Cloud 资源的权限。
Workload Identity Federation
Workload Identity Federation 让你能够使用 Identity and Access Management (IAM) 来授予 外部身份 IAM 角色。
传统上,在 Google Cloud 外部运行的应用程序使用 服务账号密钥 来访问 Google Cloud 资源。然而,服务账号密钥是强大的 凭证,如果管理不当,可能会带来安全风险。
通过身份联合,你可以使用 Identity and Access Management (IAM) 直接 授予外部身份 IAM 角色, 而无需服务账号。这种方法 消除了与服务账号及其密钥相关的维护和安全负担。
工作负载身份池
工作负载身份池 是一个实体,让你能够管理 Google Cloud 上的非 Google 身份。
Google Cloud 上的 GitLab 集成将引导你设置一个工作负载 身份池来向 Google Cloud 进行身份验证。此设置包括 将你的 GitLab 角色属性映射到 Google Cloud IAM 策略中的声明。有关 GitLab 在 Google Cloud 集成中可用属性的完整列表,请参阅 OIDC 自定义声明。
工作负载身份池提供者
工作负载身份池提供者 是一个实体,描述了 Google Cloud 与你的身份提供者 (IdP) 之间的关系。对于 Google Cloud 上的 GitLab 集成,GitLab 是 你的工作负载身份池的身份提供者。
有关外部工作负载的身份联合的更多信息,请参阅 Workload Identity Federation。
默认的 Google Cloud 上的 GitLab 集成假设你想要在 GitLab 组织级别设置从 GitLab 到 Google Cloud 的身份验证。如果你想要 按项目控制对 Google Cloud 的访问,那么你必须为你的 工作负载身份池提供者配置 IAM 策略。有关 控制谁可以从你的 GitLab 组织访问 Google Cloud 的更多信息,请参阅 使用 IAM 进行访问控制。
使用 Workload Identity Federation 进行 GitLab 身份验证
在设置好你的工作负载身份池和提供者,将你的 GitLab
角色和权限映射到 IAM 角色后,你可以通过设置
identity 关键字为
google_cloud 来配置 runners,
以便从 GitLab 部署工作负载到 Google Cloud,从而获得
对 Google Cloud 的授权。
有关使用 Google Cloud 上的 GitLab 集成配置 runners 的更多信息,请参阅教程 在 Google Cloud 中配置 runners。
创建和配置 Workload Identity Federation
要设置 Workload Identity Federation,你可以选择:
- 使用 GitLab UI 进行引导式设置。
- 使用 Google Cloud CLI 手动设置 Workload Identity Federation。
使用 GitLab UI
要使用 GitLab UI 设置 Workload Identity Federation:
- 在左侧边栏,选择 搜索或跳转至 并找到你的项目。
- 选择 设置 > 集成。
- 找到 Google Cloud IAM 集成并选择 配置。
- 选择 引导式设置 并按照说明操作。
由于已知问题,在引导式设置中运行脚本后,Google Cloud IAM 集成页面中的字段可能不会 填充。如果字段为空,请刷新页面。 有关更多信息,请参阅 issue 448831。
使用 Google Cloud CLI
先决条件:
-
使用以下命令创建工作负载身份池。替换这些 值:
<your_google_cloud_project_id>替换为你的 Google Cloud 项目 ID。 为提高安全性,请使用专门用于身份管理的项目, 与资源和 CI/CD 项目分开。<your_identity_pool_id>替换为要用于池的 ID,该 ID 必须为 4 到 32 个小写字母、数字或连字符。为避免冲突, 请使用唯一 ID。你应该包含 GitLab 项目 ID 或项目路径, 因为这有助于 IAM 策略管理。例如,gitlab-my-project-name。
gcloud iam workload-identity-pools create <your_identity_pool_id> \ --project="<your_google_cloud_project_id>" \ --location="global" \ --display-name="Workload identity pool for GitLab project ID" -
使用以下命令向工作负载身份池添加一个 OIDC 提供者。替换这些 值:
<your_identity_provider_id>替换为要用于提供者的 ID,该 ID 必须为 4 到 32 个小写字母、数字或连字符。为避免 冲突,请在身份池中使用唯一 ID。例如,gitlab。<your_google_cloud_project_id>替换为你的 Google Cloud 项目 ID。<your_identity_pool_id>替换为你 在上一步中创建的工作负载身份池的 ID。<your_issuer_uri>替换为你的身份提供者发行者 URI,该 URI 可以 在选择手动设置时从 IAM 集成页面复制,并且必须完全匹配该值。该参数必须包含 顶级组的路径。例如,如果项目位于my-root-group/my-subgroup/project-a下,则issuer-uri必须设置为https://auth.gcp.gitlab.com/oidc/my-root-group。
gcloud iam workload-identity-pools providers create-oidc "<your_identity_provider_id>" \ --location="global" \ --project="<your_google_cloud_project_id>" \ --workload-identity-pool="<your_identity_pool_id>" \ --issuer-uri="<your_issuer_uri>" \ --display-name="GitLab OIDC provider" \ --attribute-mapping="attribute.guest_access=assertion.guest_access,\ attribute.reporter_access=assertion.reporter_access,\ attribute.developer_access=assertion.developer_access,\ attribute.maintainer_access=assertion.maintainer_access,\ attribute.owner_access=assertion.owner_access,\ attribute.namespace_id=assertion.namespace_id,\ attribute.namespace_path=assertion.namespace_path,\ attribute.project_id=assertion.project_id,\ attribute.project_path=assertion.project_path,\ attribute.user_id=assertion.user_id,\ attribute.user_login=assertion.user_login,\ attribute.user_email=assertion.user_email,\ attribute.user_access_level=assertion.user_access_level,\ google.subject=assertion.sub"
attribute-mapping参数必须包含包含在 JWT ID 令牌中的 OIDC 自定义声明 到用于在 Identity and Access Management (IAM) 策略中授予访问权限的相应身份属性的映射。 有关更多信息,请参阅你可以用来 控制对 Google Cloud 的访问 的 支持的 OIDC 自定义声明。
要限制对特定 GitLab 项目或组的身份令牌访问,请使用属性条件。对项目使用属性 assertion.project_id,对组使用属性 assertion.namespace_id。
有关更多信息,请参阅 Google Cloud 文档中关于如何
定义属性条件 的内容。定义属性条件后,你可以
更新工作负载身份提供者。
创建工作负载身份池和提供者后,要在 GitLab 中完成设置:
- 在左侧边栏,选择 搜索或跳转至 并找到你的项目。
- 选择 设置 > 集成。
- 找到 Google Cloud IAM 集成并选择 配置。
- 选择 手动设置
- 完成字段。
OIDC 自定义声明
ID 令牌包含以下自定义声明:
| 声明名称 | 时间 | 描述 |
|---|---|---|
namespace_id |
在项目事件上 | 组或用户级命名空间的 ID。 |
namespace_path |
在项目事件上 | 组或用户级命名空间的路径。 |
project_id |
在项目事件上 | 项目的 ID。 |
project_path |
在项目事件上 | 项目的路径。 |
root_namespace_id |
在组事件上 | 顶级组或用户级命名空间的 ID。 |
root_namespace_path |
在组事件上 | 顶级组或用户级命名空间的路径。 |
user_id |
在用户触发的事件上 | 用户的 ID。 |
user_login |
在用户触发的事件上 | 用户的用户名。 |
user_email |
在用户触发的事件上 | 用户的电子邮件。 |
ci_config_ref_uri |
在 CI/CD 管道运行期间 | 顶级 CI 管道定义的 ref 路径。 |
ci_config_sha |
在 CI/CD 管道运行期间 | ci_config_ref_uri 的 Git 提交 SHA。 |
job_id |
在 CI/CD 管道运行期间 | CI 作业的 ID。 |
pipeline_id |
在 CI/CD 管道运行期间 | CI 管道的 ID。 |
pipeline_source |
在 CI/CD 管道运行期间 | CI 管道源。 |
project_visibility |
在 CI/CD 管道运行期间 | 运行管道的项目的可见性。 |
ref |
在 CI/CD 管道运行期间 | CI 作业的 Git ref。 |
ref_path |
在 CI/CD 管道运行期间 | CI 作业的完全限定 ref。 |
ref_protected |
在 CI/CD 管道运行期间 | Git ref 是否受保护。 |
ref_type |
在 CI/CD 管道运行期间 | Git ref 类型。 |
runner_environment |
在 CI/CD 管道运行期间 | CI 作业使用的 runner 类型。 |
runner_id |
在 CI/CD 管道运行期间 | 执行 CI 作业的 runner 的 ID。 |
sha |
在 CI/CD 管道运行期间 | CI 作业的提交 SHA。 |
environment |
在 CI/CD 管道运行期间 | CI 作业部署到的环境。 |
environment_protected |
在 CI/CD 管道运行期间 | 部署的环境是否受保护。 |
environment_action |
在 CI/CD 管道运行期间 | CI 作业中指定的环境操作。 |
deployment_tier |
在 CI/CD 管道运行期间 | CI 作业指定的环境的部署层级。 |
user_access_level |
在用户触发的事件上 | 用户的角色,值为 guest、reporter、developer、maintainer、owner。 |
guest_access |
在用户触发的事件上 | 表示用户是否至少具有 guest 角色,值为字符串 “true” 或 “false”。 |
reporter_access |
在用户触发的事件上 | 表示用户是否至少具有 reporter 角色,值为字符串 “true” 或 “false”。 |
developer_access |
在用户触发的事件上 | 表示用户是否至少具有 developer 角色,值为字符串 “true” 或 “false”。 |
maintainer_access |
在用户触发的事件上 | 表示用户是否至少具有 maintainer 角色,值为字符串 “true” 或 “false”。 |
owner_access |
在用户触发的事件上 | 表示用户是否至少具有 owner 角色,值为字符串 “true” 或 “false”。 |
这些声明是 ID 令牌声明 的超集。所有值都是字符串类型。有关更多 详细信息和使用示例,请参阅 ID 令牌声明文档。
控制对 Google Cloud 的访问
当你设置 Workload Identity Federation时,
许多标准的 GitLab 声明(例如,user_access_level)会自动映射到
Google Cloud 属性。
你可以进一步自定义谁可以从你的 GitLab 组织访问 Google Cloud。 为此,你使用 Common Expression Language (CEL) 基于 GitLab 在 Google Cloud 集成的 OIDC 自定义属性 设置主体。
例如,允许 GitLab 中具有 maintainer 角色的用户
将工件推送到 GitLab 项目 gitlab-org/my-project 的 Google Artifact Registry:
-
登录 Google Cloud Console 并转到 Workload Identity Federation 页面。
-
在 显示名称 列中,选择你的工作负载身份池。
-
在 提供者 部分,在你想要编辑的工作负载身份提供者旁边, 选择 编辑 ( ) 以打开 提供者详情。
-
在 属性映射 部分,选择 添加映射。
-
在 Google N 文本框中,输入:
attribute.my_project_maintainer -
在 OIDC N 文本框中,输入以下 CEL 表达式:
assertion.maintainer_access=="true" && assertion.project_path=="gitlab-org/my-project" -
选择 保存。
Google 属性
my_project_maintainer被映射到 GitLab 声明maintainer_access==true和project_path=="gitlab-org/my-project"。 -
在 Google Cloud Console 中,转到 IAM 页面。
-
选择 授予访问权限。
-
在 新主体 文本框中,输入包含
attribute.my_project_maintainer/true的主体集,格式如下:principalSet://iam.googleapis.com/projects/<PROJECT_NUMBER>/locations/global/workloadIdentityPools/<POOL_ID>/attribute.my_project_maintainer/true替换以下内容:
<PROJECT_NUMBER>替换为你的 Google Cloud 项目编号。要查找 你的项目编号,请参阅 识别项目。<POOL_ID>替换为你的工作负载身份池 ID。
-
在 选择角色 下拉列表中,选择 Google Artifact Registry Writer 角色 (
roles/artifactregistry.writer)。 -
选择 保存。
该角色被授予包含在 GitLab 项目 gitlab-org/my-project 中具有 maintainer
角色的用户的主体集。
为了防止你的其他 GitLab 项目将工件推送到 Google Artifact Registry,你 可以在 Google Cloud Console 中查看你的 IAM 策略,并根据需要 删除或编辑角色。
查看 IAM 策略
登录 Google Cloud Console 并转到 IAM 页面
你可以选择 按主体查看 或 按角色查看。