Google Cloud 시크릿 엔진

Google Cloud 시크릿 엔진

Google Cloud Vault 시크릿 엔진은 IAM 정책을 기반으로 Google Cloud 서비스 계정 키와 OAuth 토큰을 동적으로 생성해요. 덕분에 사용자는 전용 서비스 계정을 만들거나 관리할 필요 없이 Google Cloud 리소스에 접근할 수 있어요.

이 시크릿 엔진으로 Google Cloud IAM 서비스 계정을 관리하면 얻는 이점은 다음과 같아요.

  • GCP IAM 서비스 계정 키 자동 정리 — 각 서비스 계정 키는 Vault 리스(lease)와 연결돼요. 리스가 만료되면(정상 폐기 또는 조기 폐기 모두) 서비스 계정 키가 자동으로 폐기돼요.
  • 빠르고 단기적인 접근 — 사용자는 단기 또는 일회성 접근(배치 작업이나 빠른 조사 같은)을 위해 새 GCP 서비스 계정을 만들 필요가 없어요.
  • 멀티클라우드·하이브리드 클라우드 애플리케이션 — 사용자는 중앙 identity 서비스(예: LDAP)로 Vault에 인증하고, 그 사용자를 위해 새 서비스 계정을 만들거나 관리하지 않고도 GCP 자격 증명을 생성해요.

참고: access_token 리스 폐기(Deprecation) — 이 시크릿 엔진의 이전 버전(Vault ≤ 0.11.1에서 릴리스)에서는 access token과 함께 리스가 생성됐어요. 플러그인의 이전 버전을 쓰고 있다면 업그레이드하세요. 자세한 내용은 업그레이드 가이드를 읽어 보세요.

출처: 문서

본문

설정(Setup)

대부분의 시크릿 엔진은 기능을 수행하기 전에 미리 구성해야 해요. 이 단계는 보통 운영자 또는 구성 관리 도구가 수행해요.

Google Cloud 시크릿 엔진을 활성화해요.

$ vault secrets enable gcp
Success! Enabled the gcp secrets engine at: gcp/

기본적으로 시크릿 엔진은 엔진 이름 그대로의 경로에 마운트돼요. 다른 경로에 두고 싶다면 -path 인자를 사용하면 됩니다.

설정 중 기존 워크로드 아이덴티티 페더레이션(WIF) identity token 키를 보려면 identity/oidc/key 엔드포인트에 대한 list 권한이 있어야 해요.

Vault GUI에서 활성화하는 방법은 다음과 같아요.

  1. Vault 인스턴스의 GUI를 엽니다.
  2. 플러그인의 네임스페이스로 로그인하거나, 왼쪽 메뉴 하단의 셀렉터에서 네임스페이스를 선택해 다시 인증해요.
  3. 왼쪽 메뉴에서 Secrets를 선택해요.
  4. 하위 메뉴에서 Secrets engines를 선택해요.
  5. Secrets Engines 페이지에서 **Enable new engine +**를 클릭해요.
  6. Google Cloud를 선택해요.
  7. Next를 클릭해요.
  8. GCP 플러그인의 마운트 경로를 설정해요. 예: gcp.
  9. WIF를 쓴다면 identity token 키를 추가해요. Method Options를 클릭하고 Identity Token Key를 클릭한 뒤 새 키 이름을 입력하거나 토큰 키 목록에서 선택해요.
  10. Enable engine을 클릭해요.
  11. Save를 클릭해 플러그인을 활성화해요.

계정 자격 증명으로 시크릿 엔진을 구성하거나, Application Default Credentials를 쓰려면 비워 두거나 쓰지 않은 채로 두세요.

$ vault write gcp/config [email protected]
Success! Data written to: gcp/config

GUI에서 구성하는 방법은 다음과 같아요.

  1. Vault 인스턴스의 GUI를 엽니다.
  2. 플러그인의 네임스페이스로 로그인하거나 네임스페이스를 선택해 다시 인증해요.
  3. 좌측 메뉴에서 Secrets를 선택해요.
  4. 하위 메뉴에서 Secrets engines를 선택해요.
  5. 업데이트하려는 GCP 플러그인을 선택해요.
  6. Configure를 클릭해요.
  7. 구성 정보를 입력해요.
  8. Access type을 Enterprise로 설정해요.
  9. 변경 사항을 저장해요.

Vault를 Google Compute Engine이나 Google Kubernetes Engine 안에서 실행 중이라면, credentials JSON 파일을 지정하는 대신 인스턴스 또는 파드의 서비스 계정을 사용할 수 있어요. 인증에 대한 자세한 내용은 아래 인증 섹션을 참고하세요.

