GCP 워크로드 ID 페더레이션을 OpenID Connect로 구성하려면
이 자습서에서는 JSON 웹 토큰(JWT) 및 워크로드 ID 페더레이션을 사용하여 GitLab CI/CD 작업에서 Google Cloud에 인증하는 방법을 보여줍니다. 이 구성은 어떤 비밀을 저장할 필요 없이 요청 시 생성되는 유효 기간이 짧은 자격증명을 생성합니다.
시작하려면 GitLab과 Google Cloud 간의 ID 페더레이션을 위해 OpenID Connect (OIDC)를 구성하세요. GitLab에서 OIDC를 사용하는 자세한 내용은 클라우드 서비스에 연결을 참조하세요.
이 자습서는 Google Cloud 계정 및 Google Cloud 프로젝트가 있는 것으로 가정합니다. 계정은 Google Cloud 프로젝트에서 적어도 워크로드 ID 풀 관리자 권한이 있어야 합니다.
이 자습서를 완료하려면:
Google Cloud 워크로드 ID 풀 생성
다음 옵션을 사용하여 Google Cloud 워크로드 ID 풀을 생성하세요:
-
이름:
GitLab
과 같이 워크로드 ID 풀의 사람 친화적인 이름 -
풀 ID:
gitlab
과 같이 Google Cloud 프로젝트의 워크로드 ID 풀을 위한 고유 ID. 이 값은 풀을 참조하는 데 사용되며 URL에 표시됩니다. - 설명: 선택 사항. 풀의 설명.
-
풀 사용 설정: 이 옵션을
true
로 설정하세요.
하나의 GitLab 설치 당 하나의 Google Cloud 프로젝트에 단일 _풀_을 생성하는 것이 좋습니다. 동일한 GitLab 인스턴스에서 여러 GitLab 리포지터리 및 CI/CD 작업이 있는 경우, 다른 _프로바이더_가 같은 _풀_을 대상으로 사용하여 인증할 수 있습니다.
워크로드 ID 프로바이더 생성
이전 단계에서 생성된 워크로드 ID 풀 내에 새로운 Google Cloud 워크로드 ID 프로바이더를 생성하고 다음 옵션을 사용하세요:
- 프로바이더 유형: OpenID Connect (OIDC).
-
프로바이더 이름:
gitlab/gitlab
과 같이 워크로드 ID 프로바이더의 사람 친화적인 이름 - 프로바이더 ID: 풀 내에서 워크로드 ID 프로바이더를 참조하는 데 사용되는 고유 ID. URL에 표시됩니다.
-
발급자 (URL):
https://gitlab.com/
또는https://gitlab.example.com/
과 같이 GitLab 인스턴스의 주소- 주소는
https://
프로토콜을 사용해야 합니다. - 주소는 끝에 슬래시가 있어야 합니다.
- 주소는
-
수강자: 허용된 수강자 디렉터리을 매뉴얼으로 GitLab 인스턴스의 주소(
https://gitlab.com
또는https://gitlab.example.com
등)로 설정합니다.- 주소는
https://
프로토콜을 사용해야 합니다. - 주소는 끝에 슬래시가 있어서는 안 됩니다.
- 주소는
-
프로바이더 속성 매핑: 다음 매핑을 생성합니다.
attribute.X
는 Google의 클레임에 표시되길 원하는 속성의 이름이며,assertion.X
는 GitLab 클레임에서 추출할 값을 나타냅니다.Google의 속성 GitLab에서의 클레임 google.subject
assertion.sub
attribute.X
assertion.X
공통 표현 언어(CEL)를 사용하여 복합적인 속성을 만들 수도 있습니다.
권한 부여에 사용하려면 각 속성을 매핑해야 합니다. 예를 들어, 다음 단계에서 사용자의 이메일 주소를 기반으로 권한을 매핑하려면
attribute.user_email
을assertion.user_email
로 매핑해야 합니다.
서비스 계정 임시 인증 정보 검색
워크로드 ID 풀 및 워크로드 ID 프로바이더를 생성하면 Google Cloud로의 인증_이 정의됩니다. 이 시점에서 GitLab CI/CD 작업에서 Google Cloud로 _인증_할 수 있습니다. 그러나 Google Cloud에서 권한(_인가)이 부여되지 않았습니다.
Google Cloud에서 GitLab CI/CD 작업에 권한을 부여하려면 다음을 수행해야 합니다.
- Google Cloud 서비스 계정 생성. 원하는 이름 및 ID를 사용할 수 있습니다.
- Google Cloud 리소스에 대한 IAM 권한 부여.
이러한 권한은 사용 사례에 따라 크게 달라집니다. 일반적으로 이 서비스 계정에는 GitLab CI/CD 작업에서 사용하고자 하는 Google Cloud 프로젝트 및 리소스에 대한 권한을 부여합니다. 예를 들어, GitLab CI/CD 작업에서 Google Cloud Storage 버킷에 파일을 업로드해야 하는 경우, 이 서비스 계정에는 클라우드 스토리지 버킷에 대한
roles/storage.objectCreator
역할을 부여합니다. -
외부 ID 권한 부여하여 서비스 계정을 루트 사용자화합니다. 이 단계을 통해 GitLab CI/CD 작업이 서비스 계정을 대표해 Google Cloud로 _인가_할 수 있습니다. 이 단계은 서비스 계정 자체에 대한 IAM 권한을 부여하여 외부 ID를 통해 이 서비스 계정이 행동할 수 있도록 하는 것입니다. 외부 ID는
principalSet://
프로토콜을 사용하여 표현됩니다.
이전 단계와 마찬가지로 이 단계는 원하는 구성에 크게 의존합니다. 예를 들어, GitLab CI/CD 작업이 chris
라는 GitLab 사용자가 시작했을 때 my-service-account
라는 서비스 계정을 대표하여 허용하려면 외부 ID에 roles/iam.workloadIdentityUser
IAM 역할을 my-service-account
의 외부 ID에 부여합니다.
외부 ID는 다음 형식을 취합니다:
principalSet://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/attribute.user_login/chris
여기서 PROJECT_NUMBER
는 Google Cloud 프로젝트 번호이고, POOL_ID
는 첫 번째 섹션에서 생성한 워크로드 ID 풀의 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 및 서비스에 인증할 수 있습니다. 또한 이 값을 CLOUDSDK_AUTH_ACCESS_TOKEN
환경 변수로 설정하여 gcloud
CLI에 전달할 수도 있습니다.
작동 예시
참조 프로젝트를 검토하여 Terraform을 사용하여 GCP에서 OIDC를 프로비저닝하고, 임시 자격 증명을 가져오는 샘플 스크립트를 참조하세요.
문제 해결
-
curl
응답을 디버깅할 때, 최신 버전의 curl을 설치하세요.-f
대신--fail-with-body
를 사용합니다. 이 명령은 유용한 오류 메시지를 포함할 수 있는 전체 본문을 인쇄합니다. -
Google Cloud의 Workload Identity Federation 문제 해결에 대한 문서를 검토하세요.