GCP Secret Manager’s automatic rotation is less about secrets "rotating" themselves and more about a controlled, scheduled replacement of a secret’s value with a newly generated one.
Here’s a secret in action, being accessed by a hypothetical application:
{
"data": "ewogICAgIm5hbWUiOiAiYXBwbGljYXRpb24iLAogICAgInZlcnNpb24iOiAiMS4wIgp9",
"version_number": 1,
"create_time": "2023-10-27T10:00:00Z",
"user_managed": true,
"destroy_time": null
}
When an application needs this secret, it makes an API call to Secret Manager:
curl -H "Authorization: Bearer $(gcloud auth print-access-token)" \ https://secretmanager.googleapis.com/v1/projects/my-gcp-project/secrets/my-api-key/versions/latest
The response will contain the latest enabled version of the secret. If a new version has been created and enabled, the application automatically gets that one.
The core problem Secret Manager’s rotation solves is the operational burden and security risk of manually updating secrets. Imagine thousands of database passwords, API keys, or TLS certificates. Manually rotating these is error-prone, time-consuming, and often leads to delays where old secrets remain in use longer than they should. Automated rotation ensures that secrets are regularly refreshed, minimizing the window of opportunity for a compromised secret to be exploited.
Internally, Secret Manager doesn’t modify existing secret versions. Instead, when a rotation is triggered, it executes a pre-configured "replication" process. This process typically involves:
- Generating a new secret value: This is usually done by a separate service or a custom script that can generate strong, random credentials (e.g., a new database password, a new API key).
- Creating a new secret version: The newly generated value is uploaded to Secret Manager as a new version of the existing secret.
- Enabling the new version: The new version is then marked as "enabled," making it the default for subsequent
latestrequests. - Disabling the old version: The previous version is often disabled after a grace period, preventing applications that haven’t yet picked up the new secret from accessing the now-stale credential.
You control this process through a combination of Secret Manager’s built-in features and Cloud Functions or Cloud Run. The key components are:
- Secret Manager: Stores the secret and its versions.
- Cloud Scheduler: Triggers the rotation on a defined schedule (e.g., every 30 days).
- Cloud Functions/Cloud Run: Executes the logic to generate the new secret and update Secret Manager. This function needs appropriate IAM permissions to create and manage secret versions.
- IAM: Grants the Cloud Function/Run service account the
Secret Manager Secret Writerrole.
The most surprising true thing about this topic is that Secret Manager itself doesn’t generate the new secret values for rotation; it’s a passive store and version manager. The intelligence for how to generate a new credential (e.g., a new database password with specific complexity rules, a new TLS certificate signed by a specific CA) must reside entirely in the custom code you deploy to Cloud Functions or Cloud Run. Secret Manager only orchestrates the storage and versioning of whatever you provide it.
Consider the scenario where you want to rotate a database password. Your Cloud Function would likely interact with the database’s native tools or an API to generate a new password, grant it access, and then pass that new password to Secret Manager as a new version. If your rotation mechanism fails to properly grant the new credentials access before creating the new secret version, your applications will start failing to connect to the database, even though the secret itself has been "rotated."
The next step after setting up automatic rotation is managing the lifecycle of disabled secret versions, particularly deciding when to permanently delete them to avoid accumulating sensitive data.