경우에 따라 민감한 IAM 보안 자격 증명을 Vault 구성에 둘 수 없는 상황이 있어요. 예를 들어 조직이 모든 보안 자격 증명을 단기로 유지하거나 머신 아이덴티티에 명시적으로 연결하길 요구할 수 있어요. IAM 보안 자격 증명을 Vault에 제공하려면 아래처럼 Vault 플러그인 워크로드 아이덴티티 페더레이션(WIF)을 사용하는 것을 권장해요.

대안으로 플러그인 WIF에 사용할 audience 클레임 값과 가장(assume)할 서비스 계정 이메일을 구성할 수 있어요.

$ vault write gcp/config \
    identity_token_audience=<TOKEN_AUDIENCE> \
    service_account_email=<SERVICE_ACCOUNT_EMAIL>

Access Type으로 Workload Identity Federation을 선택하고 다음 정보를 입력해요.

  • Issuer URL — Vault 플러그인 identity token 발급자의 완전히 정규화되고 네트워크에서 접근 가능한 issuer URL. 예: https://vault.example.com/v1/identity/oidc/plugins
  • Identity token audience — 플러그인 identity token의 audience 클레임 값. 이 값은 대상 Federated Identity Credential에 구성된 허용 audience와 일치해야 해요.
  • Service account email — Workload Identity Federation에 가장(impersonate)할 서비스 계정의 이메일 ID.

Vault의 identity token 공급자는 플러그인 identity token JWT를 내부적으로 서명해요. Vault와 GCP 사이에 WIF를 통한 신뢰 관계가 있으면, 시크릿 엔진은 Vault identity token을 federated access token으로 교환할 수 있어요.

Vault와 GCP 사이에 신뢰 관계를 구성하려면:

  • Vault의 identity token issuer 백엔드를 구성해야 해요.
  • GCP에 Vault 플러그인의 identity token 공급자에 대한 완전히 정규화되고 네트워크에서 접근 가능한 issuer URL 정보로 구성된 workload identity pool과 provider가 있어야 해요.

Vault와 GCP 사이에 신뢰 관계를 맺으면 GCP가 JWKS 공개 키를 가져와 플러그인 identity token 서명을 검증할 수 있어요.

참고: Vault UI는 GCP Secret 엔진 구성만 지원해요. 그 외 작업은 CLI/API를 사용해야 해요.

Rolesets

roleset은 Vault가 관리하는 GCP 서비스 계정과, 그 서비스 계정에 대해 정의된 IAM 바인딩 집합으로 이뤄져요. 서비스 계정 이름은 생성 또는 업데이트 시점을 기준으로 생성돼요. 서비스 계정 이름이 고정돼 있다고 의존하면 안 되며, roleset을 생성하거나 업데이트할 때 모든 IAM 바인딩은 bindings 파라미터를 통해 관리해야 해요.

roleset과 정적 계정(static account)의 차이에 대한 자세한 내용은 아래 '참고할 사항' 섹션을 확인해 주세요.

Roleset 정책 고려 사항

Vault 1.8.0부터 GCP 시크릿 엔진용 glob이 포함된 기존의 관대한 정책이 /gcp/roleset/:roleset/token/gcp/roleset/:roleset/key 엔드포인트의 도입으로 추가 권한을 부여할 수 있어요. 다음 정책은 사용자에게 모든 roleset을 읽을 권한을 주지만, 동시에 토큰과 키를 생성하는 것도 허용해요. 이런 유형의 정책은 권장되지 않아요.

# DO NOT USE — 사용하지 마세요
path "/gcp/roleset/*" {
  capabilities = ["read"]
}

반면 다음 예시처럼 와일드카드를 사용해 최소 권한 원칙을 지키는 roleset 정책을 만들 수 있어요.

path "/gcp/roleset/+" {
  capabilities = ["read"]
}

정책 문법에 대한 자세한 내용은 정책 문서를 참고해 주세요.

예시(Examples)

OAuth2 access token을 생성하는 roleset을 구성해요(권장).

$ vault write gcp/roleset/my-token-roleset \
    project="my-project-id" \
    secret_type="access_token"  \
    token_scopes="https://www.googleapis.com/auth/cloud-platform" \
    bindings=-<<EOF
      resource "//cloudresourcemanager.googleapis.com/projects/my-project-id" {
        roles = ["roles/viewer"]
      }
    EOF

GCP 서비스 계정 키를 생성하는 roleset을 구성해요.

$ vault write gcp/roleset/my-key-roleset \
    project="my-project" \
    secret_type="service_account_key"  \
    bindings=-<<EOF
      resource "//cloudresourcemanager.googleapis.com/projects/my-project" {
        roles = ["roles/viewer"]
      }
    EOF

