Authentification par jeton Web JSON

Vector Search accepte les points de terminaison d'index authentifiés à l'aide de jetons Web JSON (JWT) autosignés. Pour contrôler l'accès au point de terminaison de l'index, il est configuré pour n'accepter que les jetons JWT signés émis par des comptes de service Google spécifiquement autorisés. Cela signifie que seuls les clients utilisant ces comptes désignés peuvent interagir avec le point de terminaison.

Cette page décrit les étapes requises pour configurer un point de terminaison d'index avec l'authentification par jeton Web JSON (JWT) et exécuter des requêtes sur celui-ci.

Limites

  • L'authentification JWT n'est disponible que pour les points de terminaison privés avec appairage de VPC ou Private Service Connect (PSC).
  • L'authentification JWT n'est possible que pour les API RPC du plan de données (telles que MatchingService) appelées à l'aide de gRPC. Les exemples RPC de cette page utilisent l'outil Open Source grpc_cli pour envoyer des requêtes gRPC au serveur d'index déployé.
  • Les API d'administration pour la création, le déploiement et la gestion d'index sont sécurisées à l'aide de rôles IAM prédéfinis.

Créer et utiliser un jeton JWT pour interroger un index

Suivez la procédure suivante pour créer un point de terminaison d'index et l'interroger avec un jeton JWT autosigné.

Créer un index

Créez un index Vector Search en suivant les instructions de la section Créer un index.

Créer un point de terminaison privé

Créez un point de terminaison privé en suivant les instructions de l'une des pages de documentation suivantes :

Créer un compte de service

Créez un compte de service et attribuez-lui le rôle IAM Créateur de jetons du compte de service.

  1. Activez l'API IAM Service Account Credentials, puis créez un compte de service :

    gcloud services enable iamcredentials.googleapis.com --project="PROJECT_ID"
    gcloud iam service-accounts create SERVICE_ACCOUNT_ID --project="PROJECT_ID"
    

    Remplacez les valeurs suivantes :

    • PROJECT_ID : projet dans lequel créer votre compte de service.
    • SERVICE_ACCOUNT_ID : ID du compte de service.

    Découvrez comment créer un compte de service.

  2. Exécutez l'une des commandes suivantes pour attribuer le rôle IAM iam.serviceAccountTokenCreator à votre compte de service :

    • La commande suivante vous autorise à créer des jetons JWT à l'aide du compte de service d'une VM Compute Engine à laquelle le compte de service est associé :

      gcloud iam service-accounts add-iam-policy-binding \
         "SERVICE_ACCOUNT_ID@PROJECT_ID.iam.gserviceaccount.com" \
         --role "roles/iam.serviceAccountTokenCreator" \
         --member "serviceAccount:SERVICE_ACCOUNT_ID@PROJECT_ID.iam.gserviceaccount.com" \
         --project "PROJECT_ID"
      

      Remplacez les valeurs suivantes :

      • SERVICE_ACCOUNT_ID : ID du compte de service.
      • PROJECT_ID : projet dans lequel créer votre compte de service.
    • La commande suivante permet de créer des jetons JWT à l'aide du compte de service de votre propre compte Google (sur votre poste de travail) :

      gcloud iam service-accounts add-iam-policy-binding \
         "SERVICE_ACCOUNT_ID@PROJECT_ID.iam.gserviceaccount.com" \
         --role "roles/iam.serviceAccountTokenCreator" \
         --member "user:EMAIL_ADDRESS" \
         --project PROJECT_ID
      

      Remplacez les valeurs suivantes :

      • SERVICE_ACCOUNT_ID : ID du compte de service.
      • PROJECT_ID : projet dans lequel créer votre compte de service.
      • EMAIL_ADDRESS : votre adresse e-mail.

