Usar tags de entidade para controle de simultaneidade otimista

O Secret Manager é compatível com o uso de tags de entidade (ETags) para controle de simultaneidade otimista.

Em alguns casos, dois processos que atualizam o mesmo recurso em paralelo podem interferir no outro. O último processo substitui o esforço do anterior.

As ETags oferecem um meio para o controle de simultaneidade otimista, permitindo que os processos verifiquem se um recurso foi modificado antes de agir.

Usar ETags com o Secret Manager

As seguintes solicitações de modificação de recurso são compatíveis com ETags:

Em uma solicitação secrets.patch, a ETag da solicitação é incorporada aos dados Secret. Todas as outras solicitações aceitam um parâmetro etag opcional.

Se uma ETag for fornecida e corresponder à ETag do recurso atual, a solicitação será bem-sucedida. Caso contrário, ocorrerá uma falha com um erro FAILED_PRECONDITION e um código de status HTTP 400. Se uma ETag não for fornecida, a solicitação vai prosseguir sem verificar o valor da ETag armazenada no momento.

As ETags do recurso são geradas na criação do recurso (projects.secrets.create, projects.secrets.addVersion) e atualizadas para cada uma das solicitações de modificação listadas acima. Uma solicitação de modificação só atualiza a ETag do recurso a que ela se aplica. Ou seja, a atualização de uma versão do secret não afeta a ETag do secret e, da mesma forma, a atualização da ETag não afeta a versão do secret.

Mesmo quando uma atualização não muda o estado de um recurso, ela ainda atualiza a ETag do recurso.

Veja o exemplo a seguir.

  • O usuário 1 tenta ativar uma versão do secret sem saber que ela já está ativada. O sistema processa isso, mudando apenas a ETag da versão.

  • O usuário 2, usando a ETag antiga, tenta desativar a versão.

  • Isso falha porque o sistema reconhece a ETag mais recente, que indica uma intenção mais recente de manter a versão ativada.

Mesmo atualizações aparentemente pequenas são importantes devido às mudanças na ETag. Isso garante a consistência dos dados, principalmente com vários usuários ou sistemas interagindo com o mesmo recurso.

O recurso etag é retornado na resposta sempre que um recurso (Secret ou SecretVersion) for incluído.

Excluir um secret com ETags

Esta seção descreve o uso de ETags ao excluir um secret. Se o secret tiver sido modificado por outro processo, a operação de exclusão vai falhar.

gcloud

Antes de usar os dados do comando abaixo, faça estas substituições:

  • SECRET_ID: o ID do secret ou o identificador totalmente qualificado do secret.
  • ETAG: a tag de entidade do secret. A ETag precisa incluir aspas. Por exemplo, se o valor de ETag for "abc", o valor de escape do shell será "\"abc\"".

Execute o seguinte comando:

Linux, macOS ou Cloud Shell

gcloud secrets delete SECRET_ID \
    --etag "ETAG"

Windows (PowerShell)

gcloud secrets delete SECRET_ID `
    --etag "ETAG"

Windows (cmd.exe)

gcloud secrets delete SECRET_ID ^
    --etag "ETAG"

REST

Antes de usar os dados da solicitação abaixo, faça as substituições a seguir:

  • PROJECT_ID: o ID do projeto do Google Cloud .
  • SECRET_ID: o ID do secret ou o identificador totalmente qualificado do secret.
  • ETAG: a tag de entidade do secret. A ETag é especificada como parte da querystring do URL e precisa ser codificada para URL. Por exemplo, se o valor de ETag for "abc", o valor codificado por URL será %22abc%22 porque o caractere de aspas está codificado como %22.

Método HTTP e URL:

DELETE https://secretmanager.googleapis.com/v1/projects/PROJECT_ID/secrets/SECRET_ID?etag=ETAG

Corpo JSON da solicitação:

{}

Para enviar a solicitação, escolha uma destas opções:

curl

Salve o corpo da solicitação em um arquivo com o nome request.json e execute o comando a seguir:

curl -X DELETE \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json; charset=utf-8" \
-d @request.json \
"https://secretmanager.googleapis.com/v1/projects/PROJECT_ID/secrets/SECRET_ID?etag=ETAG"

PowerShell

Salve o corpo da solicitação em um arquivo com o nome request.json e execute o comando a seguir:

$cred = gcloud auth print-access-token
$headers = @{ "Authorization" = "Bearer $cred" }

Invoke-WebRequest `
-Method DELETE `
-Headers $headers `
-ContentType: "application/json; charset=utf-8" `
-InFile request.json `
-Uri "https://secretmanager.googleapis.com/v1/projects/PROJECT_ID/secrets/SECRET_ID?etag=ETAG" | Select-Object -Expand Content

Você receberá uma resposta JSON semelhante a esta:

{}

Atualizar um secret com ETags

Nesta seção, descrevemos como usar ETags ao atualizar um secret. Se o secret tiver sido modificado por outro processo, a operação de atualização falhará.

gcloud

Antes de usar os dados do comando abaixo, faça estas substituições:

  • SECRET_ID: o ID do secret ou o identificador totalmente qualificado do secret.
  • KEY: o nome do rótulo.
  • VALUE: o valor do rótulo correspondente.
  • ETAG: a tag de entidade do secret. A ETag precisa incluir aspas. Por exemplo, se o valor de ETag for "abc", o valor de escape do shell será "\"abc\"".

Execute o seguinte comando:

Linux, macOS ou Cloud Shell

gcloud secrets update SECRET_ID \
    --update-labels "KEY=VALUE" \
    --etag "ETAG"

Windows (PowerShell)