bindings 인자에 파일을 제공할 수도 있어요.

$ vault write gcp/roleset/my-roleset
    [email protected]
    ...

역할 바인딩과 샘플 역할 바인딩에 대한 자세한 내용은 아래 bindings 섹션을 참고해 주세요. OAuth2 access token과 서비스 계정 키의 차이에 대한 자세한 내용은 아래 '참고할 사항' 섹션을 참고해 주세요.

roleset 생성·관리에 대한 자세한 내용은 GCP 시크릿 엔진 API 문서를 참고해 주세요.

정적 계정(Static accounts)

정적 계정은 Vault 밖에서 생성된 GCP 서비스 계정으로, Vault에 제공해 access token이나 키를 생성해요. Vault로 서비스 계정의 IAM 바인딩을 선택적으로 관리할 수도 있어요.

roleset과 정적 계정의 차이에 대한 자세한 내용은 아래 '참고할 사항' 섹션을 참고해 주세요.

예시(Examples)

정적 계정을 구성하기 전에 먼저 Google Cloud Service Account를 만들어야 해요. 생성한 서비스 계정의 이메일 주소를 기억해 두세요. 서비스 계정 이메일은 <service-account-id>@<project-id>.iam.gserviceaccount.com 형식이에요.

OAuth2 access token을 생성하는 정적 계정을 구성해요(권장).

$ vault write gcp/static-account/my-token-account \
    service_account_email="[email protected]" \
    secret_type="access_token"  \
    token_scopes="https://www.googleapis.com/auth/cloud-platform" \
    bindings=-<<EOF
      resource "//cloudresourcemanager.googleapis.com/projects/my-project" {
        roles = ["roles/viewer"]
      }
    EOF

GCP 서비스 계정 키를 생성하는 정적 계정을 구성해요.

$ vault write gcp/static-account/my-key-account \
    service_account_email="[email protected]" \
    secret_type="service_account_key"  \
    bindings=-<<EOF
      resource "//cloudresourcemanager.googleapis.com/projects/my-project" {
        roles = ["roles/viewer"]
      }
    EOF

bindings 인자에 파일을 제공할 수도 있어요.

$ vault write gcp/static-account/my-account
    [email protected]
    ...

역할 바인딩과 샘플 역할 바인딩에 대한 자세한 내용은 아래 bindings 섹션을 참고해 주세요. 정적 계정 생성·관리에 대한 자세한 내용은 GCP 시크릿 엔진 API 문서를 참고해 주세요.

가장 계정(Impersonated accounts)

가장 계정은 다른 주어진 서비스 계정의 권한과 접근 권한이 부여된 OAuth2 access token을 생성하는 방법이에요. 이 access token은 서비스 계정 키가 갖는 10개 키 제한이 없으면서도 단기라는 특성은 유지해요. 기본적으로 GCP에서 TTL이 1시간이지만, Google의 단기 자격 증명 문서에서 설명하듯 최대 12시간까지 구성할 수 있어요.

GCP의 서비스 계정 가장에 대한 자세한 내용은 여기 문서부터 시작해 보세요.

예시(Examples)

cloud platform과 compute 스코프로 Google Cloud 프로젝트의 관리자를 가장(impersonate)하는 Vault 역할을 구성해요.

$ vault write gcp/impersonated-account/my-token-impersonate \
    service_account_email="[email protected]" \
    token_scopes="https://www.googleapis.com/auth/cloud-platform,https://www.googleapis.com/auth/compute" \
    ttl="6h"

사용법(Usage)

시크릿 엔진을 구성하고 사용자/머신이 적절한 권한을 가진 Vault 토큰을 갖고 있으면 자격 증명을 생성할 수 있어요. Vault 역할이 어떻게 구성됐느냐에 따라 OAuth2 토큰 또는 서비스 계정 키를 생성할 수 있어요.

Access tokens

OAuth2 access token을 생성하려면 gcp/.../token API에서 읽어요. roleset이나 정적 계정을 쓰는 경우 secret_typeaccess_token으로 생성되어 있어야 해요. 가장 계정은 기본적으로 OAuth2 토큰을 생성해요.

Roleset:

$ vault read gcp/roleset/my-token-roleset/token
Key                Value
---                -----
expires_at_seconds    1537402548
token                 ya29.c.ElodBmNPwHUNY5gcBpnXcE4ywG4w1k...
token_ttl             3599

Static account:

$ vault read gcp/static-account/my-token-account/token
Key                Value
---                -----
expires_at_seconds    1672231587
token                 ya29.c.b0Aa9VdykAdYoW9S1ImtPZykF_oTi9...
token_ttl             3599

