Vault

Vault GCP Secrets Engine: Automating Short-Lived Service Account Keys

2026-04-19
NicheeLab Editorial Team

The core use case for Vault's GCP secrets engine is replacing long-lived JSON keys with short-lived, per-job service account keys that are issued and revoked automatically.

This article focuses on stable, documented behavior and covers least privilege, TTLs and leases, revocation, choosing between secret types, and operational pitfalls — useful both in production and on the exam.

How It Works and What the Exam Tests

The GCP secrets engine uses an admin credential held by Vault to call the GCP IAM API, create a service account key on the fly, and return it to the client. A lease is attached at issue time, and when the TTL expires or the client revokes the lease, Vault calls the same API to delete the key. This eliminates long-lived shared keys and reduces both leak risk and audit overhead.

Unlike a static secret stored in KV, a key issued by the GCP secrets engine is a dynamic secret: generated on demand and invalidated when its TTL expires. The engine can also issue OAuth2 access_tokens and id_tokens, but this article focuses on the service account key flow.

  • Minimize credential distribution: keys are issued only when needed and expire automatically via TTL
  • Auditable: both the Vault audit log and the GCP audit log capture issue and revoke events
  • Exam hotspots: the roleset's secret_type, TTL vs max_ttl, lease revoke behavior, and the GCP key limit (max 10 keys per service account)

End-to-end flow from issue to auto-revoke

ClientVaultGCP IAMrequest keycreate serviceAccountKeykey + leasekey + leaseuse key (until TTL)delete serviceAccountKeylease expire / revokeAudit: Vault audit log / GCP Admin Activity log

Key API paths to remember

sys/mounts                     # エンジンの有効化
gcp/config                      # GCP 管理用クレデンシャル設定
gcp/roleset/<name>              # 発行ポリシー(ロールセット)
gcp/key/<roleset-name>         # サービスアカウント鍵の動的発行
#gcp/token/<roleset-name>      # access_token(参考)
#gcp/id-token/<roleset-name>   # id_token(参考)

Prerequisites and Least-Privilege Design (GCP and Vault)

For Vault to create and delete keys, you need an admin-side service account (hereafter the Vault admin SA) with least-privilege access to the target service account. Creating and deleting keys requires roles/iam.serviceAccountKeyAdmin. Issuing access_tokens additionally requires roles/iam.serviceAccountTokenCreator. As a rule, scope these grants to the individual target service account — never to the project, folder, or organization.

On the Vault side, grant applications only read access to the gcp/key/<roleset> issue path. Avoid write and list to keep the leak surface as small as possible.

  • GCP: roles/iam.serviceAccountKeyAdmin for key create/delete, plus roles/iam.serviceAccountTokenCreator if you also issue tokens
  • Constrain the scope to the target service account by binding the policy at the SA resource level
  • Vault policy grants read only on the issue path; administrative operations live in a separate role

Concrete least-privilege examples (GCP and Vault)

# GCP: Vault 管理 SA に対して、対象 SA の鍵管理権限を付与
# 置換: [email protected], [email protected]
#gcloud
gcloud iam service-accounts add-iam-policy-binding "SA_EMAIL" \
  --member="serviceAccount:VAULT_ADMIN_SA" \
  --role="roles/iam.serviceAccountKeyAdmin"

# Vault: アプリに鍵発行のみ許可する最小ポリシー
# 置換: ROLESET 名は ci-builder
path "gcp/key/ci-builder" {
  capabilities = ["read"]
}
# mount 情報の参照など運用系は別ポリシーに分離

Setup Steps: Enable, Configure, Create a Roleset, Issue a Key

1) Enable the engine and register the Vault admin SA's JSON credential. 2) Create a roleset for service account keys. 3) Clients read gcp/key/<roleset> to obtain a key. The key is returned with a lease attached, and Vault deletes it when the TTL expires or the lease is revoked.

