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.
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.
End-to-end flow from issue to auto-revoke
Key API paths to remember
sys/mounts # enabling engines
gcp/config # GCP admin credentials
gcp/roleset/<name> # the issuing policy (roleset)
gcp/key/<roleset-name> # dynamically issued service account keys
#gcp/token/<roleset-name> # access_token (for reference)
#gcp/id-token/<roleset-name> # id_token (for reference)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.
Concrete least-privilege examples (GCP and Vault)
# GCP: give the Vault admin SA key-management rights over the target SA
# Substitute: [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: a minimal policy that only lets the app issue keys
# Substitute: the roleset name is ci-builder
path "gcp/key/ci-builder" {
capabilities = ["read"]
}
# Keep operational reads such as mount info in a separate policy1) 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.
End-to-end example (Vault CLI)
# 1) Enable the engine (at the path gcp)
vault secrets enable -path=gcp gcp
# 2) Configure the GCP admin credentials (store the JSON safely)
vault write gcp/config [email protected]
# 3) Create the roleset (issues service account keys)
# Substitute PROJECT_ID, SA_EMAIL and TTL to match your requirements
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) Issue a key (with a lease)
# The output contains the lease_id and the key material (the key is JSON)
vault read -format=json gcp/key/ci-builder > key.json
# Extract private_key from the JSON and pass it to your tooling if neededEvery 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.
Common operations (immediate revoke and renew)
# Use the lease_id from when you issued it (example)
LEASE_ID="gcp/key/ci-builder/abcd-efgh-..."
# Revoke immediately (deletes the key straight away)
vault lease revoke "$LEASE_ID"
# Extend the TTL (where allowed)
vault lease renew "$LEASE_ID"
# Force-revoke every lease under a roleset (high impact, be careful)
vault lease revoke -prefix gcp/key/ci-builderVault'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.
| Secret Type | Typical Lifetime | Revoke / Expiration | Primary Use Cases |
|---|---|---|---|
| service_account_key | Minutes to hours (keep it short) | Vault calls the delete-key API; manual deletion also works | Tools that require a JSON key, legacy compatibility, batch jobs |
| access_token | About 1 hour (Google default) | Auto-invalidated on expiry; explicit revocation is usually unnecessary | Short-lived API calls; preferred when avoiding key distribution |
| id_token | Minutes to 1 hour | Auto-invalidated on expiry | Authenticating to OIDC-aware services that verify the JWT |
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.
Concrete examples for auditing and health checks
# Send the Vault audit log to a file (mind the permissions and where it is kept)
vault audit enable file file_path=/var/log/vault_audit.log
# GCP: check for leftover keys and remove them by hand
gcloud iam service-accounts keys list \
[email protected]
gcloud iam service-accounts keys delete KEY_ID \
[email protected]Associate / Ops
Question 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?
Correct answer: 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.
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.
Practice with certification-focused question sets
Try free questionsNicheeLab Editorial Team
NicheeLab editorial team focused on data engineering and cloud certification learning. Content is structured around practical study needs and official exam domains.
Vault Core Concepts: Sealed/Unsealed, Auth, Secrets (2026)
Vault fundamentals — sealed/unsealed state, auth methods, se...
Vault Operations Professional (VOP-003): Complete Guide (2026)
Pass the Vault Operations Professional exam — enterprise pat...
Vault Path-Based Routing: API URL Structure (2026)
How Vault's path-based routing works — mount points, sub-pat...
Vault Tokens: Auth Token Mechanics (2026)
Token fundamentals — service vs. batch tokens, accessor, ren...
Vault Token Types: Service, Batch, Periodic (2026)
Service vs. batch tokens compared — performance, ACL behavio...