Autenticación de token web JSON

Vector Search admite extremos de índice autenticados mediante tokens web JSON (JWT) autofirmados. Para controlar el acceso al extremo del índice, se configura para aceptar solo los JWT firmados que emiten las cuentas de servicio de Google autorizadas de manera específica. Esto significa que solo los clientes que usan esas cuentas designadas pueden interactuar con el extremo.

En esta página, se describen los pasos necesarios para configurar un extremo de índice con la autenticación de token web JSON (JWT) y ejecutar consultas en él.

Limitaciones

  • La autenticación de JWT solo es compatible con extremos privados con el intercambio de tráfico entre VPC o Private Service Connect (PSC).
  • La autenticación de JWT solo es compatible con las API de RPC del plano de datos (como MatchService) que se invocan mediante gRPC. En los ejemplos de RPC de esta página, se usa la herramienta de código abierto grpc_cli para enviar solicitudes de gRPC al servidor de índice implementado.
  • Las API de administrador para la creación, implementación y administración de índices están protegidas mediante roles predefinidos de IAM.

Crea y usa un JWT para consultar un índice

Sigue estos pasos para crear un extremo de índice y consultarlo con un JWT autofirmado.

Crea un índice

Crea un índice de Vector Search mediante las instrucciones que aparecen en Crea un índice.

Crea un extremo privado

Para crear un extremo privado, sigue las instrucciones de una de las siguientes páginas de documentación:

Crea una cuenta de servicio

Crea una cuenta de servicio y otórgale el rol de IAM de Creador de tokens de cuenta de servicio.

  1. Habilita la API de credenciales de la cuenta de servicio de IAM y crea una cuenta de servicio:

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

    Reemplaza los siguientes valores:

    • PROJECT_ID es el proyecto en el que se creará la cuenta de servicio.
    • SERVICE_ACCOUNT_ID: El ID para la cuenta de servicio.

    Más información sobre cómo crear una cuenta de servicio.

  2. Usa uno de los siguientes comandos para otorgar el rol de IAM iam.serviceAccountTokenCreator a tu cuenta de servicio:

    • El siguiente comando te otorga permiso para crear JWT mediante la cuenta de servicio de una VM de Compute Engine que tiene la cuenta de servicio conectada:

      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"
      

      Reemplaza los siguientes valores:

      • SERVICE_ACCOUNT_ID: El ID para la cuenta de servicio.
      • PROJECT_ID es el proyecto en el que se creará la cuenta de servicio.
    • El siguiente comando otorga permiso para crear JWT mediante la cuenta de servicio de tu propia Cuenta de Google (en tu estación de trabajo):

      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
      

      Reemplaza los siguientes valores:

      • SERVICE_ACCOUNT_ID: El ID para la cuenta de servicio.
      • PROJECT_ID es el proyecto en el que se creará la cuenta de servicio.
      • EMAIL_ADDRESS: tu dirección de correo electrónico.

Implementa el índice en el extremo con la configuración de autenticación de JWT

  1. Implementa el índice en el extremo privado, como se muestra en el siguiente ejemplo:

    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
    

    Reemplaza los siguientes valores:

    • INDEX_ENDPOINT_ID: Es el ID del extremo del índice.
    • INDEX_ID: Es el ID del índice.
    • DEPLOYED_INDEX_ID: Una cadena especificada por el usuario para identificar de forma inequívoca el índice implementado. Debe comenzar con una letra y contener solo letras, números o guiones bajos. Consulta DeployedIndex.id para obtener lineamientos de formato.
    • DEPLOYED_INDEX_NAME: Nombre visible del índice implementado.
    • AUDIENCES: Una cadena descriptiva que identifica el público esperado para tu servicio, carga de trabajo o app, por ejemplo, "123456-my-app".
    • SERVICE_ACCOUNT_ID: El ID para la cuenta de servicio.
    • PROJECT_ID: El ID del proyecto de Google Cloud.
    • LOCATION: la región en la que usas Vertex AI.

Consulta el índice con un JWT autofirmado

A grandes rasgos, los pasos necesarios son los siguientes:

  1. Crea una carga útil de JWT.
  2. Firma el token con la cuenta de servicio creada antes.
  3. Consulta el índice mediante una llamada a gRPC y pasa el token en el encabezado de autorización.

Crea la carga útil de JWT