Set the roleset's secret_type to service_account_key. Specify the target service account and the TTL/max_ttl at the roleset level, and keep them consistent with the mount-level TTL.

  • The roleset names the target SA explicitly; the key's effective permissions come from the IAM bindings already attached to that SA — the roleset itself does not grant them
  • Prefer streaming the key into downstream tooling via stdin rather than writing to disk; if a file is unavoidable, use a temp file with tight permissions
  • Keep TTLs short — a typical target is the build/deploy job duration plus a few minutes of buffer

End-to-end example (Vault CLI)

# 1) エンジン有効化(任意パス gcp)
vault secrets enable -path=gcp gcp

# 2) GCP 管理用クレデンシャルを設定(JSON を安全に保管)
vault write gcp/config [email protected]

# 3) roleset 作成(サービスアカウント鍵を発行)
# 置換: PROJECT_ID, SA_EMAIL, TTL は要件に合わせる
vault write gcp/roleset/ci-builder \
  project="PROJECT_ID" \
  secret_type="service_account_key" \
  service_account_email="SA_EMAIL" \
  ttl="1h" max_ttl="24h"

# 4) 鍵を発行(lease 付き)
# 出力には lease_id と鍵素材が含まれる(鍵は JSON 形式)
vault read -format=json gcp/key/ci-builder > key.json

# 必要に応じて、JSON から private_key を抽出してツールへ渡すなどの処理を行う

Leases, TTLs, and Revocation: How Auto-Revoke Actually Works

Every dynamic secret carries a lease. The client holds the lease_id and can renew or revoke it as needed. When the TTL expires, Vault calls the GCP IAM delete-key API to invalidate the key — that call is the core of auto-revocation. If renewal is enabled, lease renew extends only the expiration time; the key material itself stays the same.

If revocation fails — due to a network outage or a permission change, for example — Vault's revocation queue retries automatically. When failures persist for a long time, an operator must revoke manually, either in Vault or by deleting the key directly in GCP. For the exam, remember two key facts: lease revoke lets you invalidate a key immediately, and renewal cannot extend a lease beyond max_ttl.

  • Both TTL and max_ttl are constrained at the roleset level and the mount level
  • Renew does not rotate the key material; rotating the material requires issuing a new key
  • There is a hard ceiling of 10 keys per service account — avoid long-lived leases and over-issuance

Common operations (immediate revoke and renew)

# 取得時の lease_id を使用(例)
LEASE_ID="gcp/key/ci-builder/abcd-efgh-..."

# 即時撤回(鍵を即座に削除)
vault lease revoke "$LEASE_ID"

# TTL 延長(許可されている場合)
vault lease renew "$LEASE_ID"

# 役割(roleset)配下の全リースを強制失効させる場合(影響大に注意)
vault lease revoke -prefix gcp/key/ci-builder

Which Should You Use: Key vs Access Token vs ID Token

Vault's GCP secrets engine can issue service account keys (JSON), access_tokens, and id_tokens. JSON keys offer the broadest compatibility but require distributing private key material. Tokens are short-lived and far less risky to hand around, so the modern default is to prefer tokens. Reach for dynamically issued keys with a very short TTL only when an existing tool requires a JSON key.

Inside GCE or GKE, combining Vault with Workload Identity or runtime metadata-based tokens is also a solid pattern. For the exam, be ready to justify why you picked a given secret_type for a given workload.

  • Keys exist for legacy compatibility; tokens carry far less distribution risk and are easier to operate with least privilege
  • Use access_tokens for short CI/CD jobs; fall back to keys only when an external tool forces you to
  • Use id_tokens for authentication to services that expect OIDC/JWT on the receiving end
Secret TypeTypical LifetimeRevoke / ExpirationPrimary Use Cases
service_account_keyMinutes to hours (keep it short)Vault calls the delete-key API; manual deletion also worksTools that require a JSON key, legacy compatibility, batch jobs
access_tokenAbout 1 hour (Google default)Auto-invalidated on expiry; explicit revocation is usually unnecessaryShort-lived API calls; preferred when avoiding key distribution
id_tokenMinutes to 1 hourAuto-invalidated on expiryAuthenticating to OIDC-aware services that verify the JWT

