Secret Manager from Cloud Shell: store a key, rotate it, then retire the old version
Stop pasting API keys into code and config files. Create a secret, read it back, add a new version, disable and destroy the old one, and delete everything at the end, all inside the free tier.
Secret Manager, in plain words
Secret Manager is a locked drawer for the small, sensitive strings your apps need: API keys, database passwords, OAuth client secrets, TLS keys. Instead of baking them into source code or an environment file, you store them once in Google Cloud and let only the identities that need them read them. Everything is encrypted in transit and at rest by default, and you can bring your own Cloud KMS key (CMEK) if your rules demand it.
Two ideas carry most of the service. A secret is the named container that holds labels, replication settings and IAM permissions. A secret version holds the actual bytes (up to 64 KiB) and is numbered 1, 2, 3 and so on. Rotating a key means adding a new version, not editing the old one. Each version can be enabled, disabled (reads fail, but you can switch it back on) or destroyed (the data is gone for good). The alias latest always points at the newest version, which is handy in a lab but risky in production, where Google advises pinning a version number.
Pricing is by active version and by read. The free tier covers 6 active versions, 10,000 access operations and 3 rotation notifications per month for each billing account. Beyond that, an active version costs about $0.06 a month and reads cost $0.03 per 10,000. Enabled and disabled versions both count as active; destroyed ones are free, and creating or changing secrets costs nothing. Automatic replication is billed as one location; user-managed replication is billed once per region you pick. There were no Secret Manager release notes in the last two weeks; the most recent entries, from August and September 2026, were about Parameter Manager, its companion service for plain configuration values.
Reach for it when
- A Cloud Run service or job needs a database password or third-party API key; mount it with
--set-secretsinstead of writing it into the container image or a plain environment variable. - Several apps or teammates share one credential and you want a single place to rotate it, with IAM deciding exactly who can read it and audit logs showing who did.
- You need to retire a leaked key quickly: add a new version, switch apps over, then disable the old one so any lingering reads fail loudly.
Skip it when
- The value is ordinary configuration such as a feature flag or a region name; Parameter Manager (or a normal config file) fits better and keeps secrets and settings apart.
- You want Google Cloud identities to call Google Cloud APIs; use service accounts and IAM roles directly rather than storing keys, and never create downloadable service account keys just to stash them here.
- The data is larger than 64 KiB, such as a certificate bundle with big files or a dataset; keep it in Cloud Storage with tight IAM, optionally encrypted with Cloud KMS.
The AI angle
AI apps are full of keys: a third-party model API key, a vector database password, an OAuth client for a tool your agent calls. The Gemini Enterprise Agent Platform (formerly Vertex AI) docs for deployed agents on Agent Runtime say API keys and OAuth client secrets are kept in Secret Manager at the project level, where several agents can share them and labels can tag which agent uses which. Calls to Google's own models from inside Google Cloud should use a service account and IAM (for example roles/aiplatform.user) rather than a stored key, so reserve Secret Manager for credentials Google Cloud cannot issue for you.
Hands-on lab: Store, rotate and retire a practice secret
Create a secret holding a random practice value, read it back, add a second version, disable and destroy the first, inspect who can read it, then delete the secret.
Before you start
- A sandbox Google Cloud project you own (shown here as YOUR_PROJECT_ID) with billing linked.
- Cloud Shell, or any terminal with the gcloud CLI signed in as a user who can enable APIs and administer secrets (Secret Manager Admin,
roles/secretmanager.admin; a project Owner has it). - The value used here is random practice data. Do not put a real password or key in a lab project.
Point gcloud at your project and enable the API
Open Cloud Shell, set the project, pick a secret name and turn on the Secret Manager API. Enabling it is free.
gcloud config set project YOUR_PROJECT_ID export SECRET_ID="sandbox-lab-secret" gcloud services enable secretmanager.googleapis.comCreate the secret with a random first version
--data-file=-reads the value from standard input, so the value never appears in your command line or shell history.openssl randmakes a fake 32-character key, andtr -dstrips the trailing newline so it is not stored as part of the value. With no replication flags the secret uses automatic replication, billed as one location.openssl rand -hex 16 | tr -d '\n' | gcloud secrets create "$SECRET_ID" \ --data-file=- --labels=purpose=sandbox-lab gcloud secrets describe "$SECRET_ID"Read it back
Read version 1 by number and again through the
latestalias; both print the same value because only one version exists. Output goes to the terminal as text, which is fine for this hex string; for binary secrets the reference suggests--out-fileinstead.gcloud secrets versions access 1 --secret="$SECRET_ID"; echo gcloud secrets versions access latest --secret="$SECRET_ID"; echoRotate: add a second version
Adding a version is how you rotate. Afterwards
latestpoints at version 2, while version 1 still works until you switch it off. List the versions to see both, with their state.openssl rand -hex 16 | tr -d '\n' | gcloud secrets versions add "$SECRET_ID" --data-file=- gcloud secrets versions access latest --secret="$SECRET_ID"; echo gcloud secrets versions list "$SECRET_ID"Disable, then destroy the old version
Disabling is the safe first move: reads of version 1 now fail with an error, but you could re-enable it if an app breaks. Once you are sure, destroy it; that is permanent, and destroyed versions stop counting toward billing. Finally, look at the secret's IAM policy. It is empty, which means only project-level roles such as Owner can read it; in real use you would grant
roles/secretmanager.secretAccessoron this one secret to the app's service account.gcloud secrets versions disable 1 --secret="$SECRET_ID" gcloud secrets versions access 1 --secret="$SECRET_ID" # expect an error gcloud secrets versions destroy 1 --secret="$SECRET_ID" --quiet gcloud secrets versions list "$SECRET_ID" gcloud secrets get-iam-policy "$SECRET_ID"
Check that it worked
The two reads in step 3 print the same 32-character hex string; after step 4, latest prints a different string; in step 5 the read of version 1 fails once it is disabled, and the final list shows version 2 as enabled and version 1 as destroyed.
Clean up
Delete the secret. This destroys every remaining version and cannot be undone, so check the name first. Then confirm it is gone. Leave the Secret Manager API on if anything else in the project uses it; if this is a practice-only project with no other secrets, you can disable it, or delete the whole practice project instead.
gcloud secrets delete "$SECRET_ID" --quiet
# Confirm: this should print nothing
gcloud secrets list --filter="name:$SECRET_ID"
# Optional, practice-only project with no other secrets:
# gcloud services disable secretmanager.googleapis.com
unset SECRET_IDGotchas
- Disabled versions still count as active and are billed; only destroyed versions are free. Disable first to test, then destroy what you no longer need.
echo "value"adds a newline that becomes part of the stored secret and can break logins; useprintf,echo -n, or strip it as this lab does.- Avoid
latestin production. A Cloud Run environment variable reads the secret only when an instance starts, so Google recommends pinning a version number there; a mounted volume reads it on each file read. - IAM can be granted on a secret but not on a single version, so anyone with access to a secret can read every enabled version of it.
- User-managed replication bills each chosen region separately: 5 versions in 3 regions count as 15 active versions.