GCP 워크로드 ID 페더레이션을 OpenID Connect로 구성하려면

Tier: Free, Premium, Ultimate Offering: GitLab.com, Self-managed, GitLab Dedicated
caution
CI_JOB_JWT_V2GitLab 15.9에서 사양이 폐기되었으며 GitLab 17.0에서 제거 예정입니다. ID 토큰을 대신 사용하세요.

이 자습서에서는 JSON 웹 토큰(JWT) 및 워크로드 ID 페더레이션을 사용하여 GitLab CI/CD 작업에서 Google Cloud에 인증하는 방법을 보여줍니다. 이 구성은 어떤 비밀을 저장할 필요 없이 요청 시 생성되는 유효 기간이 짧은 자격증명을 생성합니다.

시작하려면 GitLab과 Google Cloud 간의 ID 페더레이션을 위해 OpenID Connect (OIDC)를 구성하세요. GitLab에서 OIDC를 사용하는 자세한 내용은 클라우드 서비스에 연결을 참조하세요.

이 자습서는 Google Cloud 계정 및 Google Cloud 프로젝트가 있는 것으로 가정합니다. 계정은 Google Cloud 프로젝트에서 적어도 워크로드 ID 풀 관리자 권한이 있어야 합니다.

note
이 자습서 대신 Terraform 모듈과 CI/CD 템플릿을 사용하려면 Google Cloud와 GitLab CI/CD 파이프라인의 인증을 간소화하는 OIDC 모듈 소개을 참조하세요.

이 자습서를 완료하려면:

  1. Google Cloud 워크로드 ID 풀 생성.
  2. 워크로드 ID 프로바이더 생성.
  3. 서비스 계정 임시 인증 정보 검색.

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.XGitLab 클레임에서 추출할 값을 나타냅니다.

    Google의 속성 GitLab에서의 클레임
    google.subject assertion.sub
    attribute.X assertion.X

    공통 표현 언어(CEL)를 사용하여 복합적인 속성을 만들 수도 있습니다.

    권한 부여에 사용하려면 각 속성을 매핑해야 합니다. 예를 들어, 다음 단계에서 사용자의 이메일 주소를 기반으로 권한을 매핑하려면 attribute.user_emailassertion.user_email로 매핑해야 합니다.

서비스 계정 임시 인증 정보 검색

워크로드 ID 풀 및 워크로드 ID 프로바이더를 생성하면 Google Cloud로의 인증_이 정의됩니다. 이 시점에서 GitLab CI/CD 작업에서 Google Cloud로 _인증_할 수 있습니다. 그러나 Google Cloud에서 권한(_인가)이 부여되지 않았습니다.

Google Cloud에서 GitLab CI/CD 작업에 권한을 부여하려면 다음을 수행해야 합니다.

  1. Google Cloud 서비스 계정 생성. 원하는 이름 및 ID를 사용할 수 있습니다.
  2. Google Cloud 리소스에 대한 IAM 권한 부여. 이러한 권한은 사용 사례에 따라 크게 달라집니다. 일반적으로 이 서비스 계정에는 GitLab CI/CD 작업에서 사용하고자 하는 Google Cloud 프로젝트 및 리소스에 대한 권한을 부여합니다. 예를 들어, GitLab CI/CD 작업에서 Google Cloud Storage 버킷에 파일을 업로드해야 하는 경우, 이 서비스 계정에는 클라우드 스토리지 버킷에 대한 roles/storage.objectCreator 역할을 부여합니다.
  3. 외부 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 문제 해결에 대한 문서를 검토하세요.