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

Tier: 프리미엄, 얼티밋 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는 ID 토큰을 GitLab로 검증합니다.
  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 콘솔에서 IAM 및 관리 > Workload Identity Federation로 이동합니다.
  2. 풀 생성을 선택하고 고유한 이름(예: gitlab-pool)으로 새로운 식별 풀을 생성합니다.
  3. 제공자 추가를 선택하여 Identity Pool에 고유한 이름(예: gitlab-provider)의 새 OIDC 제공자를 추가합니다.
    1. 발행자 (URL) 를 GitLab URL(예: https://gitlab.com)로 설정합니다.
    2. 기본 대상(allowed audiences)을 선택하거나 GitLab CI/CD의 ID 토큰의 aud에 사용되는 사용자 정의 대상(allowed audiences)을 선택합니다.
  4. 속성 매핑에서 다음과 같은 매핑을 생성합니다.

    • attribute.X는 Google의 클레임에 표시될 속성의 이름입니다.
    • assertion.XGitLab 클레임에서 추출할 값입니다.
    Google의 속성 GitLab에서의 클레임
    google.subject assertion.sub
    attribute.gitlab_project_id assertion.project_id

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

WIF를 설정한 후에는 WIF 프로바이더를 통해 생성된 주체에게 Secret Manager의 시크릿에 액세스 권한을 부여해야 합니다.

  1. GCP 콘솔에서 IAM 및 관리 > IAM으로 이동합니다.
  2. 액세스 권한을 부여하려면 액세스 권한 부여를 선택합니다. 외부 식별형식은 다음과 같습니다:

    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입니다.
  3. Secret Manager Secret Accessor 역할을 할당합니다.
  4. (선택 사항) IAM 조건(선택 사항)을 선택하여 IAM 조건을 추가합니다. **조건 빌더에서 조건을 추가할 수 있습니다. 예를 들어 두 가지 AND 조건을 추가할 수 있습니다:
    • 첫 번째 조건:
      • 조건 유형: 유형
      • 연산자: is
      • 리소스 유형: secretmanager.googleapis.com/SecretVersion
    • 두 번째 조건:
      • 조건 유형: 이름
      • 연산자: 시작이
      • : 액세스 권한을 부여하려는 시크릿의 패턴입니다.

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

GCP 시크릿 매니저 시크릿을 사용하도록 GitLab CI/CD 구성

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` must match the audience defined in the WIF Identity Pool.
      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 오류

긴 병합 요청 브랜치 이름이 the assertion.sub attribute가 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를 등록할 수 있습니다.