Secret Manager
Secret Manager is a secure, centralized service for managing API keys, passwords, certificates, and other sensitive data. It provides versioning, automatic rotation, IAM-based access control, and audit logging.
How Secret Manager Works
Secret Manager:
┌──────────────┐ ┌──────────────────┐ ┌──────────────┐
│ DevOps Team │───▶│ Secret Manager │◀───│ Cloud Run │
│ (create) │ │ │ │ (access) │
│ │ │ my-db-password │ ├──────────────┤
│ │ │ ├── v1 (disabled) │ │ GKE │
│ │ │ ├── v2 (enabled) │ │ (access) │
│ │ │ └── v3 (latest) │ ├──────────────┤
│ │ │ │ │ Cloud │
│ │ │ Encrypted at rest │ │ Functions │
│ │ │ IAM-controlled │ │ (access) │
└──────────────┘ └──────────────────┘ └──────────────┘
Create and Manage Secrets
# Create a secret
$ gcloud secrets create my-db-password \
--replication-policy="automatic"
# Add a secret version (the actual value)
$ echo -n "SuperS3cret!" | gcloud secrets versions add my-db-password --data-file=-
# Create secret with value in one step
$ printf "my-api-key-value" | gcloud secrets create my-api-key \
--replication-policy="automatic" \
--data-file=-
# List secrets
$ gcloud secrets list
# Output:
# NAME CREATED REPLICATION_POLICY
# my-db-password 2026-03-30T07:00:00 automatic
# my-api-key 2026-03-30T07:01:00 automatic
Secret Versions
# Add a new version (rotates the secret)
$ echo -n "NewP@ssw0rd!" | gcloud secrets versions add my-db-password --data-file=-
# List versions
$ gcloud secrets versions list my-db-password
# Output:
# NAME STATE CREATED
# 2 enabled 2026-03-30T07:05:00Z
# 1 enabled 2026-03-30T07:00:00Z
# Access the latest version
$ gcloud secrets versions access latest --secret=my-db-password
# NewP@ssw0rd!
# Access a specific version
$ gcloud secrets versions access 1 --secret=my-db-password
# SuperS3cret!
# Disable an old version
$ gcloud secrets versions disable 1 --secret=my-db-password
# Destroy a version (permanent)
$ gcloud secrets versions destroy 1 --secret=my-db-password
Regional Replication
# Automatic replication (Google manages)
$ gcloud secrets create auto-secret \
--replication-policy="automatic"
# User-managed replication (specific regions)
$ gcloud secrets create regional-secret \
--replication-policy="user-managed" \
--locations="us-central1,us-east1"
IAM Access Control
# Grant a service account access to a secret
$ gcloud secrets add-iam-policy-binding my-db-password \
--member="serviceAccount:my-app@my-project.iam.gserviceaccount.com" \
--role="roles/secretmanager.secretAccessor"
# View who has access
$ gcloud secrets get-iam-policy my-db-password
| Role |
Permissions |
roles/secretmanager.secretAccessor |
Access secret versions |
roles/secretmanager.viewer |
View secret metadata (not values) |
roles/secretmanager.admin |
Full management |
roles/secretmanager.secretVersionManager |
Add/disable/destroy versions |
Secret Rotation
# Set a rotation schedule
$ gcloud secrets update my-db-password \
--next-rotation-time="2026-04-30T00:00:00Z" \
--rotation-period="2592000s"
# Rotation sends a Pub/Sub notification
# Create a topic for rotation events
$ gcloud pubsub topics create secret-rotation
# Configure the secret to notify on rotation
$ gcloud secrets update my-db-password \
--topics="projects/my-project/topics/secret-rotation"
Labels and Organization
# Add labels
$ gcloud secrets update my-db-password \
--update-labels=env=production,team=backend
# Filter secrets by label
$ gcloud secrets list --filter="labels.env=production"
Access Secrets from Code
from google.cloud import secretmanager
client = secretmanager.SecretManagerServiceClient()
# Access the latest version
name = "projects/my-project/secrets/my-db-password/versions/latest"
response = client.access_secret_version(request={"name": name})
secret_value = response.payload.data.decode("UTF-8")
print(f"Secret: {secret_value}")
Common Mistakes
| Mistake |
Why It’s Wrong |
Fix |
| Secrets in env vars / code |
Exposed in logs, repos |
Use Secret Manager |
| Too broad IAM roles |
Over-permissioned access |
Grant secretAccessor only |
| No version rotation |
Stale credentials |
Set rotation schedule |
| Not disabling old versions |
Old creds remain valid |
Disable after rotation |
| No audit logging |
Can’t track access |
Enable Data Access audit logs |
Quick Reference
| Command |
Description |
gcloud secrets create NAME |
Create a secret |
gcloud secrets versions add NAME |
Add a version |
gcloud secrets versions access latest |
Read latest value |
gcloud secrets versions disable VERSION |
Disable a version |
gcloud secrets add-iam-policy-binding |
Grant access |
gcloud secrets list |
List secrets |
Next → Accessing Secrets