GCP Secret Manager을 GitLab CI/CD에서 사용하기

Tier: Premium, Ultimate Offering: GitLab.com, Self-managed, GitLab Dedicated

당신은 GitLab CI/CD 파이프라인에서 Google Cloud (GCP) Secret Manager에 저장된 시크릿을 사용할 수 있습니다.

GitLab을 GCP Secret Manager와 함께 사용하는 흐름은 다음과 같습니다:

  1. GitLab은 CI/CD 작업에 ID 토큰을 제공합니다.
  2. 러너는 해당 ID 토큰을 사용하여 GCP에 인증합니다.
  3. GCP는 GitLab에서 ID 토큰을 확인합니다.
  4. GCP는 유효 기간이 짧은 액세스 토큰을 발급합니다.
  5. 러너는 액세스 토큰을 사용하여 시크릿 데이터에 액세스합니다.
  6. GCP는 액세스 토큰의 주최자에 대한 IAM 권한을 확인합니다.
  7. GCP는 시크릿 데이터를 러너에게 반환합니다.

GitLab을 GCP Secret Manager와 함께 사용하려면 다음을 해야합니다:

GCP IAM Workload Identity Federation (WIF) 구성

GCP IAM WIF는 GitLab에서 발급된 ID 토큰을 인식하고 해당 토큰에 적절한 주체를 할당하도록 구성해야 합니다. 주체는 시크릿 매니저 리소스에 대한 액세스를 승인하는 데 사용됩니다:

  1. GCP 콘솔에서 IAM 및 관리자 > Workload Identity Federation으로 이동합니다.
  2. 풀 생성을 선택하고 고유한 이름(예: gitlab-pool)으로 새 ID 풀을 생성합니다.
  3. 공급자 추가를 선택하여 고유한 이름(예: gitlab-provider)으로 ID 풀에 새 OIDC 공급자를 추가합니다.
    1. 발급자 (URL)를 GitLab URL(예: https://gitlab.com)로 설정합니다.
    2. 기본 청중을 선택하거나 사용자 정의 청중을 위해 허용 청중을 선택합니다. 이는 GitLab CI/CD ID 토큰의 aud에서 사용됩니다.
  4. 속성 매핑에서 다음 매핑을 생성합니다.
    • attribute.X는 Google의 클레임에 존재하는 속성의 이름입니다.
    • assertion.XGitLab의 클레임에서 추출한 값입니다.
    Google의 속성 GitLab에서의 클레임
    google.subject assertion.sub
    attribute.gitlab_project_id assertion.project_id

GCP IAM 주체에 액세스 권한 부여

WIF를 설정한 후, 작업량 ID 주체에게 시크릿 매니저에 있는 시크릿에 대한 액세스 권한을 부여해야 합니다.

  1. GCP 콘솔에서 IAM & 관리자 > IAM으로 이동합니다.
  2. 외부 ID 형식은 다음과 같습니다:

    principalSet://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/attribute.gitlab_project_id/GITLAB_PROJECT_ID
    

    여기서:

    • PROJECT_NUMBER: 프로젝트 대시보드에서 찾을 수 있는 Google Cloud 프로젝트 번호입니다.
    • POOL_ID: 첫 번째 섹션에서 만든 작업량 ID 풀의 ID(이름이 아님)입니다. 예시: gitlab-pool.
    • GITLAB_PROJECT_ID: 프로젝트 개요 페이지에서 찾을 수 있는 GitLab 프로젝트 ID입니다.
  3. Secret Manager Secret Accessor 역할을 할당합니다.
  4. (옵션) IAM 조건(옵션)을 선택하여 IAM 조건을 추가합니다. 조건 빌더에서 조건을 추가할 수 있습니다. 예를 들어, 두 개의 AND 조건을 추가할 수 있습니다:
    • 첫 번째 조건:
      • 조건 유형: 유형
      • 연산자: is
      • 리소스 유형: secretmanager.googleapis.com/SecretVersion
    • 두 번째 조건:
      • 조건 유형: 이름
      • 연산자: 시작할 때
      • : 액세스를 부여하려는 시크릿의 패턴

프로젝트 이름으로 시작하는 시크릿에 액세스하거나 다른 세부적인 액세스 제어를 위해 추가적인 IAM 조건을 추가할 수 있습니다.

GitLab CI/CD에서 GCP Secret Manager 시크릿 사용 구성

GCP Secret Manager에 대한 세부 정보를 제공하기 위해 이러한 CI/CD 변수를 추가해야 합니다:

  • GCP_PROJECT_NUMBER: GCP 프로젝트 번호.
  • GCP_WORKLOAD_IDENTITY_FEDERATION_POOL_ID: WIF Pool ID, 예: gitlab-pool.
  • GCP_WORKLOAD_IDENTITY_FEDERATION_PROVIDER_ID: WIF Provider ID, 예: gitlab-provider.

그런 다음, gcp_secret_manager 키워드를 사용하여 CI/CD 작업에서 GCP Secret Manager에 저장된 시크릿을 정의할 수 있습니다:

job_using_gcp_sm:
  id_tokens:
    GCP_ID_TOKEN:
      # `aud`는 WIF ID 풀에 정의된 청중과 일치해야 합니다.
      aud: https://iam.googleapis.com/projects/${GCP_PROJECT_NUMBER}/locations/global/workloadIdentityPools/${GCP_WORKLOAD_IDENTITY_FEDERATION_POOL_ID}/providers/${GCP_WORKLOAD_IDENTITY_FEDERATION_PROVIDER_ID}
  secrets:
    DATABASE_PASSWORD:
      gcp_secret_manager:
        name: my-project-secret  # GCP Secret Manager에 정의된 시크릿의 이름
        version: 1               # 선택 사항: 기본값은 `latest`입니다.
      token: $GCP_ID_TOKEN

문제 해결

The size of mapped attribute google.subject exceeds the 127 bytes limit 오류

긴 Merge Request 브랜치 이름은 assertion.sub 속성이 127자 이상인 경우 다음 오류로 작업 실패를 일으킬 수 있습니다:

ERROR: Job failed (system failure): resolving secrets: failed to exchange sts token: googleapi: got HTTP response code 400 with body:
{"error":"invalid_request","error_description":"The size of mapped attribute google.subject exceeds the 127 bytes limit.
Either modify your attribute mapping or the incoming assertion to produce a mapped attribute that is less than 127 bytes."}

예를 들어, gitlab-org/gitlab 브랜치의 경우, 페이로드는 project_path:gitlab-org/gitlab:ref_type:branch:ref:{branch_name}가 되어야 하므로, 브랜치 이름은 76자 이하여야 합니다.

WARNING: Not resolved: no resolver that can handle the secret 경고

Google Cloud Secret Manager 통합은 적어도 GitLab 16.8과 GitLab Runner 16.8이 필요합니다. 이 경고는 16.8보다 이전 버전의 러너를 사용하여 작업을 실행하는 경우에 나타납니다.

GitLab.com에서 SaaS 러너가 이전 버전을 실행하는 알려진 문제로 이 문제가 해결될 때까지의 임시 방편으로, 16.8 이상 버전의 GitLab Runner를 등록할 수 있습니다.