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

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 토큰을 인식하고 적절한 주체를 할당하도록 구성해야 합니다.
주체는 Secret Manager 리소스에 대한 액세스를 승인하는 데 사용됩니다:

  1. GCP Console에서 IAM & Admin > Workload Identity Federation로 이동합니다.
  2. 풀 생성을 선택하고 예를 들어 gitlab-pool와 같은 고유한 이름의 새로운 ID 풀을 생성합니다.
  3. 제공자 추가를 선택하여 예를 들어 gitlab-provider와 같은 고유한 이름의 새로운 OIDC 제공자를 ID 풀에 추가합니다.
    1. 발급자(URL)를 GitLab URL로 설정합니다. 예: https://gitlab.com.
    2. 기본 청중을 선택하거나, 커스텀 청중을 위해 허용된 청중을 선택합니다. 이는 GitLab CI/CD ID 토큰의 aud에서 사용됩니다.
  4. 속성 매핑 아래에서 다음 매핑을 생성합니다:

    • attribute.X는 Google의 클레임에 존재해야 하는 속성의 이름입니다.
    • assertion.XGitLab 클레임에서 추출할 값입니다.
    Google의 속성 GitLab의 Assertion
    google.subject assertion.sub
    attribute.gitlab_project_id assertion.project_id

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

WIF를 설정한 후에는 WIF 주체에 비밀 관리자에서 비밀에 대한 액세스 권한을 부여해야 합니다.

  1. GCP Console에서 보안 > 비밀 관리자로 이동합니다.
  2. 액세스 권한을 부여하려는 비밀의 이름을 선택하여 비밀의 세부정보를 확인합니다.
  3. 권한 탭에서 액세스 부여를 선택하여 WIF 제공자를 통해 생성된 주체에 액세스를 부여합니다.
    외부 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: 첫 번째 섹션에서 생성된 Workload Identity Pool의 ID(이름 아님), 예: gitlab-pool.
    • GITLAB_PROJECT_ID: 프로젝트 개요 페이지에서 찾을 수 있는 GitLab 프로젝트 ID.
  4. Secret Manager 비밀 접근자 역할을 할당합니다.

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 Identity Pool에 정의된 audience와 일치해야 합니다.
      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/<project-number>/secrets/<secret-name> 형식으로 완전한 비밀 이름을 사용하세요.

예를 들어, 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 issue #264362370에서 추적됩니다.

이 문제를 해결하는 유일한 방법은 브랜치와 리포지토리의 이름을 짧게 사용하는 것입니다.

비밀 제공자를 찾을 수 없습니다. CI/CD 변수를 확인하고 다시 시도하십시오. 메시지

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

비밀 제공자를 찾을 수 없습니다. CI/CD 변수를 확인하고 다시 시도하십시오.

필수 변수가 정의되지 않았기 때문에 작업을 만들 수 없습니다:

  • GCP_PROJECT_NUMBER
  • GCP_WORKLOAD_IDENTITY_FEDERATION_POOL_ID
  • GCP_WORKLOAD_IDENTITY_FEDERATION_PROVIDER_ID

경고: 해결되지 않음: 비밀을 처리할 수 있는 해결자가 없음 경고

Google Cloud Secret Manager 통합은 최소한 GitLab 16.8 및 GitLab Runner 16.8을 요구합니다.

이 경고는 16.8보다 이전 버전을 사용하는 러너에 의해 작업이 실행될 때 나타납니다.

GitLab.com에서는 알려진 문제로 인해 SaaS 러너가 이전 버전을 실행하고 있습니다. 이 문제가 해결될 때까지,

자신의 GitLab Runner를 버전 16.8 또는 그 이상으로 등록할 수 있습니다.