Operations and Troubleshooting: Auditing, Limits, Incident Response

Auditing: enable a Vault audit device to preserve issue and revoke metadata. GCP also records key creation and deletion in the Admin Activity log. Cross-referencing the two logs gives you the strongest traceability.

Limits and rates: each service account is capped at 10 keys. Keep TTLs short, revoke aggressively, and balance job concurrency against the key budget. Plan for keys to linger briefly when revocation fails.

Incident response: when revocations pile up because of a network outage or a permission change, retry lease revoke and fall back to manual deletion in GCP if needed. From a DR standpoint, it is practical to keep the TTL below your acceptable failure window.

  • Stream issued credentials downstream via stdout and avoid writing to disk wherever possible
  • Use response wrapping to wrap the secret in a temporary token and unwrap only at consumption time
  • In CI environments, handle the secret in a tmpfs scratch directory with the tightest possible permissions

Concrete examples for auditing and health checks

# Vault 監査をファイルに出力(権限と保管に注意)
vault audit enable file file_path=/var/log/vault_audit.log

# GCP: 残存鍵の確認と手動削除
gcloud iam service-accounts keys list \
  [email protected]

gcloud iam service-accounts keys delete KEY_ID \
  [email protected]

Check Your Understanding

Associate / Ops

問題 1

You want Vault's GCP secrets engine to issue a short-lived GCP service account key per CI job and delete it automatically when the TTL expires. Which configuration is most appropriate?

  1. Set secret_type to service_account_key on a gcp/roleset, specify the target service account, and have the client read gcp/key/<roleset>
  2. Store the JSON key in the KV engine; read it at job start and delete it at job end
  3. Encrypt the key with the transit engine, store it in GCS, and decrypt it when needed
  4. Issue access_tokens from a gcp/roleset and convert them to JSON keys when needed

正解: A

Service account keys as dynamic secrets are issued by setting secret_type=service_account_key on a roleset and reading from gcp/key/<roleset>. KV stores static secrets and does not auto-expire them, transit is an encryption-as-a-service engine, and access_tokens cannot be converted into JSON keys.

Frequently Asked Questions

What GCP permissions does the Vault admin service account need?

Issuing and deleting service account keys requires roles/iam.serviceAccountKeyAdmin. If you also issue access_tokens, grant roles/iam.serviceAccountTokenCreator as well. Scope these permissions to the target service account only, never to the project or organization.

Keys are not deleted after the TTL expires. How do I diagnose and fix this?

Check Vault's revoke queue in the server and audit logs, plus GCP's Admin Activity log. Run lease revoke manually in Vault, and if that still does not clear the key, delete it manually on GCP. Also look for network outages or recent IAM permission changes that may have blocked the revoke API call.

Can I provision this with Terraform?

Yes. Use the Vault Provider's vault_gcp_secret_backend resource for the engine and vault_gcp_secret_roleset for rolesets. Make sure secrets do not leak into Terraform state, and keep the roleset TTL aligned with the mount-level TTL.

Check what you learned with practice questions

Practice with certification-focused question sets

無料で問題を解いてみる
Author

NicheeLab Editorial Team

NicheeLab editorial team focused on data engineering and cloud certification learning. Content is structured around practical study needs and official exam domains.


Related articles
Vault

Vault Core Concepts: Sealed/Unsealed, Auth, Secrets (2026)

Vault fundamentals — sealed/unsealed state, auth methods, se...

Vault

Vault Operations Professional (VOP-003): Complete Guide (2026)

Pass the Vault Operations Professional exam — enterprise pat...

Vault

Vault Path-Based Routing: API URL Structure (2026)

How Vault's path-based routing works — mount points, sub-pat...

Vault

Vault Tokens: Auth Token Mechanics (2026)

Token fundamentals — service vs. batch tokens, accessor, ren...

Vault

Vault Token Types: Service, Batch, Periodic (2026)

Service vs. batch tokens compared — performance, ACL behavio...

Browse all Vault articles (101)
© 2026 NicheeLab All rights reserved.