Impersonated account:

$ vault read gcp/impersonated-account/my-token-impersonate/token
Key                Value
---                -----
expires_at_seconds    1671667844
token                 ya29.c.b0AT7lpjBRmO7ghBEyMV18evd016hq...
token_ttl             59m59s

이 엔드포인트는 최대 수명 1시간인 갱신 불가·폐기 불가 정적 OAuth2 access token을 생성해요. 여기서 token_ttl은 초 단위로 주어지고, expires_at_seconds는 Unix 타임스탬프로 주어지는 토큰 만료 시각이에요. 토큰 값은 GCP API 요청에서 HTTP Authorization Bearer 토큰으로 사용할 수 있어요.

$ curl -H "Authorization: Bearer ya29.c...k..."

서비스 계정 키(Service account keys)

서비스 계정 키를 생성하려면 gcp/.../key에서 읽어요. Vault는 서비스 계정 키 데이터를 private_key_data 필드에 base64 인코딩된 문자열로 반환해요. 이 값을 base64 --decode "ewogICJ0e..." 또는 원하는 다른 base64 도구로 디코딩해 읽을 수 있어요. roleset 또는 정적 계정은 service_account_key 타입으로 생성되어 있어야 해요.

$ vault read gcp/roleset/my-key-roleset/key
Key                 Value
---                 -----
lease_id            gcp/key/my-key-roleset/ce563a99-5e55-389b...
lease_duration      30m
lease_renewable     true
key_algorithm       KEY_ALG_RSA_2048
key_type            TYPE_GOOGLE_CREDENTIALS_FILE
private_key_data    ewogICJ0eXBlIjogInNlcnZpY2VfYWNjb3VudCIsC...

이 엔드포인트는 역할의 서비스 계정과 연결된 새 GCP IAM 서비스 계정 키를 생성해요. 리스가 만료되면(또는 조기 폐기되면) 서비스 계정 키가 삭제돼요.

서비스 계정마다 기본적으로 키 10개 제한이 있어요. 이 제한과 권장 대책에 대한 자세한 내용은 아래 '참고할 사항' 섹션을 참고해 주세요.

Bindings(바인딩)

roleset 또는 정적 계정 바인딩은 리소스 목록과 해당 리소스의 연결된 IAM 역할을 정의해요. 바인딩은 roleset이나 정적 계정을 생성하거나 업데이트할 때 bindings 인자로 사용되며, HCL로 다음 형식으로 지정돼요.

resource NAME {
  roles = [ROLE, [ROLE...]]
}

예시:

resource "buckets/my-bucket" {
  roles = [
    "roles/storage.objectAdmin",
    "roles/storage.legacyBucketReader",
  ]
}

# 인스턴스 단위, self-link 사용
resource "https://www.googleapis.com/compute/v1/projects/my-project/zone/my-zone/instances/my-instance" {
  roles = [
    "roles/compute.instanceAdmin.v1"
  ]
}

# 프로젝트 단위
resource "//cloudresourcemanager.googleapis.com/projects/my-project" {
  roles = [
    "roles/compute.instanceAdmin.v1",
    "roles/iam.serviceAccountUser",
    # 서비스 계정으로 실행되는 인스턴스를 관리한다면 필요
  ]
}

# 폴더 단위
resource "//cloudresourcemanager.googleapis.com/folders/123456" {
  roles = [
    "roles/compute.viewer",
    "roles/deploymentmanager.viewer",
  ]
}

최상위 resource 블록은 IAM 정책 정보가 바인딩될 리소스 또는 리소스 경로를 정의해요. 리소스 경로는 몇 가지 다른 형식으로 지정할 수 있어요.

  • 프로젝트 단위 self-link — 스킴과 호스트가 있는 URI로, 일반적으로 GCP 리소스의 self_link 속성에 해당해요. 반드시 상위 프로젝트에 중첩된 리소스를 포함해야 해요. # compute alpha zone https://www.googleapis.com/compute/alpha/projects/my-project/zones/us-central1-c
  • 전체 리소스 이름(Full resource name) — DNS 호환 API 서비스 이름과 리소스 경로로 구성된 스킴 없는 URI. 전체 리소스 이름 API 문서를 참고하세요. # Compute snapshot //compute.googleapis.com/project/my-project/snapshots/my-compute-snapshot, # Pubsub snapshot //pubsub.googleapis.com/project/my-project/snapshots/my-pubsub-snapshot, # BigQuery dataset //bigquery.googleapis.com/projects/my-project/datasets/mydataset, # Resource manager //cloudresourcemanager.googleapis.com/projects/my-project
  • 상대 리소스 이름(Relative resource name) — path-no-scheme URI 경로로, 보통 API에서 받아들여지는 형태. 버전이나 서비스가 리소스 유형에서 분명하다면 이 형식을 사용해요. 상대 리소스 이름 API 문서를 참고하세요. # Storage bucket objects buckets/my-bucket, buckets/my-bucket/objects/my-object, # PubSub topics projects/my-project/topics/my-pubsub-topic

