Secret Manager supports rotation schedules on secrets. Secret Manager sends messages to Pub/Sub topics configured on the secret based on the provided rotation frequency and rotation time. This topic shows you how to set up one-time or periodic schedules on your secrets to receive notifications when it's time to rotate the secret.
Periodically rotating secrets helps to:
- Limit the duration a leaked secret remains valid and exposes a vulnerability.
- Continuously exercise rotation flow to ensure process reliability.
How does it work?
Secret Manager sends a SECRET_ROTATE
message to the Pub/Sub topics
configured on the secret at the secret's next_rotation_time
. This timestamp is
set in one of two ways:
Provided by the user when creating or updating the secret.
If a
rotation_period
is provided, Secret Manager will send aSECRET_ROTATE
message after the elapsedrotation_period
.next_rotation_time
will be updated to reflect the new next rotation time.
You must configure a Pub/Sub subscriber to receive and act on the SECRET_ROTATE
messages
. If necessary, implement additional workflows such as adding a new secret version
and triggering application deploys.
Notes
Managing rotation policies is only available in the Secret Manager
v1
API and Google Cloud CLI.Pub/Sub topics must be configured on the secret. To learn how to create a Pub/Sub topic and subscription, see the Pub/Sub quickstart. To learn how to configure topics on a secret, see Event Notifications for Secret Manager.
next_rotation_time
must be set ifrotation_period
is specified.next_rotation_time
cannot be set to less than five minutes in the future. Therotation_period
cannot be less than one hour long. For timestamp formatting guidance, see the gcloud datetime reference.Delivery Errors: Secret Manager will automatically retry failed attempts to send a message. Secret Manager does not make guarantees regarding delivery should there be misconfiguration regarding secret or topic config, permissions, or quotas.
In-flight rotations must complete before another rotation can be started in order to prevent concurrent rotations from yielding unexpected behavior. Notifications are considered in-flight while Secret Manager is attempting to send the message to Pub/Sub. Scheduled rotations are skipped if there is an in-flight rotation. Secret Manager will automatically retry failed attempts to send a message for up to seven days, after which the rotation is aborted.
Examples
Configure rotation on a secret
Create a secret with a next_rotation_time
that rotates every 30 days starting on June 1st, 2021:
gcloud
gcloud secrets create secret-id \ --replication-policy "automatic" \ --next-rotation-time="2021-06-01T09:00:00Z" \ --rotation-period="2592000s" \ --topics="full-topic-name"
API
curl "https://secretmanager.googleapis.com/v1/projects/${PROJECT_ID}/secrets?secretId=${SECRET_ID}" \
--request "POST" \
--header "Content-Type: application/json" \
--header "Authorization: Bearer $(gcloud auth print-access-token)" \
--data-binary @- <<EOF
{
"replication":{
"automatic":{}
},
"topics": {"name" : "projects/${PROJECT_ID}/topics/${TOPIC_NAME}"},
"rotation":
{
"next_rotation_time": "2021-06-01T09:00:00Z",
"rotation_period" : '2592000s'
},
}
EOF
Update a secret's rotation settings
Valid updateMask paths for rotation include: rotation
, rotation.next_rotation_time
, rotation.rotation_period
.
Update a secret's next_rotation_time
:
gcloud
gcloud secrets update secret-id \ --next-rotation-time "2022-06-01T09:00:00Z"
API
$ curl "https://secretmanager.googleapis.com/v1/projects/${PROJECT_ID}/secrets/${SECRET_ID}?updateMask=rotation.next_rotation_time" \
--request "PATCH" \
--header "Authorization: Bearer $(gcloud auth print-access-token)" \
--header "Content-Type: application/json" \
--data-binary @- <<EOF
{
"rotation": {"next_rotation_time": "2040-06-01T09:00:00Z"}
}
EOF
Disable rotation on a secret
Remove a secret's next_rotation_time
:
gcloud
gcloud secrets update secret-id \ --remove-next-rotation-time
API
$ curl "https://secretmanager.googleapis.com/v1/projects/${PROJECT_ID}/secrets/${SECRET_ID}?updateMask=rotation.next_rotation_time" \
--request "PATCH" \
--header "Authorization: Bearer $(gcloud auth print-access-token)" \
--header "Content-Type: application/json" \
--data-binary @- <<EOF
{}
EOF
Remove a secret's rotation schedule. This removes both the next_rotation_time
and rotation_period
.
gcloud
gcloud secrets update secret-id \ --remove-rotation-schedule
API
$ curl "https://secretmanager.googleapis.com/v1/projects/${PROJECT_ID}/secrets/${SECRET_ID}?updateMask=rotation" \
--request "PATCH" \
--header "Authorization: Bearer $(gcloud auth print-access-token)" \
--header "Content-Type: application/json" \
--data-binary @- <<EOF
{}
EOF
What's next
Learn how to enable Customer-Managed Encryption Keys (CMEK) for Secret Manager.
Learn how to use ETags for optimistic concurrency control.