Creating and managing expiring secrets

This topic discusses support for expiring secrets in Secret Manager.

Overview

By default, secrets stored in Secret Manager exist until a user deletes them. If a secret should only be stored for a known, limited amount of time, you can attach an expiration time to it. At a secret's configured expiration time, it is automatically deleted.

If you don't have requirements that the secret must be deleted, consider using IAM Conditions or the Disabled version state to revoke access in a safe way.

When inputting an expiration, it can be expressed as either a timestamp or a duration. When retrieving secret metadata, the expiration will always be returned as a timestamp, regardless of how it was given.

An expiration can be added, updated, or removed from a secret at any time.

Limitations

  • Secret expiration is only available only in the Secret Manager v1 API and gcloud command-line tool.

  • A secret's expiration cannot be less than 60 seconds away or more than 100 years away.

Safely using expiring secrets

When a secret expires in Secret Manager, it is irreversibly deleted. The best way to detect soon-to-expire secrets is by using IAM Conditions to remove permissions from the accounts that use the secret prior to expiration.

To do this, when granting permissions on a secret, attach a time-based condition to the binding. The binding should expire after the secret is expected to no longer be used, but early enough that the removed permissions would be noticed before the secret expires. If workflows that were thought to no longer use the secret break after permissions are revoked, then permissions can be added back to quickly mitigate. If more time is required, the secret expiration can be updated or even removed.

For example, suppose a service account is expected to access a secret daily over a 30 day period. The secret expiration could then be set to 60 days from creation and a conditional IAM binding could be used to grant the service account the Secret Accessor role for 45 days. If the service account attempts to access the secret after 45 days, a Permission Denied error will be returned and workflows requiring the secret would break. An administrator could then grant the Secret Accessor role back to the service account to quickly mitigate while investigating, since the secret itself wouldn't be deleted for 15 more days.

Additionally, it is possible to create alerts based on logs warning of secrets that are expiring soon. See Expiration logging for more information.

Specifying timestamps and durations

  • Timestamp values must be formatted as RFC 3339, for example 2100-01-01T09:00:00-05:00.

  • Duration values must be formatted as the number of seconds including the "s" suffix, for example 86400s.

Creating an expiring secret

To create an expiring secret using a timestamp run:

Command-line

To use Secret Manager on the command line, first Install or upgrade to version 338.0.0 or higher of the Cloud SDK.

gcloud secrets create "SECRET_ID" \
    --replication-policy "automatic" \
    --expire-time "TIMESTAMP"

API

These examples use curl to demonstrate using the API.

curl "https://secretmanager.googleapis.com/v1/projects/PROJECT_ID/secrets?secretId=SECRET_ID" \
    --request "POST" \
    --header "Content-Type: application/json" \
    --header "Authorization: Bearer TOKEN" \
    --data-binary @- <<EOF
{
  "replication": {"automatic": {}},
  "expire_time": "TIMESTAMP"
}
EOF

To create an expiring secret using a duration run:

Command-line

To use Secret Manager on the command line, first Install or upgrade to version 338.0.0 or higher of the Cloud SDK.

gcloud secrets create "SECRET_ID" \
    --replication-policy "automatic" \
    --ttl "DURATION"

API

These examples use curl to demonstrate using the API.

curl "https://secretmanager.googleapis.com/v1/projects/PROJECT_ID/secrets?secretId=SECRET_ID" \
    --request "POST" \
    --header "Content-Type: application/json" \
    --header "Authorization: Bearer TOKEN" \
    --data-binary @- <<EOF
{
  "replication": {"automatic": {}},
  "ttl": "DURATION"
}
EOF

Updating a secret's expiration

Any secret can have a new expiration applied to it regardless of whether it already has one. Each secret can only have one configured expiration at a time. Updating the expiration of a secret that already has one will overwrite its existing expiration.

To update a secret's expiration using a timestamp run:

Command-line

To use Secret Manager on the command line, first Install or upgrade to version 338.0.0 or higher of the Cloud SDK.

gcloud secrets update "SECRET_ID" \
    --expire-time "TIMESTAMP"

API

These examples use curl to demonstrate using the API.

curl "https://secretmanager.googleapis.com/v1/projects/PROJECT_ID/secrets/SECRET_ID?updateMask=expire_time" \
    --request "PATCH" \
    --header "Content-Type: application/json" \
    --header "Authorization: Bearer TOKEN" \
    --data-binary @- <<EOF
{
  "expire_time": "TIMESTAMP"
}
EOF

To update a secret's expiration using a duration run:

Command-line

To use Secret Manager on the command line, first Install or upgrade to version 338.0.0 or higher of the Cloud SDK.

gcloud secrets update "SECRET_ID" \
    --ttl "DURATION"

API

These examples use curl to demonstrate using the API.

curl "https://secretmanager.googleapis.com/v1/projects/PROJECT_ID/secrets/SECRET_ID?updateMask=ttl" \
    --request "PATCH" \
    --header "Content-Type: application/json" \
    --header "Authorization: Bearer TOKEN" \
    --data-binary @- <<EOF
{
  "ttl": "DURATION"
}
EOF

Removing a secret's expiration

To remove a secret's expiration run:

Command-line

To use Secret Manager on the command line, first Install or upgrade to version 338.0.0 or higher of the Cloud SDK.

gcloud secrets update "SECRET_ID" \
    --remove-expiration

API

These examples use curl to demonstrate using the API.

Including either expire_time or ttl in the updateMask while providing values for neither will remove the expiration.

curl "https://secretmanager.googleapis.com/v1/projects/PROJECT_ID/secrets/SECRET_ID?updateMask=ttl" \
    --request "PATCH" \
    --header "Content-Type: application/json" \
    --header "Authorization: Bearer TOKEN" \
    --data-binary '{}'

Expiration logging

Cloud Audit Logs are not produced when a Secret automatically expires. Instead Secret Manager writes logs to the Secret Manager Secret resource at specific intervals leading up to a secret's expiration.

Log Timing Secret Event Type
30 days before expiration EXPIRES_IN_30_DAYS
7 days before expiration EXPIRES_IN_7_DAYS
1 day before expiration EXPIRES_IN_1_DAY
6 hours before expiration EXPIRES_IN_6_HOURS
1 hour before expiration EXPIRES_IN_1_HOUR
at expiration EXPIRED

See the Logging Quickstart guide for information about how to view these logs. You can create Log-based metrics and use them to create alerts for upcoming expirations.

What's next?