중첩된 roles 속성은 GCP IAM 역할 이름의 문자열 배열이에요. 역할은 다음 형식으로 지정할 수 있어요.

  • 전역 역할 이름(Global role name) — Google Cloud에 내장된 전역 역할. 사용 가능한 전체 목록은 사전 정의된 GCP 역할 목록을 참고하세요. roles/viewer, roles/bigquery.user, roles/billing.admin
  • 조직 수준 사용자 지정 역할(Organization-level custom role) — 조직 소유자가 조직 수준에서 만든 역할. organizations/my-organization/roles/my-custom-role. GCP 사용자 지정 역할 문서를 참고하세요.
  • 프로젝트 수준 사용자 지정 역할(Project-level custom role) — 프로젝트 소유자가 프로젝트별로 만든 역할. projects/my-project/roles/my-custom-role. GCP 사용자 지정 역할 문서를 참고하세요.

인증(Authentication)

Google Cloud Vault 시크릿 백엔드는 공식 Google Cloud Golang SDK를 사용해요. 즉 Google Cloud에 자격 증명을 제공하는 일반적인 방법을 지원해요. Vault 구성으로 직접 자격 증명을 지정하는 것 외에도, Vault 서버에서 다음 값으로 구성을 가져올 수 있어요.

  1. GOOGLE_APPLICATION_CREDENTIALS 환경 변수 — Google Cloud 자격 증명 파일(보통 서비스 계정용)의 경로로 지정돼요. 이 환경 변수가 있으면 그 자격 증명이 사용돼요. 자격 증명이 유효하지 않으면 오류가 반환돼요.
  2. Google Cloud 워크로드의 identity — Vault 서버가 Google Compute Engine이나 Google Kubernetes Engine 같은 Google 워크로드에서 실행 중이면, 워크로드에 연결된 identity가 자동으로 사용돼요. Google Compute Engine에 identity를 구성하려면 attached service accounts를, Google Kubernetes Engine에는 GKE workload identity를 참고하세요.

서비스 계정에 대한 자세한 내용은 Google Cloud Service Accounts 문서를 참고하세요.

이 시크릿 엔진을 사용하려면 서비스 계정이 다음 최소 스코프를 가져야 해요.

https://www.googleapis.com/auth/cloud-platform

필요 권한(Required permissions)

프로젝트 수준에서 roleset을 사용할 때 Vault에 주어지는 자격 증명은 다음 권한을 가져야 해요.

# 서비스 계정 + 키 관리자
iam.serviceAccounts.create
iam.serviceAccounts.delete
iam.serviceAccounts.get
iam.serviceAccounts.list
iam.serviceAccounts.update
iam.serviceAccountKeys.create
iam.serviceAccountKeys.delete
iam.serviceAccountKeys.get
iam.serviceAccountKeys.list

정적 계정이나 가장 계정을 사용할 때는 Vault가 서비스 계정 수준에서 다음 권한을 가져야 해요.

# `access_token` 시크릿과 가장 계정용
iam.serviceAccounts.getAccessToken

# `service_account_keys` 시크릿용
iam.serviceAccountKeys.create
iam.serviceAccountKeys.delete
iam.serviceAccountKeys.get
iam.serviceAccountKeys.list

바인딩과 함께 roleset이나 정적 계정을 사용할 때 Vault는 다음 권한을 가져야 해요.

# IAM 정책 변경
<service>.<resource>.getIamPolicy
<service>.<resource>.setIamPolicy

여기서 <service><resource>는 부여될 권한에 해당해요. 예를 들면:

# 프로젝트
resourcemanager.projects.getIamPolicy
resourcemanager.projects.setIamPolicy

# 모든 compute
compute.*.getIamPolicy
compute.*.setIamPolicy

# BigQuery 데이터셋
bigquery.datasets.get
bigquery.datasets.update

다음 중 하나를 선택하면 돼요.

  • 이 권한을 사용해 사용자 지정 역할을 만들고 프로젝트 수준에서 그 역할을 할당해요.
  • 리소스별 getIamPolicy/setIamPolicy 권한을 얻는 데 필요한 역할 집합을 할당해요. 최소한 Vault가 서비스 계정과 키를 관리할 수 있도록 roles/iam.serviceAccountAdminroles/iam.serviceAccountKeyAdmin을 할당해야 해요.
  • BigQuery는 다른 리소스와 다른 권한이 필요하다는 점을 알아 두세요. BigQuery는 전통적인 IAM 권한 대신 구형 ACL을 사용하기 때문이에요. 데이터셋 접근을 업데이트하려면 Vault가 데이터셋의 메타데이터를 업데이트할 수 있어야 해요.

