GCP Secret Manager 시크릿을 GitLab CI/CD에서 사용하기
GCP Secret Manager 시크릿을 GitLab CI/CD에서 사용하기
Google Cloud(GCP) Secret Manager에 저장된 시크릿을 GitLab CI/CD 파이프라인에서 사용하는 방법을 설명하는 문서예요. Workload Identity Federation(WIF)을 이용한 인증 흐름과 IAM 권한 구성, CI/CD 변수 설정을 코드 예시와 함께 옆에서 설명해 주는 방식으로 정리했어요.
다른 GCP 프로젝트의 시크릿을 읽는 방법과 자주 겪는 문제 해결 방법도 함께 다루고 있어요.
출처: 문서
본문
Google Cloud(GCP) Secret Manager에 저장된 시크릿을 GitLab CI/CD 파이프라인에서 사용할 수 있어요.
GitLab을 GCP Secret Manager와 함께 사용하는 흐름은 다음과 같아요.
- GitLab이 CI/CD 작업에 ID 토큰을 발급해요.
- 러너가 ID 토큰으로 GCP에 인증해요.
- GCP가 ID 토큰을 GitLab으로 검증해요.
- GCP가 수명이 짧은 액세스 토큰을 발급해요.
- 러너가 액세스 토큰으로 시크릿 데이터에 접근해요.
- GCP가 액세스 토큰의 주체(principal)에 대한 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 콘솔에서 IAM & Admin > Workload Identity Federation으로 이동하세요.
- CREATE POOL을 선택하고 고유한 이름(예:
gitlab-pool)으로 새 ID 풀을 만드세요. - ADD PROVIDER를 선택해 ID 풀에 고유한 이름(예:
gitlab-provider)의 새 OIDC 제공자를 추가하세요.- **Issuer (URL)**을 GitLab URL(예:
https://gitlab.com)로 설정하세요. - Default audience를 선택하거나, GitLab CI/CD ID 토큰의
aud에 사용할 사용자 지정 오디언스를 위해 Allowed audiences를 선택하세요. - Attribute Mapping 아래에서 다음 매핑을 만드세요. 여기서:
attribute.X는 Google 토큰에 클레임으로 포함할 속성 이름.assertion.X는 GitLab 클레임에서 추출할 값. | 속성 (Google 쪽) | 어서션 (GitLab 쪽) | |---|---| |google.subject|assertion.sub| |attribute.gitlab_project_id|assertion.project_id|
- **Issuer (URL)**을 GitLab URL(예:
GCP IAM 주체에 접근 권한 부여
WIF를 설정한 후에는 WIF 주체가 Secret Manager의 시크릿에 접근할 수 있도록 권한을 부여해야 해요.
- GCP 콘솔에서 Security > Secret Manager로 이동하세요.
- 접근 권한을 부여할 시크릿의 이름을 선택해 시크릿 세부 정보를 보세요.
- PERMISSIONS 탭에서 GRANT ACCESS를 선택해 WIF 제공자를 통해 생성된 주체 집합(principal set)에 접근 권한을 부여하세요. 외부 ID 형식은 다음과 같아요.
이 예시에서:principalSet://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/attribute.gitlab_project_id/GITLAB_PROJECT_IDPROJECT_NUMBER: 프로젝트의 대시보드에서 찾을 수 있는 Google Cloud 프로젝트 번호(ID가 아님).POOL_ID: 첫 번째 섹션에서 만든 워크로드 ID 풀의 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 Project Number.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 키워드로 정의해 GCP Secret Manager에 저장된 시크릿을 CI/CD 작업에서 사용할 수 있어요.
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 # This is the name of the secret defined in GCP Secret Manager
version: 1 # optional: default to `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:
# ... as previously configured ...
secrets:
DATABASE_PASSWORD:
gcp_secret_manager:
name: projects/123456789/secrets/my-project-secret # fully-qualified name of the secret defined in GCP Secret Manager
version: 1 # optional: defaults to `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_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 통합을 지원하지 않을 때 나타나요. 러너를 지원되는 버전으로 업그레이드하세요.
더 알아보기
GCP Secret Manager 통합 설정의 자세한 사항은 GCP용 OIDC 문서와 함께, 시크릿 인증의 기반이 되는 ID 토큰 인증 문서를 함께 읽어보시면 좋아요.