Use entity tags for optimistic concurrency control

Secret Manager supports using entity tags (ETags) for optimistic concurrency control.

In some cases, two processes updating the same resource in parallel may interfere with one another, where the latter process overwrites the effort of the former one.

ETags provide a means for optimistic concurrency control by allowing processes to see if a resource has been modified before taking action on that resource.

Use ETags with Secret Manager

The following resource modification requests support ETags:

In a secrets.patch request, the request ETag is embedded in the Secret data. All other requests accept an optional etag parameter.

If an ETag is provided and matches the current resource ETag, the request succeeds; otherwise, it fails with a FAILED_PRECONDITION error and an HTTP status code 400. If an ETag is not provided, the request proceeds without checking the currently stored ETag value.

Resource ETags are generated at resource creation (projects.secrets.create, projects.secrets.addVersion) and updated for each of the above-listed modification requests. A modification request only updates the ETag of the resource to which it applies. That is, updating a secret version does not affect the secret ETag, and vice versa.

A no-operation resource update also updates the resource ETag. For example, consider the following scenario: A caller issues a request to enable a secret version which is already enabled, without them being aware. The request is processed successfully, does not change the version state but changes the version ETag. Another caller, using the older ETag, attempts to disable the same version. Their request fails, since we captured the intent to enable the version prior to the disable request in the modified ETag.

The resource etag is returned in the response whenever a resource (Secret or SecretVersion) is included.

Usage

Delete a secret with etags

This demonstrates using etags when deleting a secret. If the secret has been modified by another process, the delete operation will fail.

gcloud

To use Secret Manager on the command line, first Install or upgrade to version 378.0.0 or higher of the Google Cloud CLI. On Compute Engine or GKE, you must authenticate with the cloud-platform scope.

The etag must include the surrounding quotes. For example, if the etag value was "abc", the shell-escaped value would be "\"abc\"".

gcloud beta secrets delete "SECRET_ID" \
    --etag "ETAG"

You can also specify etags during other secret mutation operations:

API

These examples use curl to demonstrate using the API. You can generate access tokens with gcloud auth print-access-token. On Compute Engine or GKE, you must authenticate with the cloud-platform scope.

The etag is specified as part of the URL's querystring and must be URL-encoded. For example, if the etag value was "abc", the URL-encoded value would be %22abc%22 because the quote character is encoded as %22.

curl "https://secretmanager.googleapis.com/v1/projects/PROJECT_ID/secrets/SECRET_ID?etag=ETAG" \
    --request "DELETE" \
    --header "Authorization: Bearer ACCESS_TOKEN"

Update a secret with etags

This demonstrates using etags when updating a secret. If the secret has been modified by another process, the update operation will fail.

gcloud

To use Secret Manager on the command line, first Install or upgrade to version 378.0.0 or higher of the Google Cloud CLI. On Compute Engine or GKE, you must authenticate with the cloud-platform scope.

The etag must include the surrounding quotes. For example, if the etag value was "abc", the shell-escaped value would be "\"abc\"".

gcloud beta secrets update "SECERT_ID" \
    --update-labels "foo=bar" \
    --etag "ETAG"

You can also specify etags during other secret mutation operations:

API

These examples use curl to demonstrate using the API. You can generate access tokens with gcloud auth print-access-token. On Compute Engine or GKE, you must authenticate with the cloud-platform scope.

The etag is specified as a field on the Secret and must include the surrounding quotes. For example, if the etag value was "abc", the JSON-escaped value would be {"etag":"\"abc\""}.

curl "https://secretmanager.googleapis.com/v1/projects/PROJECT_ID/secrets/SECRET_ID?updateMask=labels" \
    --request "PATCH" \
    --header "Authorization: Bearer ACCESS_TOKEN" \
    --header "Content-Type: application/json" \
    --data '{"etag":"ETAG", "labels":{"foo": "bar"}}'

Update a secret version with etags

This demonstrates using etags when updating a secret version. If the secret version has been modified by another process, the update operation will fail.

gcloud

To use Secret Manager on the command line, first Install or upgrade to version 378.0.0 or higher of the Google Cloud CLI. On Compute Engine or GKE, you must authenticate with the cloud-platform scope.

The etag must include the surrounding quotes. For example, if the etag value was "abc", the shell-escaped value would be "\"abc\"".

gcloud beta secrets versions disable "VERSION_ID" \
    --secret "SECRET_ID" \
    --etag "ETAG"

You can also specify etags during other secret version mutation operations:

API

These examples use curl to demonstrate using the API. You can generate access tokens with gcloud auth print-access-token. On Compute Engine or GKE, you must authenticate with the cloud-platform scope.

The etag is specified as a field on the SecretVersion and must include the surrounding quotes. For example, if the etag value was "abc", the JSON-escaped value would be {"etag":"\"abc\""}.

curl "https://secretmanager.googleapis.com/v1/projects/PROJECT_ID/secrets/SECRET_ID/versions/VERSION_ID:disable" \
    --request "POST" \
    --header "Authorization: Bearer ACCESS_TOKEN" \
    --header "Content-Type: application/json" \
    --data '{"etag":"ETAG"}'

What's next