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. Runner가 ID 토큰을 사용하여 GCP에 인증합니다.
  3. GCP가 GitLab에서 ID 토큰을 확인합니다.
  4. GCP가 수명이 짧은 액세스 토큰을 발급합니다.
  5. Runner가 액세스 토큰을 사용하여 비밀 데이터에 액세스합니다.
  6. GCP는 액세스 토큰의 주요 부분에서 IAM 비밀 권한을 확인합니다.
  7. GCP가 비밀 데이터를 Runner에 반환합니다.

GitLab과 GCP Secret Manager를 사용하려면 다음을 해야 합니다:

GCP IAM Workload Identity Federation (WIF) 구성

GCP IAM WIF는 GitLab에서 발급된 ID 토큰을 인식하고 해당 토큰에 적절한 주체를 할당하여야 합니다. 주체는 Secret Manager 리소스에 대한 액세스를 인가하는 데 사용됩니다:

  1. GCP Console에서 IAM 및 관리자 > Workload Identity Federation로 이동합니다.
  2. POOL 생성을 선택하여 고유 이름(예: gitlab-pool)으로 새 식별 풀을 생성합니다.
  3. 제공자 추가를 선택하여 새 OIDC 제공자(예: gitlab-provider)를 고유 이름으로 식별 풀에 추가합니다.
    1. 발행자(발급 URL)를 GitLab URL(예: https://gitlab.com)로 설정합니다.
    2. 기본 청중(Default audience)을 선택하거나 GitLab CI/CD ID 토큰의 aud에 사용되는 사용자 정의 청중에 대해 허용된 청중(Allowed audiences)을 선택합니다.
  4. 속성 매핑에서 다음과 같은 매핑을 만듭니다.

    • 속성.X은 Google 클레임에 나타나길 원하는 속성의 이름입니다.
    • 주장.XGitLab claim에서 추출할 값입니다.
    Google의 속성 GitLab에서의 주장
    google.subject 주장.sub
    속성.gitlab_project_id 주장.project_id

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

WIF를 설정한 후에는 Secret Manager의 비밀에 대한 WIF 주체에게 액세스 권한을 부여해야 합니다.

  1. GCP Console에서 보안 > Secret Manager로 이동합니다.
  2. 액세스 권한을 부여할 비밀 이름을 선택하여 비밀의 세부정보를 보여줍니다.
  3. 권한 탭에서 WIF 제공자를 통해 생성된 주체에게 액세스 권한을 부여하려면 액세스 부여를 선택합니다. 외부 식별자 형식은 다음과 같습니다:

    principalSet://iam.googleapis.com/projects/프로젝트_번호/locations/global/workloadIdentityPools/POOL_ID/attribute.gitlab_project_id/GITLAB_PROJECT_ID
    

    이 예시에서:

    • 프로젝트_번호: 프로젝트 대시보드에서 찾을 수 있는 Google Cloud 프로젝트 번호입니다.
    • POOL_ID: 첫 번째 섹션에서 생성한 Workload Identity Pool의 ID(이름이 아닙니다). 예: gitlab-pool.
    • GITLAB_PROJECT_ID: 프로젝트 개요 페이지에서 찾을 수 있는 GitLab 프로젝트 ID입니다.
  4. 역할을 Secret Manager Secret Accessor로 지정합니다.

GitLab CI/CD를 GCP Secret Manager 비밀을 사용하도록 구성

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

  • GCP_PROJECT_NUMBER: GCP 프로젝트 번호.
  • GCP_WORKLOAD_IDENTITY_FEDERATION_POOL_ID: WIF 풀 ID(예: gitlab-pool).
  • GCP_WORKLOAD_IDENTITY_FEDERATION_PROVIDER_ID: WIF 제공자 ID(예: gitlab-provider).

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

job_using_gcp_sm:
  id_tokens:
    GCP_ID_TOKEN:
      # `aud`는 WIF 식별 풀에서 정의된 청중과 일치해야 합니다.
      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

다른 GCP 프로젝트에서 비밀 사용

GCP의 비밀 이름은 프로젝트별입니다. 기본값으로 gcp_secret_manager:name에 지정된 비밀은 GCP_PROJECT_NUMBER에서 지정된 프로젝트에서 읽혀집니다.

WIF 풀을 포함한 프로젝트와 다른 프로젝트에서 비밀을 읽으려면 projects/<프로젝트_번호>/secrets/<비밀_이름> 형식으로 완전한 비밀 이름을 사용합니다.

예를 들어, my-project-secret가 GCP 프로젝트 번호 123456789에 있으면 다음과 같이 해당 비밀에 액세스할 수 있습니다:

job_using_gcp_sm:
  # ... 위와 같이 구성됨 ...
  secrets:
    DATABASE_PASSWORD:
      gcp_secret_manager:
        name: projects/123456789/secrets/my-project-secret  # GCP Secret Manager에 정의된 비밀의 완전한 이름
        version: 1                                          # 옵션: 기본값은 `latest`입니다.
      token: $GCP_ID_TOKEN

문제 해결

오류: 매핑된 속성 ‘google.subject’의 크기가 127바이트 제한을 초과합니다.

긴 브랜치 경로는 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}입니다. 문자열이 127자보다 짧아야 하므로 브랜치 이름은 76자 이하여야 합니다. 이 제한은 Google Cloud IAM에서 부여되며 Google 이슈 #264362370에서 추적됩니다.

이 문제의 유일한 해결책은 더 짧은 이름을 사용하는 것입니다. 브랜치 및 저장소의 이름을 더 짧게 사용하십시오.

The secrets provider can not be found. Check your CI/CD variables and try again. 메시지

GCP Secret Manager에 액세스하도록 구성된 작업을 시작하려고 시도할 때이 오류가 발생할 수 있습니다.

The secrets provider can not be found. Check your CI/CD variables and try again.

하나 이상의 필수 변수가 정의되지 않았기 때문에 작업을 생성할 수 없습니다:

  • GCP_PROJECT_NUMBER
  • GCP_WORKLOAD_IDENTITY_FEDERATION_POOL_ID
  • GCP_WORKLOAD_IDENTITY_FEDERATION_PROVIDER_ID

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를 등록할 수 있습니다.