Use etiquetas de entidade para o controlo de concorrência otimista

O Secret Manager suporta a utilização de etiquetas de entidade (ETags) para o controlo de simultaneidade otimista.

Em alguns casos, dois processos que atualizam o mesmo recurso em paralelo podem interferir entre si, em que o último processo substitui o esforço do primeiro.

As ETags oferecem um meio de controlo de simultaneidade otimista, permitindo que os processos verifiquem se um recurso foi modificado antes de tomar medidas nesse recurso.

Use ETags com o Secret Manager

Os seguintes pedidos de modificação de recursos suportam ETags:

Num pedido secrets.patch, o ETag do pedido está incorporado nos dados Secret. Todos os outros pedidos aceitam um parâmetro etag opcional.

Se for fornecido um ETag e este corresponder ao ETag do recurso atual, o pedido é bem-sucedido. Caso contrário, falha com um erro FAILED_PRECONDITION e um código de estado HTTP 400. Se não for fornecido um ETag, o pedido prossegue sem verificar o valor ETag armazenado atualmente.

As ETags de recursos são geradas na criação de recursos (projects.secrets.create, projects.secrets.addVersion) e atualizadas para cada um dos pedidos de modificação indicados acima. Um pedido de modificação apenas atualiza o ETag do recurso ao qual se aplica. Ou seja, a atualização de uma versão do segredo não afeta o ETag do segredo e, da mesma forma, a atualização do ETag não afeta a versão do segredo.

Mesmo quando uma atualização não altera o estado de um recurso, continua a atualizar o ETag do recurso.

Considere o seguinte exemplo:

  • O utilizador 1 tenta ativar uma versão secreta sem saber que já está ativada. O sistema processa esta ação, não alterando nada além do ETag da versão.

  • O utilizador 2, que usa o ETag antigo, tenta desativar a versão.

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

Mesmo as atualizações aparentemente menores são importantes devido às alterações da ETag. Isto garante a consistência dos dados, especialmente com vários utilizadores ou sistemas a interagir com o mesmo recurso.

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

Elimine um segredo com ETags

Esta secção descreve a utilização de ETags quando elimina um segredo. Se o código secreto tiver sido modificado por outro processo, a operação de eliminação falha.

gcloud

Antes de usar qualquer um dos dados de comandos abaixo, faça as seguintes substituições:

  • SECRET_ID: o ID do segredo ou o identificador totalmente qualificado do segredo.
  • ETAG: a etiqueta de entidade do segredo. A ETag tem de incluir as aspas. Por exemplo, se o valor ETag fosse "abc", o valor com carateres de escape da shell seria "\"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 qualquer um dos dados do pedido, faça as seguintes substituições:

  • PROJECT_ID: o Google Cloud ID do projeto.
  • SECRET_ID: o ID do segredo ou o identificador totalmente qualificado do segredo.
  • ETAG: a etiqueta de entidade do segredo. O ETag é especificado como parte da string de consulta do URL e tem de ser codificado por URL. Por exemplo, se o valor ETag for "abc", o valor codificado por URL seria %22abc%22 porque o caráter de aspas é codificado como %22.

Método HTTP e URL:

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

Corpo JSON do pedido:

{}

Para enviar o seu pedido, escolha uma destas opções:

curl

Guarde o corpo do pedido num ficheiro com o nome request.json, e execute o seguinte comando:

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

Guarde o corpo do pedido num ficheiro com o nome request.json, e execute o seguinte comando:

$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

Deve receber uma resposta JSON semelhante à seguinte:

{}

Atualize um segredo com ETags

Esta secção descreve a utilização de ETags ao atualizar um segredo. Se o segredo tiver sido modificado por outro processo, a operação de atualização falha.

gcloud

Antes de usar qualquer um dos dados de comandos abaixo, faça as seguintes substituições:

  • SECRET_ID: o ID do segredo ou o identificador totalmente qualificado do segredo.
  • KEY: o nome da etiqueta.
  • VALUE: o valor da etiqueta correspondente.
  • ETAG: a etiqueta de entidade do segredo. A ETag tem de incluir as aspas. Por exemplo, se o valor ETag fosse "abc", o valor com carateres de escape da shell seria "\"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 devolve o segredo.

REST

Antes de usar qualquer um dos dados do pedido, faça as seguintes substituições:

  • PROJECT_ID: o Google Cloud ID do projeto.
  • SECRET_ID: o ID do segredo ou o identificador totalmente qualificado do segredo.
  • ETAG: a etiqueta de entidade do segredo. O ETag é especificado como um campo no Secret e tem de incluir as aspas. Por exemplo, se o valor ETag fosse "abc", o valor com carateres de escape JSON seria {"etag":"\"abc\""}.
  • KEY: o nome da etiqueta.
  • VALUE: o valor da etiqueta correspondente.

Método HTTP e URL:

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

Corpo JSON do pedido:

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

Para enviar o seu pedido, escolha uma destas opções:

curl

Guarde o corpo do pedido num ficheiro com o nome request.json, e execute o seguinte comando:

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

Guarde o corpo do pedido num ficheiro com o nome request.json, e execute o seguinte comando:

$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

Deve receber uma resposta JSON semelhante à seguinte:

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

Atualize uma versão secreta com ETags

Esta secção descreve a utilização de ETags quando atualiza uma versão secreta. Se a versão do segredo tiver sido modificada por outro processo, a operação de atualização falha.

O exemplo de código aqui descrito descreve a desativação de uma versão secreta com ETags. Também pode especificar ETags durante outras operações de mutação de segredos, como quando ativa versões desativadas ou destrói versões de segredos. Consulte os exemplos de código para o Secret Manager.

gcloud

Antes de usar qualquer um dos dados de comandos abaixo, faça as seguintes substituições:

  • VERSION_ID: o ID da versão do segredo.
  • SECRET_ID: o ID do segredo ou o identificador totalmente qualificado do segredo.
  • ETAG: a etiqueta da entidade. A ETag tem de incluir as aspas. Por exemplo, se o valor ETag fosse "abc", o valor com carateres de escape da shell seria "\"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 devolve o segredo.

REST

Antes de usar qualquer um dos dados do pedido, faça as seguintes substituições:

  • PROJECT_ID: o Google Cloud ID do projeto
  • SECRET_ID: o ID do segredo ou o identificador totalmente qualificado do segredo
  • VERSION_ID: o ID da versão do segredo
  • ETAG: a etiqueta de entidade da versão do segredo. O ETag é especificado como um campo no SecretVersion e tem de incluir as aspas. Por exemplo, se o valor ETag fosse "abc", o valor com carateres de escape JSON seria {"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 do pedido:

{"etag":"ETAG"}

Para enviar o seu pedido, escolha uma destas opções:

curl

Guarde o corpo do pedido num ficheiro com o nome request.json, e execute o seguinte comando:

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

Guarde o corpo do pedido num ficheiro com o nome request.json, e execute o seguinte comando:

$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

Deve receber uma resposta JSON semelhante à seguinte:

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

O que se segue?