GCP Workload Identity Federation의 OpenID Connect 구성
Tier: Free, Premium, Ultimate
Offering: GitLab.com, Self-Managed, GitLab Dedicated
경고:
CI_JOB_JWT_V2
가 GitLab 15.9에서 더 이상 사용되지 않음
예정이며 GitLab 17.0에서 제거될 예정입니다. ID 토큰을 대신 사용하십시오.
이 튜토리얼은 JSON Web Token (JWT) 토큰과 Workload Identity Federation을 사용하여 GitLab CI/CD 작업에서 Google Cloud에 인증하는 방법을 보여줍니다.
이 구성은 비밀 정보를 저장할 필요 없이 요청 시 생성되는 단기 자격 증명을 생성합니다.
시작하려면 GitLab과 Google Cloud 간의 ID 페더레이션을 위해 OpenID Connect (OIDC)를 구성합니다.
GitLab에서 OIDC를 사용하는 자세한 정보는 클라우드 서비스에 연결을 참조하십시오.
이 튜토리얼은 Google Cloud 계정과 Google Cloud 프로젝트가 있다고 가정합니다.
Google Cloud 계정은 Google Cloud 프로젝트에서 적어도 Workload Identity Pool Admin 권한을 갖고 있어야 합니다.
참고:
이 튜토리얼을 따르려면 이 튜토리얼 대신 테라폼 모듈과 CI/CD 템플릿을 사용하고 싶다면 Google Cloud와 GitLab CI/CD 파이프라인의 인증을 간소화할 수 있는 OIDC 모듈 소개을 참조하십시오.
이 튜토리얼을 완료하려면:
Google Cloud Workload Identity Pool 생성
다음 옵션으로 새 Google Cloud Workload Identity Pool 생성:
-
이름: Workload Identity Pool의 사람 친화적인 이름(예:
GitLab
). -
풀 ID: Workload Identity Pool의 Google Cloud 프로젝트 내 고유 ID(예:
gitlab
). 이 값은 풀을 참조하거나 URL에 표시됩니다. - 설명: 선택 사항. 풀에 대한 설명.
-
풀 활성화: 이 옵션이
true
로 설정되어 있는지 확인합니다.
한 Google Cloud 프로젝트 당 GitLab 설치 당 단일 풀 생성을 권장합니다.
동일한 GitLab 인스턴스의 여러 GitLab 저장소 및 CI/CD 작업이 동일한 풀을 대상으로 다른 공급자를 사용하여 인증할 수 있습니다.
워크로드 신원 공급자 생성
이전 단계에서 생성한 Workload Identity Pool 내에 새 Google Cloud Workload Identity Provider 생성하고 다음 옵션을 사용합니다:
- 공급자 유형: OpenID Connect (OIDC).
-
공급자 이름: Workload Identity Provider의 사람 친화적인 이름(예:
gitlab/gitlab
). -
공급자 ID: 공급자의 풀에서 사용하는 고유 ID(예:
gitlab-gitlab
). 이 값은 공급자를 참조하거나 URL에 표시됩니다. -
발행자 (URL): GitLab 인스턴스의 주소(예:
https://gitlab.com/
또는https://gitlab.example.com/
).- 주소는
https://
프로토콜을 사용해야 합니다. - 주소는 trailing slash로 끝나야 합니다.
- 주소는
-
수강청취자(Audiences): 허용된 수강청취자 목록을 수동으로 GitLab 인스턴스의 주소(예:
https://gitlab.com
또는https://gitlab.example.com
)로 설정합니다.- 주소는
https://
프로토콜을 사용해야 합니다. - 주소는 trailing slash로 끝나서는 안 됩니다.
- 주소는
-
공급자 속성 매핑: 다음 매핑을 만듭니다. 여기서
attribute.X
는 Google의 클레임에 존재해야 하는 속성의 이름이고assertion.X
는 GitLab 클레임에서 추출할 값입니다:Google의 속성 GitLab의 Assertion google.subject
assertion.sub
attribute.X
assertion.X
또한 Common Expression Language (CEL)을 사용하여 복잡한 속성을 작성할 수 있습니다.
허가 부여하는 데 사용하려는 모든 속성을 매핑해야 합니다. 예를 들어, 다음 단계에서 사용 권한을 매핑하려면 사용자 이메일 주소를 기반으로 권한을 매핑하고 싶다면
attribute.user_email
을assertion.user_email
로 매핑해야 합니다.
서비스 계정 표현에 대한 권한 부여
Workload Identity Pool 및 Workload Identity Provider 생성은 Google Cloud에서의 인증을 정의합니다.
이 시점에서 GitLab CI/CD 작업에서 Google Cloud로 인증할 수 있습니다.
그러나 Google Cloud의 권한(authorization)을 갖지는 못합니다.
GitLab CI/CD 작업에 Google Cloud에서의 권한을 부여하려면 다음을 수행해야 합니다:
- Google Cloud 서비스 계정 생성. 원하는 이름과 ID를 사용할 수 있습니다.
- Google Cloud 리소스에 대한 IAM 권한 부여.
이러한 권한은 사용 사례에 따라 크게 다를 수 있습니다. 일반적으로 이 서비스 계정에는 GitLab CI/CD 작업에서 사용하려는 Google Cloud 프로젝트 및 리소스에 대한 권한을 부여합니다. 예를 들어 GitLab CI/CD 작업에서 Google Cloud Storage 버킷에 파일을 업로드해야 하는 경우 Cloud Storage 버킷에
roles/storage.objectCreator
권한을 부여합니다. - 외부 신원에 권한 부여하여 해당 서비스 계정을 의도한 작업을 대신할 수 있도록 합니다. 이 단계에서는 GitLab CI/CD 작업이 서비스 계정의 신원을 나타내도록 허용하는 IAM 권한을 서비스 계정 자체에 부여합니다.
이 단계 또한 원하는 구성에 크게 의존합니다.
예를 들어, GitLab CI/CD 작업이 chris
라는 사용자가 시작한 경우 my-service-account
라는 서비스 계정을 표현하는 데 사용자 chris
에게 roles/iam.workloadIdentityUser
IAM 역할을 부여한다면 외부 신원은 다음과 같은 형식을 가집니다:
principalSet://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/attribute.user_login/chris
여기서 PROJECT_NUMBER
는 Google Cloud 프로젝트 번호이고 POOL_ID
는 첫 번째 섹션에서 생성한 Workload Identity Pool의 ID입니다.
이 구성은 이전 섹션에서 클레임에서 매핑된 user_login
을 추가했다고 가정합니다.
임시 자격 증명 얻기
OIDC 및 역할을 구성한 후 GitLab CI/CD 작업은 Google Cloud 보안 토큰 서비스 (STS)에서 임시 자격 증명을 가져올 수 있습니다.
CI/CD 작업에 id_tokens
를 추가하세요:
job:
id_tokens:
GITLAB_OIDC_TOKEN:
aud: https://gitlab.example.com
ID 토큰을 사용하여 임시 자격 증명을 가져옵니다:
PAYLOAD="$(cat <<EOF
{
"audience": "//iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/providers/PROVIDER_ID",
"grantType": "urn:ietf:params:oauth:grant-type:token-exchange",
"requestedTokenType": "urn:ietf:params:oauth:token-type:access_token",
"scope": "https://www.googleapis.com/auth/cloud-platform",
"subjectTokenType": "urn:ietf:params:oauth:token-type:jwt",
"subjectToken": "${GITLAB_OIDC_TOKEN}"
}
EOF
)"
FEDERATED_TOKEN="$(curl --fail "https://sts.googleapis.com/v1/token" \
--header "Accept: application/json" \
--header "Content-Type: application/json" \
--data "${PAYLOAD}" \
| jq -r '.access_token'
)"
여기서:
-
PROJECT_NUMBER
는 Google Cloud 프로젝트 번호입니다 (이름이 아닙니다). -
POOL_ID
는 첫 번째 섹션에서 만든 Workload Identity Pool의 ID입니다. -
PROVIDER_ID
는 두 번째 섹션에서 만든 Workload Identity Provider의 ID입니다. -
GITLAB_OIDC_TOKEN
은 OIDC ID 토큰입니다.
그런 다음 이 결과를 사용하여 이전 섹션에서 생성된 서비스 계정을 흉내 낼 수 있습니다:
ACCESS_TOKEN="$(curl --fail "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/SERVICE_ACCOUNT_EMAIL:generateAccessToken" \
--header "Accept: application/json" \
--header "Content-Type: application/json" \
--header "Authorization: Bearer FEDERATED_TOKEN" \
--data '{"scope": ["https://www.googleapis.com/auth/cloud-platform"]}' \
| jq -r '.accessToken'
)"
여기서:
-
SERVICE_ACCOUNT_EMAIL
은 이전 섹션에서 생성된 서비스 계정의 전체 이메일 주소입니다. -
FEDERATED_TOKEN
은 이전 단계에서 검색된 연합 토큰입니다.
결과적으로 Google Cloud OAuth 2.0 액세스 토큰이 생성되며, 이를 사용하여 대부분의 Google Cloud API 및 서비스에 대해 bearer 토큰으로 인증할 수 있습니다. 또한 이 값을 환경 변수 CLOUDSDK_AUTH_ACCESS_TOKEN
으로 설정하여 gcloud
CLI에 전달할 수 있습니다.
작동 예시
Terraform 및 일시적 자격 증명을 검색하는 샘플 스크립트를 사용하여 GCP에서 OIDC를 프로비저닝하는 참조 프로젝트를 확인하세요.
문제 해결
-
curl
응답을 디버깅할 때, 최신 버전의 curl을 설치하세요.-f
대신--fail-with-body
를 사용하세요. 이 명령은 유용한 오류 메시지를 포함할 수 있는 전체 본문을 출력합니다. -
Workload Identity Federation의 문제 해결에 대한 Google Cloud 문서를 확인하세요.