在 AWS 中配置 OpenID Connect 以获取临时凭证
- Tier: Free, Premium, Ultimate
- Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated
CI_JOB_JWT_V2 在 GitLab 15.9 中已被弃用
并计划在 GitLab 17.0 中移除。请改用 ID tokens。
在本教程中,我们将向您展示如何使用带有 JSON Web Token (JWT) 的 GitLab CI/CD 作业从 AWS 获取临时凭证,而无需存储密钥。 为此,您必须在 GitLab 和 AWS 之间配置 OpenID Connect (OIDC) 进行身份联合。有关使用 OIDC 集成 GitLab 的背景和要求,请参阅 连接到云服务。
完成本教程需要:
添加身份提供者
按照这些 说明 在 AWS 中创建 GitLab 作为 IAM OIDC 提供者。
包含以下信息:
- 提供者 URL:您的 GitLab 实例地址,例如
https://gitlab.com或http://gitlab.example.com。 此地址必须可公开访问。如果不可公开访问,请参阅如何 配置非公开的 GitLab 实例 - 受众:您的 GitLab 实例地址,例如
https://gitlab.com或http://gitlab.example.com。- 地址必须包含
https://。 - 不要包含尾部斜杠。
- 地址必须包含
配置角色和信任关系
创建身份提供者后,配置一个带有条件的 Web 身份角色,以限制对 GitLab 资源的访问。临时凭证是使用 AWS Security Token Service 获取的,因此将 Action 设置为 sts:AssumeRoleWithWebIdentity。
您可以创建一个 自定义信任策略 来限制对特定组、项目、分支或标签的授权。 有关支持的过滤类型的完整列表,请参阅 连接到云服务。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::AWS_ACCOUNT:oidc-provider/gitlab.example.com"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"gitlab.example.com:sub": "project_path:mygroup/myproject:ref_type:branch:ref:main"
}
}
}
]
}创建角色后,将定义权限的策略附加到 AWS 服务(S3、EC2、Secrets Manager)。
获取临时凭证
配置 OIDC 和角色后,GitLab CI/CD 作业可以从 AWS Security Token Service (STS) 获取临时凭证。
assume role:
id_tokens:
GITLAB_OIDC_TOKEN:
aud: https://gitlab.example.com
script:
# this is split out for correct exit code handling
- >
aws_sts_output=$(aws sts assume-role-with-web-identity
--role-arn ${ROLE_ARN}
--role-session-name "GitLabRunner-${CI_PROJECT_ID}-${CI_PIPELINE_ID}"
--web-identity-token ${GITLAB_OIDC_TOKEN}
--duration-seconds 3600
--query 'Credentials.[AccessKeyId,SecretAccessKey,SessionToken]'
--output text)
- export $(printf "AWS_ACCESS_KEY_ID=%s AWS_SECRET_ACCESS_KEY=%s AWS_SESSION_TOKEN=%s" $aws_sts_output)
- aws sts get-caller-identity工作示例
- 请参阅此 参考项目,了解如何使用 Terraform 在 AWS 中配置 OIDC 以及获取临时凭证的示例脚本。
- GitLab 与 ECS 的 OIDC 和多账户部署。
- AWS 合作伙伴 (APN) 博客:使用 GitLab CI/CD 设置 OpenID Connect。
- GitLab 在 AWS re:Inforce 2023:使用 OpenID 和 JWT 安全地将 GitLab CD 管道连接到 AWS。
配置非公开的 GitLab 实例
- Tier: Free, Premium, Ultimate
- Offering: GitLab Self-Managed
此解决方法是一个高级配置选项,需要理解安全注意事项。 您必须小心地将 OpenID 配置和来自您的私有 GitLab Self-Managed 实例的公钥同步到公开可用的位置,例如 S3 存储桶。 您还必须确保 S3 存储桶和其中的文件得到适当保护。 未能正确保护 S3 存储桶可能导致与此 OpenID Connect 身份关联的任何云账户被接管。
如果您的 GitLab 实例不可公开访问,默认情况下无法在 AWS 中配置 OpenID Connect。您可以使用解决方法使某些特定配置公开可用,从而为实例启用 OpenID Connect 配置:
-
将您的 GitLab 实例的身份验证详细信息存储在公开可用的位置, 例如在 S3 文件中:
- 在 S3 文件中托管您实例的 OpenID 配置。配置可在
/.well-known/openid-configuration获取,如http://gitlab.example.com/.well-known/openid-configuration。 更新配置文件中的issuer:和jwks_uri:值,使其指向公开可用的位置。 - 在 S3 文件中托管您实例 URL 的公钥。密钥可在
/oauth/discovery/keys获取, 如http://gitlab.example.com/oauth/discovery/keys。
例如:
- OpenID 配置文件:
https://example-oidc-configuration-s3-bucket.s3.eu-north-1.amazonaws.com/.well-known/openid-configuration。 - JWKS (JSON Web Key Sets):
https://example-oidc-configuration-s3-bucket.s3.eu-north-1.amazonaws.com/oauth/discovery/keys。 - ID Token 中的发行者声明
iss:和 OpenID 配置中的issuer:值将是:https://example-oidc-configuration-s3-bucket.s3.eu-north-1.amazonaws.com
- 在 S3 文件中托管您实例的 OpenID 配置。配置可在
-
可选。使用 OpenID 配置验证器(如 OpenID Configuration Endpoint Validator) 验证您公开可用的 OpenID 配置。
-
为您的 ID token 配置自定义发行者声明。默认情况下,GitLab ID token 的发行者声明
iss:设置为您的 GitLab 实例地址,例如:http://gitlab.example.com。 -
更新发行者 URL:
-
编辑
/etc/gitlab/gitlab.rb:gitlab_rails['ci_id_tokens_issuer_url'] = 'public_url_with_openid_configuration_and_keys' -
保存文件并 重新配置 GitLab 以使更改生效。
-
导出 Helm 值:
helm get values gitlab > gitlab_values.yaml -
编辑
gitlab_values.yaml:global: appConfig: ciIdTokens: issuerUrl: 'public_url_with_openid_configuration_and_keys' -
保存文件并应用新值:
helm upgrade -f gitlab_values.yaml gitlab gitlab/gitlab
-
编辑
docker-compose.yml:version: "3.6" services: gitlab: environment: GITLAB_OMNIBUS_CONFIG: | gitlab_rails['ci_id_tokens_issuer_url'] = 'public_url_with_openid_configuration_and_keys' -
保存文件并重启 GitLab:
docker compose up -d
-
编辑
/home/git/gitlab/config/gitlab.yml:production: &base ci_id_tokens: issuer_url: 'public_url_with_openid_configuration_and_keys' -
保存文件并 重新配置 GitLab 以使更改生效。
-
-
运行
ci:validate_id_token_configurationRake 任务 以验证 CI/CD ID token 配置。
故障排除
错误:Not authorized to perform sts:AssumeRoleWithWebIdentity
如果您看到此错误:
An error occurred (AccessDenied) when calling the AssumeRoleWithWebIdentity operation:
Not authorized to perform sts:AssumeRoleWithWebIdentity可能的原因有多个:
- 云管理员尚未将项目配置为使用 GitLab 的 OIDC。
- 角色被限制在分支或标签上运行。请参阅 配置条件角色。
- 使用通配符条件时使用了
StringEquals而不是StringLike。请参阅 相关问题。
Could not connect to openid configuration of provider 错误
在 AWS IAM 中添加身份提供者后,您可能会收到以下错误:
Your request has a problem. Please see the following details.
- Could not connect to openid configuration of provider: `https://gitlab.example.com`当 OIDC 身份提供者的发行者呈现的证书链顺序错误,或包含重复或额外的证书时,会发生此错误。
验证您的 GitLab 实例的证书链。链必须从域名或发行者 URL 开始,然后是中间证书,最后是根证书。使用以下命令检查证书链,将 gitlab.example.com 替换为您的 GitLab 主机名:
echo | /opt/gitlab/embedded/bin/openssl s_client -connect gitlab.example.com:443Couldn't retrieve verification key from your identity provider 错误
您可能会收到类似以下的错误:
An error occurred (InvalidIdentityToken) when calling the AssumeRoleWithWebIdentity operation: Couldn't retrieve verification key from your identity provider, please reference AssumeRoleWithWebIdentity documentation for requirements
此错误可能是因为:
- 身份提供者 (IdP) 的
.well_knownURL 和jwks_uri无法从公共互联网访问。 - 自定义防火墙阻止了请求。
- 从 IdP 到 AWS STS 端点的 API 请求延迟超过 5 秒。
- STS 对您的
.well_knownURL 或 IdP 的jwks_uri发送了太多请求。
如 此错误的 AWS 知识中心文章 中所述,
您的 GitLab 实例需要可公开访问,以便 .well_known URL 和 jwks_uri 可以被解析。
如果这不可能,例如您的 GitLab 实例处于离线环境,
请参阅如何 配置非公开的 GitLab 实例