플러그인 워크로드 아이덴티티 페더레이션(Plugin WIF)

Enterprise 기능 — 이 기능은 Vault Enterprise가 필요해요.

GCP 시크릿 엔진은 플러그인 WIF 워크플로를 지원하며, plugin identity token이라는 identity 소스를 가져요. plugin identity token은 Vault의 플러그인 identity token 발급자가 내부적으로 서명한 JWT예요.

Vault와 GCP 사이에 workload identity federation을 통한 신뢰 관계가 구성돼 있다면, 시크릿 엔진은 자신의 identity token을 작업을 수행하는 데 필요한 단기 access token으로 교환할 수 있어요.

identity token을 access token으로 교환하면 GCP 시크릿 엔진이 민감한 IAM 보안 자격 증명에 대한 명시적 접근을 구성하지 않고도 동작할 수 있어요.

시크릿 엔진이 플러그인 WIF를 사용하도록 구성하려면:

  1. Vault의 openid-configuration과 공개 JWKS API가 GCP에서 네트워크로 접근 가능한지 확인해요. Vault API 노출을 제한해야 한다면 API 프록시·게이트웨이를 사용하거나 --jwk-json-path="JWK-FILE-PATH" 옵션으로 정적 JWKS 파일을 사용해요.
  2. GCP에서 workload identity pool과 provider를 생성해요. provider URL은 /.well-known/openid-configuration 접미사를 뺀 Vault 플러그인 identity token 발급자를 가리켜야 해요. 예: https://host:port/v1/identity/oidc/plugins. plugin identity token의 수신자를 audience로 고유하게 식별해요. identity pool의 기본 audience나 256자 미만의 사용자 지정 값을 쓸 수 있어요.
    • provider URL은 /.well-known/openid-configuration 접미사를 뺀 Vault 플러그인 identity token 발급자를 가리켜야 해요. 예: https://host:port/v1/identity/oidc/plugins.
    • plugin identity token의 수신자를 audience로 고유하게 식별해요. 기본 audience나 256자 미만의 사용자 지정 값을 쓸 수 있어요.
  3. 서비스 계정 가장(impersonation)을 사용해 identity pool에 전용 서비스 계정에 대한 접근을 부여함으로써 GCP에서 워크로드를 인증해요. GCP Auth 엔진이 서비스 계정을 가장할 수 있도록 plugin identity token이 발급한 고유 sub 클레임으로 요청을 필터링해요. sub 클레임의 형태는 plugin-identity:<NAMESPACE_ID>:secret:<GCP_SECRETS_MOUNT_ACCESSOR>이에요.
  4. OIDC audience 값과 서비스 계정 이메일로 GCP 시크릿 엔진을 구성해요.
$ vault write gcp/config \
    identity_token_audience="//iam.googleapis.com/projects/410449834127/locations/global/workloadIdentityPools/vault-gcp-secrets-43777a63/providers/vault-gcp-secrets-wif-provider" \
    service_account_email="vault-plugin-wif-secrets@hc-b712f250b4e04cacbadd258a90b.iam.gserviceaccount.com"

이제 시크릿 엔진이 구성 자격 증명에 플러그인 WIF를 사용할 수 있어요. 기본적으로 WIF 자격 증명은 TTL이 1시간이고 만료되면 자동으로 갱신돼요.

플러그인 WIF와 관련된 필드에 대한 자세한 내용은 API 문서를 참고해 주세요.

루트 자격 증명 회전(Root credential rotation)

마운트가 자격 증명으로 직접 구성된 경우, 자격 증명의 키를 운영자가 접근할 수 없는 Vault 생성 값으로 회전할 수 있어요. 이 작업에 대한 자세한 내용은 Root Credential Rotation API 문서를 참고해 주세요.

예약 기반 루트 자격 증명 회전(Schedule-based root credential rotation)

Enterprise 기능 — 적절한 Vault Enterprise 라이선스 필요.

rotation_schedule 필드를 사용하면 GCP 시크릿 엔진에서 루트 자격 증명의 예약 기반 자동 회전을 구성할 수 있어요. 예를 들어 다음 명령은 매주 토요일 자정(00:00)에 회전이 일어나도록 설정해요.

$ vault write gcp/config/client \
  ...
  rotation_schedule="0 * * * SAT"
  ...

