AWSでOpenID Connectを設定して一時的な認証情報を取得する
- プラン: Free、Premium、Ultimate
- 提供形態: GitLab.com、GitLab Self-Managed、GitLab Dedicated
CI_JOB_JWT_V2はGitLab 15.9で非推奨となり、GitLab 17.0で削除される予定です。代わりにIDトークンを使用してください。
このチュートリアルでは、JSON Webトークン(JWT)を使用してGitLab CI/CDジョブからAWSの一時的な認証情報を取得する方法について説明します。 シークレットを保存する必要はありません。そのためには、GitLabとAWS間のID連携用にOpenID Connect(OIDC)を設定する必要があります。OIDCを使用したGitLabの統合の背景と要件については、クラウドサービスに接続するを参照してください。
このチュートリアルを完了するには、以下を行います:
Identity Providerを追加する
これらの手順に従って、AWSでGitLabをIAM OIDCプロバイダーとして作成します。
次の情報を含めます:
プロバイダーURL(プロバイダーのURL):
https://gitlab.comやhttp://gitlab.example.comなど、GitLabインスタンスのアドレス。このアドレスは、パブリックアクセスが可能である必要があります。パブリックアクセスできない場合は、非公開のGitLabインスタンスを設定する方法をご確認ください。オーディエンス: リクエストされたセキュリティートークンで使用するターゲットサービスの論理名。
- AWS OIDCインテグレーションでは、これは通常、IAM OIDCアイデンティティプロバイダーで設定されたオーディエンス値(多くの場合、
sts.amazonaws.comまたはGitLabインスタンスURL)と一致します。 - この値は、トークンが特定のアイデンティティプロバイダーを対象としていることを確認するために、AWSによって検証されます。
https://gitlab.comまたはGitLabインスタンスURLを使用すると、AWSアイデンティティプロバイダーの参照が一致する場合に機能する可能性がありますが、これは意味的に誤解を招く可能性があります。オーディエンスは、トークンを検証して受け入れるサービスを表す必要があります。- AWS OIDCインテグレーションでは、これは通常、IAM OIDCアイデンティティプロバイダーで設定されたオーディエンス値(多くの場合、
ロールと信頼を設定する
Identity Providerを作成したら、GitLabリソースへのアクセスを制限するための条件を使用して、Web IDロールを設定します。一時的な認証情報はAWS Security Token Service(STS)を使用して取得されるため、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)ブログ: Setting up OpenID Connect with GitLab CI/CD(GitLab CI/CDでOpenID Connectを設定する)。
- GitLab at AWS re:Inforce 2023: Secure GitLab CD pipelines to AWS w/ OpenID and JWT(GitLab at AWS re:Inforce 2023: OpenID連携、OIDC、JWTを使用したAWSへの安全なGitLab CDパイプライン)
非公開のGitLabインスタンスを設定する
- プラン: Free、Premium、Ultimate
- 提供形態: GitLab Self-Managed
この回避策は高度な設定オプションであり、セキュリティ上の考慮事項を理解する必要があります。プライベートなGitLab Self-Managedインスタンスから公開されている場所(S3バケットなど)に、OpenID設定と公開キーを正しく同期するように注意する必要があります。S3バケットとその中のファイルが適切に保護されていることを確認することも必要です。S3バケットを適切に保護できない場合、このOpenID Connect IDに関連付けられているクラウドアカウントが乗っ取られる可能性があります。
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トークンの発行者クレーム
iss:とOpenID設定のissuer:値:https://example-oidc-configuration-s3-bucket.s3.eu-north-1.amazonaws.com
- S3ファイルでインスタンスのOpenID設定をホスティングします。この設定は
オプション。OpenID Configuration Endpoint ValidatorなどのOpenID設定バリデーターを使用して、公開されているOpenID設定を検証します。
IDトークンのカスタム発行者クレームを設定します。デフォルトでは、GitLab IDトークンの発行者クレーム
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.yamlgitlab_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トークンの設定を検証します。
トラブルシューティング
エラー: Not authorized to perform sts:AssumeRoleWithWebIdentity
このエラーが表示された場合:
An error occurred (AccessDenied) when calling the AssumeRoleWithWebIdentity operation:
Not authorized to perform sts:AssumeRoleWithWebIdentityこのエラーは、次のような複数の理由で発生する可能性があります:
- クラウド管理者が、GitLabでOIDCを使用するようにプロジェクトを設定していない。
- ロールが、ブランチまたはタグでの実行を制限されている。条件付きロールを設定するを参照してください。
- ワイルドカード条件を使用する際に、
StringLikeの代わりにStringEqualsが使用されている。関連イシューを参照してください。
エラー: Could not connect to openid configuration of provider
AWS IAMにIdentity Providerを追加した後、次のエラーが表示されることがあります:
Your request has a problem. Please see the following details.
- Could not connect to openid configuration of provider: `https://gitlab.example.com`このエラーは、OIDC Identity Providerの発行者が順序の間違った証明書チェーンを提示するか、重複や追加の証明書が含まれている場合に発生します。
GitLabインスタンスの証明書チェーンを検証します。チェーンは、ドメインまたは発行者のURLで始まり、中間証明書が続き、最後にルート証明書で終わる必要があります。このコマンドを使用して証明書チェーンを確認し、gitlab.example.comをGitLabホスト名に置き換えます:
echo | /opt/gitlab/embedded/bin/openssl s_client -connect gitlab.example.com:443エラー: Couldn'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
このエラーについては次のような原因が考えられます:
- パブリックインターネットからIdentity Provider(IdP)の
.well_knownURLとjwks_uriにアクセスできない。 - カスタムファイアウォールがリクエストをブロックしている。
- IdPからAWS STSエンドポイントに到達するAPIリクエストで、5秒を超えるレイテンシーが発生している。
- STSが、IdPの
.well_knownURLまたはjwks_uriに過剰なリクエストを送信している。
このエラーに関するAWSナレッジセンターのドキュメントに記載されているように、GitLabインスタンスをパブリックアクセス可能にして、.well_known URLとjwks_uriを解決できるようにする必要があります。パブリックアクセスできない場合(GitLabインスタンスがオフライン環境にある場合など)は、非公開のGitLabインスタンスを設定する方法をご確認ください。