GitLab CI/CD에서 GCP Secret Manager 시크릿 사용
Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated
GitLab CI/CD 파이프라인에서 Google Cloud (GCP) Secret Manager에 저장된 시크릿을 사용할 수 있습니다. GCP Secret Manager와 GitLab을 사용하는 흐름은 다음과 같습니다:
히스토리
- GitLab 및 GitLab Runner 16.8에서 도입됨.
GitLab CI/CD 파이프라인에서 Google Cloud (GCP) Secret Manager에 저장된 시크릿을 사용할 수 있습니다.
GCP Secret Manager와 GitLab을 사용하는 흐름은 다음과 같습니다:
- GitLab이 CI/CD job에 ID 토큰을 발급합니다.
- 러너가 ID 토큰을 사용하여 GCP에 인증합니다.
- GCP가 GitLab으로 ID 토큰을 검증합니다.
- GCP가 단기 액세스 토큰을 발급합니다.
- 러너가 액세스 토큰을 사용하여 시크릿 데이터에 액세스합니다.
- GCP가 액세스 토큰의 주체에 대한 IAM 시크릿 권한을 확인합니다.
- GCP가 러너에게 시크릿 데이터를 반환합니다.
GitLab을 GCP Secret Manager와 함께 사용하려면:
- GCP Secret Manager에 저장된 시크릿이 있어야 합니다.
- GitLab을 ID 공급자로 포함하도록 GCP Workload Identity Federation 구성을 합니다.
- GCP Secret Manager에 대한 액세스 권한을 부여하도록 GCP IAM 구성을 합니다.
- GCP Secret Manager와 함께 GitLab CI/CD 구성을 합니다.
GCP IAM Workload Identity Federation (WIF) 구성#
GCP IAM WIF는 GitLab이 발급한 ID 토큰을 인식하고 적절한 주체를 할당하도록 구성해야 합니다. 주체는 Secret Manager 리소스에 대한 액세스를 승인하는 데 사용됩니다:
-
GCP Console에서 IAM & Admin > Workload Identity Federation으로 이동합니다.
-
CREATE POOL을 선택하고 고유한 이름(예:
gitlab-pool)으로 새 ID 풀을 만듭니다. -
ADD PROVIDER를 선택하여 고유한 이름(예:
gitlab-provider)으로 ID 풀에 새 OIDC 공급자를 추가합니다.- **Issuer (URL)**을 GitLab URL(예:
https://gitlab.com)로 설정합니다. - Default audience를 선택하거나, GitLab CI/CD ID 토큰의
aud에 사용되는 사용자 정의 대상을 위해 Allowed audiences를 선택합니다.
- **Issuer (URL)**을 GitLab URL(예:
-
Attribute Mapping 아래에서 다음 매핑을 만듭니다. 여기서:
attribute.X는 Google 토큰에 클레임으로 포함할 속성의 이름입니다.assertion.X는 GitLab 클레임에서 추출할 값입니다.
속성 (Google) 주장 (GitLab) google.subjectassertion.subattribute.gitlab_project_idassertion.project_id
GCP IAM 주체에 액세스 권한 부여#
WIF를 설정한 후 WIF 주체에게 Secret Manager의 시크릿에 대한 액세스 권한을 부여해야 합니다.
-
GCP Console에서 Security > Secret Manager로 이동합니다.
-
액세스 권한을 부여할 시크릿의 이름을 선택하여 시크릿 세부 정보를 봅니다.
-
PERMISSIONS 탭에서 GRANT ACCESS를 선택하여 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 프로젝트 번호(ID 아님).POOL_ID: 첫 번째 섹션에서 만든 Workload Identity Pool의 ID(이름 아님), 예:gitlab-pool.GITLAB_PROJECT_ID: 프로젝트 개요 페이지에서 찾을 수 있는 GitLab 프로젝트 ID.
-
Secret Manager Secret Accessor 역할을 할당합니다.
GCP Secret Manager 시크릿을 사용하도록 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 job에서 GCP Secret Manager에 저장된 시크릿을 사용할 수 있습니다:
job_using_gcp_sm:
id_tokens:
GCP_ID_TOKEN:
# `aud`는 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
다른 GCP 프로젝트의 시크릿 사용#
히스토리
- GitLab 17.0에서 도입됨.
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
문제 해결#
오류: The size of mapped attribute google.subject exceeds the 127 bytes limit#
긴 브랜치 경로는 assertion.sub 속성이 127자를 초과하기 때문에 이 오류와 함께 job이 실패할 수 있습니다:
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에서 추적됩니다.
이 문제에 대한 유일한 해결 방법은 브랜치와 리포지터리 이름을 짧게 사용하는 것입니다.
The secrets provider can not be found. Check your CI/CD variables and try again. 메시지#
GCP Secret Manager에 액세스하도록 구성된 job을 시작하려고 할 때 이 오류가 발생할 수 있습니다:
The secrets provider can not be found. Check your CI/CD variables and try again.
다음 필수 변수 중 하나 이상이 정의되지 않아 job을 만들 수 없습니다:
GCP_PROJECT_NUMBERGCP_WORKLOAD_IDENTITY_FEDERATION_POOL_IDGCP_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 이전 버전을 사용하는 러너에서 job이 실행되는 경우 나타납니다.