예약된 루트 자격 증명 회전은 회전이 일어나도록 허용되는 기간인 rotation_window도 설정할 수 있어요. Vault는 윈도우가 만료되면 자격 증명 회전 시도를 중단해요. 예를 들어 다음 명령은 토요일 자정에 회전하되 1시간 범위 안에서만 회전하라고 지시해요. 어떤 이유로든 1:00까지 회전하지 못하면 Vault는 다음 예약 회전 때까지 회전 시도를 중단해요.

$ vault write gcp/config/client \
  ...
  rotation_window="1h" \
  rotation_schedule="0 * * * SAT"
  ...

disable_automated_rotationtrue로 설정하면 루트 회전을 일시적으로 비활성화할 수 있어요. disable_automated_rotation 필드를 설정하면 필드가 false로 재설정될 때까지 루트 자격 증명의 어떤 회전도 막아요. rotation_period를 쓰는 경우 disable_automated_rotation을 설정하면 자격 증명 TTL도 재설정돼요.

GCP 시크릿 엔진의 루트 자격 증명 회전에 대한 자세한 내용은 Rotate Root credentials API 문서를 참고해 주세요.

참고할 사항(Things to note)

Rolesets vs. 정적 계정(static accounts)

roleset의 장점:

  • 서비스 계정과 IAM 바인딩을 Vault가 완전히 관리해요.

roleset의 단점:

  • Vault에서 관리하는 IAM 바인딩과 쉽게 분리(de-couple)할 수 없어요.
  • Vault에 IAM 바인딩과 서비스 계정을 관리할 권한이 필요해요.

정적 계정의 장점:

  • Vault에서 관리하는 것과 별개로 IAM 바인딩을 관리할 수 있어요.
  • Vault에 IAM 바인딩과 서비스 계정 권한이 필요 없고, 서비스 계정 키와 관련된 권한만 필요해요.

정적 계정의 단점:

  • 서비스 계정을 스스로 관리해야 해요.

Access tokens vs. 서비스 계정 키(service account keys)

access_token의 장점:

  • roleset당 무제한 토큰을 생성할 수 있어요.

access_token의 단점:

  • 일부 클라이언트 라이브러리나 도구에서 사용할 수 없어요.
  • 수명이 1시간으로 고정이라 수정·폐기·연장이 안 돼요.

service_account_keys의 장점:

  • Vault를 통해 수명을 제어할 수 있어서 더 긴 접근을 허용해요.
  • 모든 일반 GCP 도구에서 사용할 수 있어요.

service_account_keys의 단점:

  • GCP에서 무한 수명이에요(즉 제대로 관리하지 않으면 유출된 키가 영원히 살 수 있어요).
  • roleset/서비스 계정당 10개로 제한돼요.

OAuth access token을 생성할 때도 Vault는 전용 서비스 계정과 키를 생성해요. 이 개인 키는 Vault에 저장되고 다른 사용자가 절대 접근할 수 없으며, 기반 키는 회전할 수 있어요. 회전에 대한 자세한 내용은 GCP API 문서를 참고해 주세요.

서비스 계정은 roleset에 묶여 있어요

서비스 계정은 시크릿이 생성될 때마다가 아니라 roleset이 생성(또는 업데이트)될 때 생성돼요. 이는 다른 시크릿 엔진과 다를 수 있지만, 그럴 만한 이유가 있어요.

  • IAM 서비스 계정 생성과 권한 전파는 완료까지 최대 60초가 걸릴 수 있어요. 서비스 계정을 미리 만들어 두면 이후 작업의 시의성을 높이고 자동화 워크플로의 불안정성을 줄여요.
  • 각 GCP 프로젝트에는 IAM 서비스 계정 수 제한이 있어요. 추가 할당량을 요청할 수 있어요. 할당량 증가는 사람이 처리하므로 미리 요청하는 게 좋아요. 이 제한은 현재 시스템 관리 서비스 계정을 포함해 100개예요. 시크릿마다 서비스 계정을 만든다면 이 할당량 제한 때문에 생성할 수 있는 시크릿 수가 줄어들 거예요.

서비스 계정 키 할당량 제한

GCP IAM에는 서비스 계정 키 수에 하드 제한(현재 10)이 있어요. 그 이상 키를 생성하려 하면 오류가 나요. 이 제한에 부딪힌다면 다음을 고려해 보세요.

  • TTL을 더 짧게 하거나 접근을 더 일찍 폐기해요. 이전 서비스 계정 키를 쓰지 않는다면 더 일찍 회전하고 할당량을 확보해요.
  • 같은 권한 집합을 공유하는 추가 roleset을 만들어요. 같은 권한 집합으로 추가 roleset을 만들면 새 서비스 계정이 생겨 만들 수 있는 키 수가 늘어나요.
  • 가능하면 서비스 계정 키 대신 OAuth2 access token을 사용해요.

