Utiliser des tags d'entité pour le contrôle de simultanéité optimiste

Secret Manager permet d'utiliser des tags d'entité (ETag) pour un contrôle de simultanéité optimiste.

Dans certains cas, deux processus mettant à jour la même ressource en parallèle peuvent interférer les uns avec les autres, ce qui risque d'écraser l'autre processus.

Les ETags offrent un moyen de contrôler la simultanéité optimiste en permettant aux processus de vérifier si une ressource a été modifiée avant d'agir sur cette ressource.

Utiliser les ETags avec Secret Manager

Les requêtes de modification de ressources suivantes sont compatibles avec les ETags :

Dans une requête secrets.patch, l'ETag de la requête est intégré aux données du Secret. Toutes les autres requêtes acceptent un paramètre etag facultatif.

Si un ETag est fourni et correspond à l'ETag actuel de la ressource, la requête aboutit. Sinon, l'opération échoue avec une erreur FAILED_PRECONDITION et un code d'état HTTP 400. Si aucun ETag n'est fourni, la requête continue sans vérifier la valeur ETag actuellement stockée.

Les ETags des ressources sont générés lors de la création de la ressource (projects.secrets.create, projects.secrets.addVersion) et mis à jour pour chacune des requêtes de modifications répertoriées ci-dessus. Une requête de modification ne met à jour que l'ETag de la ressource à laquelle il s'applique. Autrement dit, la mise à jour de la version d'un secret n'affecte pas l'ETag du secret et, de même, la mise à jour de l'ETag n'affecte pas la version du secret.

Même si une mise à jour ne modifie pas l'état d'une ressource, elle met à jour son ETag.

Prenons l'exemple suivant :

  • L'utilisateur 1 tente d'activer une version de secret sans savoir qu'elle est déjà activée. Le système traite cette requête, sans modifier autre chose que l'ETag de la version.

  • L'utilisateur 2, qui utilise l'ancien ETag, tente de désactiver la version.

  • Cette opération échoue, car le système reconnaît l'ETag le plus récent, qui indique un intent plus récent pour maintenir la version activée.

Même les mises à jour en apparence mineures sont importantes en raison des modifications apportées aux ETag. Cela garantit la cohérence des données, en particulier lorsque plusieurs utilisateurs ou systèmes interagissent avec la même ressource.

La ressource etag est renvoyée dans la réponse chaque fois qu'une ressource (Secret ou SecretVersion) est incluse.

Supprimer un secret avec des ETags

Cette section explique comment utiliser les ETags lors de la suppression d'un secret. Si le secret a été modifié par un autre processus, l'opération de suppression échouera.

gcloud

Avant d'utiliser les données de la commande ci-dessous, effectuez les remplacements suivants :

  • SECRET_ID: ID du secret ou identifiant complet du secret.
  • ETAG: balise d'entité du secret. L'ETag doit inclure les guillemets environnants. Par exemple, si la valeur ETag est "abc", la valeur échappée par l'interface système est "\"abc\"".

Exécutez la commande suivante :

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

Avant d'utiliser les données de requête ci-dessous, effectuez les remplacements suivants :

  • PROJECT_ID: ID du Google Cloud projet.
  • SECRET_ID: ID du secret ou identifiant complet du secret.
  • ETAG: balise d'entité du secret. L'ETag est spécifié dans la chaîne de requête de l'URL et doit être encodé au format URL. Par exemple, si la valeur ETag est "abc", la valeur encodée en URL est %22abc%22, car le caractère de guillemet est encodé comme %22.

Méthode HTTP et URL :

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

Corps JSON de la requête :

{}

Pour envoyer votre requête, choisissez l'une des options suivantes :

curl

Enregistrez le corps de la requête dans un fichier nommé request.json, puis exécutez la commande suivante :

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

Enregistrez le corps de la requête dans un fichier nommé request.json, puis exécutez la commande suivante :

$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

Vous devriez recevoir une réponse JSON de ce type :

{}

Mettre à jour un secret avec des ETags

Cette section décrit l'utilisation des ETags lors de la mise à jour d'un secret. Si le secret a été modifié par un autre processus, l'opération de mise à jour échoue.

gcloud

Avant d'utiliser les données de la commande ci-dessous, effectuez les remplacements suivants :

  • SECRET_ID: ID du secret ou identifiant complet du secret.
  • KEY : nom du libellé.
  • VALUE: valeur de l'étiquette correspondante.
  • ETAG: balise d'entité du secret. L'ETag doit inclure les guillemets environnants. Par exemple, si la valeur ETag est "abc", la valeur échappée par l'interface système est "\"abc\"".

Exécutez la commande suivante :

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"

La réponse renvoie le secret.

REST

Avant d'utiliser les données de requête ci-dessous, effectuez les remplacements suivants :

  • PROJECT_ID: ID du Google Cloud projet.
  • SECRET_ID: ID du secret ou identifiant complet du secret.
  • ETAG: balise d'entité du secret. L'ETag est spécifié en tant que champ dans Secret et doit inclure les guillemets autour. Par exemple, si la valeur ETag est "abc", la valeur échappée au format JSON serait {"etag":"\"abc\""}.
  • KEY : nom du libellé.
  • VALUE: valeur de l'étiquette correspondante.

Méthode HTTP et URL :

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

Corps JSON de la requête :

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

Pour envoyer votre requête, choisissez l'une des options suivantes :

curl

Enregistrez le corps de la requête dans un fichier nommé request.json, puis exécutez la commande suivante :

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

Enregistrez le corps de la requête dans un fichier nommé request.json, puis exécutez la commande suivante :

$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

Vous devriez recevoir une réponse JSON de ce type :

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

Mettre à jour une version de secret avec des ETags

Cette section décrit l'utilisation des ETags lors de la mise à jour de la version d'un secret. Si la version du secret a été modifiée par un autre processus, l'opération de mise à jour échouera.

L'exemple de code ci-dessous décrit la désactivation d'une version de secret avec des ETags. Vous pouvez également spécifier des ETags lors d'autres opérations de mutation de secret, par exemple lors de l'activation de versions désactivées ou de la destruction de versions de secret. Consultez les exemples de code pour Secret Manager.

gcloud

Avant d'utiliser les données de la commande ci-dessous, effectuez les remplacements suivants :

  • VERSION_ID: ID de la version du secret.
  • SECRET_ID: ID du secret ou identifiant complet du secret.
  • ETAG: balise d'entité. L'ETag doit inclure les guillemets environnants. Par exemple, si la valeur ETag est "abc", la valeur échappée par l'interface système est "\"abc\"".

Exécutez la commande suivante :

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"

La réponse renvoie le secret.

REST

Avant d'utiliser les données de requête ci-dessous, effectuez les remplacements suivants :

  • PROJECT_ID: ID du Google Cloud projet
  • SECRET_ID: ID du secret ou identifiant complet du secret
  • VERSION_ID: ID de la version du secret
  • ETAG: balise d'entité de la version du secret. L'ETag est spécifié en tant que champ dans SecretVersion et doit inclure les guillemets autour. Par exemple, si la valeur ETag est "abc", la valeur échappée au format JSON serait {"etag":"\"abc\""}.

Méthode HTTP et URL :

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

Corps JSON de la requête :

{"etag":"ETAG"}

Pour envoyer votre requête, choisissez l'une des options suivantes :

curl

Enregistrez le corps de la requête dans un fichier nommé request.json, puis exécutez la commande suivante :

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

Enregistrez le corps de la requête dans un fichier nommé request.json, puis exécutez la commande suivante :

$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

Vous devriez recevoir une réponse JSON de ce type :

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

Étape suivante