gcloud secrets update SECRET_ID `
    --update-labels "KEY=VALUE" `
    --etag "ETAG"

Windows (cmd.exe)

gcloud secrets update SECRET_ID ^
    --update-labels "KEY=VALUE" ^
    --etag "ETAG"

A resposta retorna o secret.

REST

Antes de usar os dados da solicitação abaixo, faça as substituições a seguir:

  • PROJECT_ID: o ID do projeto do Google Cloud .
  • SECRET_ID: o ID do secret ou o identificador totalmente qualificado do secret.
  • ETAG: a tag de entidade do secret. A ETag é especificada como um campo no Secret e precisa incluir as aspas ao redor. Por exemplo, se o valor de ETag for "abc", o valor de escape com JSON será {"etag":"\"abc\""}.
  • KEY: o nome do rótulo.
  • VALUE: o valor do rótulo correspondente.

Método HTTP e URL:

PATCH https://secretmanager.googleapis.com/v1/projects/PROJECT_ID/secrets/SECRET_ID?updateMask=labels

Corpo JSON da solicitação:

{"etag":"ETAG", "labels":{"KEY": "VALUE"}}

Para enviar a solicitação, escolha uma destas opções:

curl

Salve o corpo da solicitação em um arquivo com o nome request.json e execute o comando a seguir:

curl -X PATCH \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json; charset=utf-8" \
-d @request.json \
"https://secretmanager.googleapis.com/v1/projects/PROJECT_ID/secrets/SECRET_ID?updateMask=labels"

PowerShell

Salve o corpo da solicitação em um arquivo com o nome request.json e execute o comando a seguir:

$cred = gcloud auth print-access-token
$headers = @{ "Authorization" = "Bearer $cred" }

Invoke-WebRequest `
-Method PATCH `
-Headers $headers `
-ContentType: "application/json; charset=utf-8" `
-InFile request.json `
-Uri "https://secretmanager.googleapis.com/v1/projects/PROJECT_ID/secrets/SECRET_ID?updateMask=labels" | Select-Object -Expand Content

Você receberá uma resposta JSON semelhante a esta:

{
  "name": "projects/PROJECT_ID/locations/LOCATION/secrets/SECRET_ID",
  "createTime": "2024-09-04T04:06:00.660420Z",
  "labels": {
    "KEY": "VALUE"
  },
  "etag": "\"162145a4f894d5\""
}

Atualizar uma versão do secret com ETags

Esta seção descreve o uso de ETags ao atualizar uma versão do secret. Se a versão do secret tiver sido modificada por outro processo, a operação de atualização vai falhar.

O exemplo de código aqui descreve como desativar uma versão secreta com ETags. Também é possível especificar ETags durante outras operações de mutação de secrets, como ao ativar versões desativadas ou destruir versões de secrets. Consulte as amostras de código do Secret Manager.

gcloud

Antes de usar os dados do comando abaixo, faça estas substituições:

  • VERSION_ID: o ID da versão do secret.
  • SECRET_ID: o ID do secret ou o identificador totalmente qualificado do secret.
  • ETAG: a tag de entidade. A ETag precisa incluir aspas. Por exemplo, se o valor de ETag for "abc", o valor de escape do shell será "\"abc\"".

Execute o seguinte comando:

Linux, macOS ou Cloud Shell

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

Windows (PowerShell)

gcloud secrets versions disable VERSION_ID `
  --secret SECRET_ID `
  --etag "ETAG"

Windows (cmd.exe)

gcloud secrets versions disable VERSION_ID ^
  --secret SECRET_ID ^
  --etag "ETAG"

A resposta retorna o secret.

REST

Antes de usar os dados da solicitação abaixo, faça as substituições a seguir:

  • PROJECT_ID: o ID do projeto Google Cloud
  • SECRET_ID: o ID do secret ou o identificador totalmente qualificado do secret.
  • VERSION_ID: o ID da versão do secret
  • ETAG: a tag de entidade da versão do secret. A ETag é especificada como um campo no SecretVersion e precisa incluir as aspas ao redor. Por exemplo, se o valor de ETag for "abc", o valor de escape com JSON será {"etag":"\"abc\""}.

Método HTTP e URL:

POST https://secretmanager.googleapis.com/v1/projects/PROJECT_ID/secrets/SECRET_ID/versions/VERSION_ID:disable"

Corpo JSON da solicitação:

{"etag":"ETAG"}

Para enviar a solicitação, escolha uma destas opções:

curl

Salve o corpo da solicitação em um arquivo com o nome request.json e execute o comando a seguir:

curl -X POST \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json; charset=utf-8" \
-d @request.json \
"https://secretmanager.googleapis.com/v1/projects/PROJECT_ID/secrets/SECRET_ID/versions/VERSION_ID:disable""

PowerShell

Salve o corpo da solicitação em um arquivo com o nome request.json e execute o comando a seguir:

$cred = gcloud auth print-access-token
$headers = @{ "Authorization" = "Bearer $cred" }

Invoke-WebRequest `
-Method POST `
-Headers $headers `
-ContentType: "application/json; charset=utf-8" `
-InFile request.json `
-Uri "https://secretmanager.googleapis.com/v1/projects/PROJECT_ID/secrets/SECRET_ID/versions/VERSION_ID:disable"" | Select-Object -Expand Content

Você receberá uma resposta JSON semelhante a esta:

{
  "name": "projects/PROJECT_ID/locations/LOCATION/secrets/SECRET_ID/versions/VERSION_ID",
  "createTime": "2024-09-04T06:41:57.859674Z",
  "state": "DISABLED",
  "etag": "\"1621457b3c1459\""
}

A seguir