La autenticación de Vector Search acepta JWT firmados con una cuenta de servicio autorizada previamente, para un público predefinido. El emisor debe especificar la cuenta de servicio y el público cuando se implementa un índice en un extremo privado. Una vez que se implementa un índice con esta configuración, todas las solicitudes a la API de gRPC para ese extremo deben incluir un encabezado de autorización que contenga un JWT firmado por la entidad emisora (una cuenta de servicio) y dirigido al público proporcionado. El JWT firmado se pasa como un token del portador en el encabezado authorization de la solicitud de gRPC. Además de estar firmado por la cuenta de servicio, el JWT debe incluir las siguientes reclamaciones:

  • La reclamación iss (entidad emisora permitida) debe ser la dirección de correo electrónico de la cuenta de servicio, por ejemplo:

    "iss": "SERVICE_ACCOUNT_ID@PROJECT_ID.iam.gserviceaccount.com"
    
  • Las reclamaciones aud (público) y sub (sujeto) deben establecerse en el mismo valor. Esta es una cadena descriptiva que identifica el público esperado para tu servicio, carga de trabajo o app, por ejemplo:

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

    Este valor debe coincidir con el argumento --audiences que se pasó en el momento de la implementación del índice.

  • La reclamación iat (hora de emisión) debe configurarse en el momento en que se emite el token. La reclamación exp (hora de vencimiento) debe establecerse un poco más tarde (alrededor de una hora). Estos valores se expresan en tiempo Unix, por ejemplo:

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

En el siguiente ejemplo, se muestran estas reclamaciones en una sola carga útil de JWT:

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

La carga útil de JWT se firma con la cuenta de servicio especificada en la reclamación iss. Está codificado en base64 para la transmisión como un token del portador mediante los metadatos de gRPC, como se muestra en el siguiente ejemplo, en el que signedJwt es una variable de entorno que contiene un JWT firmado:

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

Crea el JWT

  1. Asegúrate de que tú (el emisor) puedas usar el rol roles/iam.serviceAccountTokenCreator en la cuenta de servicio.

  2. Crea un archivo JSON llamado jwt_in.json que contenga el JWT sin procesar:

    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
    

    Reemplaza los siguientes valores:

    • SERVICE_ACCOUNT_ID: El ID para la cuenta de servicio.
    • PROJECT_ID: El ID del proyecto de Google Cloud.
    • AUDIENCES: Una cadena descriptiva que identifica el público esperado para tu servicio, carga de trabajo o app, por ejemplo, "123456-my-app".

Firma el JWT (API de REST)

  1. Con la herramienta de jq, crea la carga útil de la solicitud curl mediante la codificación del JWT en una cadena:

    cat jwt_in.json | jq -Rsa >request.json
    
  2. Para firmar el token, pasa la carga útil de la solicitud al método de la API de REST signJwt.

    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 \
       "http://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/$SA:signJwt"
    

    Reemplaza los siguientes valores:

    • SERVICE_ACCOUNT_ID: El ID para la cuenta de servicio.
    • PROJECT_ID: El ID del proyecto de Google Cloud.

    Almacena el valor de signedJwt que se muestra en una variable de entorno llamada signedJwt.

Firma el JWT (gcloud CLI)

Como alternativa, puedes firmar el JWT si pasas el archivo jwt_in.json directamente al método sign-jwt de gcloud CLI.

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

Reemplaza los siguientes valores:

  • SERVICE_ACCOUNT_ID: El ID para la cuenta de servicio.
  • PROJECT_ID: El ID del proyecto de Google Cloud.

El JWT firmado se muestra en el archivo de salida jwt_out. Guárdalo en una variable de entorno llamada signedJwt.

Envía el JWT firmado al extremo del índice

Desde una VM de Compute Engine en la misma red de VPC, llama al extremo MatchService gRPC y pasa el token signedJwt en el encabezado authorization, como se muestra en el siguiente ejemplo: :

./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"

Para ejecutar este comando, necesitarás que se configuren las siguientes variables de entorno:

  • TARGET_IP es la dirección IP de tu servidor de índice implementado. Si deseas aprender a recuperar este valor, consulta Consulta índices para obtener los vecinos más cercanos.
  • DEPLOYED_INDEX_ID: Una cadena especificada por el usuario para identificar de forma inequívoca el índice implementado. Debe comenzar con una letra y contener solo letras, números o guiones bajos. Consulta DeployedIndex.id para obtener lineamientos de formato.

signedJwt es la variable de entorno que contiene el JWT firmado.

Soluciona problemas

En la siguiente tabla, se enumeran algunos mensajes de error comunes de gRPC.

Mensaje de error de gRPC Motivo
No se encontró el encabezado de autorización para el índice “INDEX_ID Los metadatos de gRPC no contienen un encabezado de autorización
El JWT no tiene un formato válido El token tiene errores de formato y no se puede analizar correctamente
Error de autenticación de JWT El token venció o no está firmado por la cuenta de servicio correcta
La entidad emisora de JWT debe estar en la lista de entidades emisoras permitidas. El token iss no se encuentra en las entidades emisoras permitidas de auth_config
Falla la verificación de permisos para el índice “INDEX_ID La reclamación aud o sub del token no se encuentra en públicos auth_config

¿Qué sigue?