IAM 바인딩의 리소스는 roleset/정적 계정 생성 시 존재해야 해요

서비스 계정의 바인딩은 roleset/정적 계정 생성 중에 설정되므로, 존재하지 않는 리소스는 getIamPolicy API 호출을 실패시켜요.

Roleset 생성은 부분적으로 실패할 수 있어요

서비스 계정 생성·키 생성·IAM 정책 변경은 각각 리소스당 하나의 GCP API 호출이에요. 이 리소스 중 하나에 대한 API 호출이 실패하면 roleset 생성이 실패하고 Vault는 롤백을 시도해요. 이 롤백도 API 호출이라 역시 실패할 수 있어요. 시크릿 엔진은 사용되지 않는 바인딩이 정리되도록 WAL을 사용해요. 할당량 제한의 경우 수동으로 정리해야 할 수도 있어요.

Vault 소유 IAM 계정을 수정하지 마세요

Vault가 처음에 IAM 서비스 계정을 만들고 권한을 할당하지만, 외부 사용자가 이 서비스 계정을 삭제하거나 수정할 수 있어요. 이런 변경은 감지하기 어려우며, IAM 권한을 통해 이런 유형의 수정을 막는 게 가장 좋아요.

Vault roleset 서비스 계정의 이메일은 다음 형식이에요.

vault<roleset-prefix>-<creation-unix-timestamp>@...

팀과 소통하거나 IAM 권한을 사용해 이 리소스를 수정하지 않도록 해주세요.

도움말 및 지원(Help & support)

Google Cloud Vault 시크릿 엔진은 외부 Vault 플러그인으로 작성됐고, 따라서 메인 Vault 저장소 밖에 있어요. Vault 릴리스에 자동으로 번들되지만 코드는 별도로 관리돼요.

이슈 보고, 기능 요청, 기여는 GitHub의 vault-plugin-secrets-gcp 저장소로 해주세요.

API

GCP 시크릿 엔진은 완전한 HTTP API를 갖고 있어요. 자세한 내용은 GCP 시크릿 엔진 API 문서를 참고해 주세요.

Terraform

Vault Terraform 공급자로 GCP 시크릿 리소스를 프로그래밍 방식으로 관리할 수 있어요. 자세한 내용은 Terraform Registry 문서를 참고해 주세요.

  • GCP 시크릿 엔진 백엔드 리소스
  • GCP 시크릿 엔진 roleset 리소스
  • GCP 시크릿 엔진 정적 계정 리소스
  • GCP 시크릿 엔진 가장 계정 리소스

업그레이드 가이드(Upgrade guides)

Access token 리스 폐기(Deprecation of access token leases)

참고: 이 폐기는 access token에만 영향을 줘요. service_account_key 시크릿 유형에는 변화가 없어요.

이 시크릿 엔진의 이전 버전(Vault ≤ 0.11.1)은 access token 시크릿마다 리스를 생성했어요. 그런데 이 토큰, 특히 IAM 서비스 계정용 Google OAuth2 토큰은 폐기가 불가능하고 수명이 60분으로 고정돼 있다는 것을 발견한 뒤 리스를 제거했어요. GCP API의 현재 제한과 맞추기 위해 시크릿 엔진은 더 이상 폐기를 허용하지 않거나 토큰 TTL을 관리하지 않을 거예요 — 더 구체적으로는 access_token 응답에 더 이상 lease_id나 다른 리스 정보가 포함되지 않아요. 이 변화는 실제 기본 OAuth 토큰이나 GCP 서비스 계정의 어떤 변화를 반영한 게 아니에요.

업그레이드하려면:

  • access token 시크릿 엔드포인트(즉 gcp/token/$roleset)의 응답을 읽을 때 lease_id, lease_duration 또는 다른 lease_* 속성에 대한 참조를 제거해요. 응답의 새 형식은 access tokens 문서를 참고하세요.
  • 이전 버전의 남은 리스에 주의해요. 이전 리스는 여전히 폐기 가능하지만 실제로는 연결된 access token을 무효화하지 않으며, 그 토큰은 최대 1시간 동안 계속 사용할 수 있어요.

더 알아보기 (Learn more)

  • GCP 시크릿 엔진 API 문서에서 HTTP API 전체를 확인해 보세요.
  • 업그레이드 가이드에서 access token 리스 변경 사항을 살펴보세요.
  • GitHub vault-plugin-secrets-gcp 저장소에 이슈나 기여를 남겨 보세요.