Déployer l'index sur le point de terminaison avec la configuration d'authentification JWT

  1. Déployez l'index sur le point de terminaison privé comme indiqué dans l'exemple suivant :

    gcloud ai index-endpoints deploy-index INDEX_ENDPOINT_ID \
       --index=INDEX_ID \
       --deployed-index-id=DEPLOYED_INDEX_ID \
       --display-name=DEPLOYED_INDEX_NAME \
       --audiences=AUDIENCES \
       --allowed-issuers="SERVICE_ACCOUNT_ID@PROJECT_ID.iam.gserviceaccount.com" \
       --project=PROJECT_ID \
       --region=LOCATION
    

    Remplacez les valeurs suivantes :

    • INDEX_ENDPOINT_ID : ID du point de terminaison de l'index.
    • INDEX_ID : ID de l'index.
    • DEPLOYED_INDEX_ID : chaîne spécifiée par l'utilisateur pour identifier de manière unique l'index déployé. Ce nom doit commencer par une lettre et ne peut contenir que des lettres, des chiffres ou des traits de soulignement. Consultez la page DeployedIndex.id pour connaître les consignes de format.
    • DEPLOYED_INDEX_NAME : nom à afficher de l'index déployé.
    • AUDIENCES : chaîne descriptive qui identifie l'audience attendue de votre service, charge de travail ou application (par exemple, "123456-my-app").
    • SERVICE_ACCOUNT_ID : ID du compte de service.
    • PROJECT_ID : L'ID de votre projet Google Cloud.
    • LOCATION : région dans laquelle vous utilisez Vertex AI.

Interroger l'index avec un jeton JWT autosigné

Dans les grandes lignes, la procédure à suivre est la suivante :

  1. Créez une charge utile JWT.
  2. Signez le jeton à l'aide du compte de service créé précédemment.
  3. Interrogez l'index en effectuant un appel gRPC, en transmettant le jeton dans l'en-tête d'autorisation.

Créer la charge utile JWT

L'authentification Vector Search accepte les jetons JWT signés avec un compte de service pré-autorisé, pour une audience prédéfinie. Le compte de service et l'audience doivent être spécifiés par l'appelant lorsqu'un index est déployé sur un point de terminaison privé. Une fois qu'un index est déployé avec ces paramètres, toutes les requêtes API gRPC adressées à ce point de terminaison doivent inclure un en-tête d'autorisation contenant un jeton JWT signé par l'émetteur (un compte de service) et destiné à l'audience indiquée. Le jeton JWT signé est transmis en tant que jeton de support dans l'en-tête authorization de la requête gRPC. En plus d'être signé par le compte de service, le jeton JWT doit inclure les revendications suivantes :

  • La revendication iss (émetteur autorisé) doit correspondre à l'adresse e-mail du compte de service. Exemple :

    "iss": "SERVICE_ACCOUNT_ID@PROJECT_ID.iam.gserviceaccount.com"
    
  • Les revendications aud (audience) et sub (objet) doivent toutes deux être définies sur la même valeur. Il s'agit d'une chaîne descriptive qui identifie l'audience attendue de votre service, charge de travail ou application. Exemple :

    "aud": "123456-my-app",
    "sub": "123456-my-app"
    

    Cette valeur doit correspondre à l'argument --audiences transmis au moment du déploiement de l'index.

  • La revendication iat (date/heure d'émission) doit être définie sur l'heure d'émission du jeton. La revendication exp (date/heure d'expiration) doit être définie sur une courte période ultérieure (environ une heure). Ces valeurs sont exprimées en epoch Unix. Exemple :

    "iat": 1698966927, // unix time since epoch eg via date +%s
    "exp": 1698967527 // iat + a few mins (eg 600 seconds)
    

L'exemple suivant illustre ces revendications dans une seule charge utile JWT :

{
   "iss": "SERVICE_ACCOUNT_ID@PROJECT_ID.iam.gserviceaccount.com",
   "aud": "123456-my-app",
   "sub": "123456-my-app",
   "iat": 1698956084,
   "exp": 1698960084
}

La charge utile JWT est signée à l'aide du compte de service spécifié dans la revendication iss. Elle est encodée en base64 pour être transmise en tant que jeton de support à l'aide des métadonnées gRPC, comme illustré dans l'exemple suivant, où signedJwt est une variable d'environnement contenant un jeton JWT signé :

./grpc_cli call ... --metadata "authorization: Bearer $signedJwt"

Créer le jeton JWT

  1. Assurez-vous que vous (l'appelant) pouvez utiliser le rôle roles/iam.serviceAccountTokenCreator sur le compte de service.

  2. Créez un fichier JSON nommé jwt_in.json contenant le jeton JWT brut :

    SA="serviceAccount:SERVICE_ACCOUNT_ID@PROJECT_ID.iam.gserviceaccount.com"
    cat << EOF > jwt_in.json
    {
      "aud": "AUDIENCES",
      "sub": "AUDIENCES",
      "iss": "${SA}",
      "iat": $(date +%s),
      "exp": $(expr $(date +%s) + 600)
    }
    EOF
    

    Remplacez les valeurs suivantes :

    • SERVICE_ACCOUNT_ID : ID du compte de service.
    • PROJECT_ID : L'ID de votre projet Google Cloud.
    • AUDIENCES : chaîne descriptive qui identifie l'audience attendue de votre service, charge de travail ou application (par exemple, "123456-my-app").

Signer le jeton JWT (API REST)

  1. À l'aide de l'outil jq, créez la charge utile de la requête curl en encodant le jeton JWT dans une chaîne :

    cat jwt_in.json | jq -Rsa >request.json
    
  2. Signez le jeton en transmettant la charge utile de la requête à la méthode signJwt de l'API REST.

    SA="serviceAccount:SERVICE_ACCOUNT_ID@PROJECT_ID.iam.gserviceaccount.com"
    curl -X POST \
       -H "Authorization: Bearer $(gcloud auth print-access-token)" \
       -H "Content-Type: application/json; charset=utf-8" \
       -d @request.json \
       "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/$SA:signJwt"
    

    Remplacez les valeurs suivantes :

    • SERVICE_ACCOUNT_ID : ID du compte de service.
    • PROJECT_ID : L'ID de votre projet Google Cloud.

    Stockez la valeur signedJwt renvoyée dans une variable d'environnement appelée signedJwt.

Signer le jeton JWT (gcloud CLI)

Vous pouvez également signer le jeton JWT en transmettant le fichier jwt_in.json directement à la méthode sign-jwt de la gcloud CLI.

gcloud iam service-accounts sign-jwt jwt_in.json jwt_out \
   --iam-account=SERVICE_ACCOUNT_ID@PROJECT_ID.iam.gserviceaccount.com

Remplacez les valeurs suivantes :

  • SERVICE_ACCOUNT_ID : ID du compte de service.
  • PROJECT_ID : L'ID de votre projet Google Cloud.

Le jeton JWT signé est renvoyé dans le fichier de sortie jwt_out. Stockez-le dans une variable d'environnement appelée signedJwt.

Envoyer le jeton JWT signé au point de terminaison de l'index

À partir d'une VM Compute Engine du même réseau VPC, appelez le point de terminaison MatchService gRPC en transmettant le jeton signedJwt dans l'en-tête authorization, comme illustré dans l'exemple suivant :

./grpc_cli call ${TARGET_IP}:10000 google.cloud.aiplatform.container.v1.MatchService.Match \
   '{deployed_index_id: "${DEPLOYED_INDEX_ID}", float_val: [-0.1,..]}' \
   --metadata "authorization: Bearer $signedJwt"

Pour exécuter cette commande, vous devez définir les variables d'environnement suivantes :

  • TARGET_IP est l'adresse IP du serveur d'index déployé. Pour savoir comment récupérer cette valeur, consultez la page Interroger les index pour obtenir les voisins les plus proches.
  • DEPLOYED_INDEX_ID : chaîne spécifiée par l'utilisateur pour identifier de manière unique l'index déployé. Ce nom doit commencer par une lettre et ne peut contenir que des lettres, des chiffres ou des traits de soulignement. Consultez la page DeployedIndex.id pour connaître les consignes de format.

signedJwt est la variable d'environnement contenant votre jeton JWT signé.

Dépannage

Le tableau suivant répertorie certains messages d'erreur gRPC courants.

Message d'erreur gRPC Motif
En-tête d'autorisation introuvable pour l'index "INDEX_ID" Les métadonnées gRPC ne contiennent pas d'en-tête d'autorisation.
Le format du jeton JWT n'est pas valide Le jeton est incorrect et ne peut pas être analysé correctement.
Échec de l'authentification JWT Le jeton a expiré ou n'est pas signé par le bon compte de service.
L'émetteur JWT doit figurer dans la liste des émetteurs autorisés Le jeton iss ne figure pas dans les émetteurs autorisés auth_config.
Échec de la vérification des autorisations pour l'index "INDEX_ID" La revendication aud ou sub du jeton ne figure pas dans les audiences auth_config.

Étapes suivantes