Autenticação do JSON Web Token

A pesquisa de vetor oferece suporte a endpoints de índice autenticados usando JSON Web Tokens (JWTs) autoassinados. Para controlar o acesso ao endpoint do índice, ele é configurado para aceitar apenas JWTs assinados emitidos por contas de serviço do Google especificamente autorizadas. Isso significa que apenas os clientes que usam as contas designadas podem interagir com o endpoint.

Nesta página, descrevemos as etapas necessárias para configurar um endpoint de índice com a autenticação JSON Web Token (JWT) e executar consultas nele.

Limitações

  • A autenticação JWT é compatível apenas com endpoints particulares com peering de VPC ou Private Service Connect (PSC).
  • A autenticação JWT é compatível apenas com APIs RPC do plano de dados (como MatchService) que são invocadas usando o gRPC. Os exemplos de RPC nesta página usam a ferramenta de código aberto grpc_cli para enviar solicitações gRPC ao servidor de índice implantado.
  • As APIs Admin para criação, implantação e gerenciamento de índices são protegidas pelo uso de papéis predefinidos do IAM.

Como criar e usar um JWT para consultar um índice

Siga estas etapas para criar um endpoint de índice e consultá-lo com um JWT autoassinado.

Criar um índice

Crie um índice de pesquisa de vetor seguindo as instruções em Criar um índice.

Criar um endpoint particular

Crie um endpoint particular seguindo as instruções em uma das seguintes páginas de documentação:

Crie uma conta de serviço

Crie uma conta de serviço e conceda a ela o papel do IAM de Criador de token de conta de serviço.

  1. Ative a API Service Account Credentials do IAM e crie uma conta de serviço:

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

    Substitua os seguintes valores:

    • PROJECT_ID: o projeto em que a conta de serviço será criada.
    • SERVICE_ACCOUNT_ID: o ID da conta de serviço.

    Saiba mais sobre como criar uma conta de serviço.

  2. Use um dos seguintes comandos para conceder o papel do IAM iam.serviceAccountTokenCreator à sua conta de serviço:

    • O comando a seguir dá permissão para criar JWTs usando a conta de serviço de uma VM do Compute Engine que tem a conta de serviço anexada a ela:

      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"
      

      Substitua os seguintes valores:

      • SERVICE_ACCOUNT_ID: o ID da conta de serviço.
      • PROJECT_ID: o projeto em que a conta de serviço será criada.
    • O comando a seguir concede permissão para criar JWTs usando a conta de serviço da sua Conta do Google (na estação de trabalho):

      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
      

      Substitua os seguintes valores:

      • SERVICE_ACCOUNT_ID: o ID da conta de serviço.
      • PROJECT_ID: o projeto em que a conta de serviço será criada.
      • EMAIL_ADDRESS: seu endereço de e-mail

Implante o índice no endpoint com a configuração de autenticação do JWT

  1. Implante o índice no endpoint particular, conforme mostrado no exemplo a seguir:

    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
    

    Substitua os seguintes valores:

    • INDEX_ENDPOINT_ID: o ID do endpoint do índice.
    • INDEX_ID: o ID do índice.
    • DEPLOYED_INDEX_ID: uma string especificada pelo usuário para identificar de maneira exclusiva o índice implantado. Ela precisa começar com uma letra e conter apenas letras, números ou sublinhados. Consulte DeployedIndex.id para ver as diretrizes de formato.
    • DEPLOYED_INDEX_NAME: nome de exibição do índice implantado.
    • AUDIENCES: uma string descritiva que identifica o público esperado para seu serviço, carga de trabalho ou app, por exemplo, "123456-my-app".
    • SERVICE_ACCOUNT_ID: o ID da conta de serviço.
    • PROJECT_ID: o ID do projeto do Google Cloud.
    • LOCATION: a região em que você está usando a Vertex AI.

Consultar o índice com um JWT autoassinado

De modo geral, estas são as etapas necessárias:

  1. Crie um payload do JWT.
  2. Assine o token usando a conta de serviço criada anteriormente.
  3. Consulte o índice usando uma chamada gRPC, passando o token no cabeçalho de autorização.

Criar o payload do JWT

A autenticação de pesquisa de vetor aceita JWTs assinados com uma conta de serviço pré-autorizada, para um público-alvo predefinido. A conta de serviço e o público precisam ser especificados pelo autor da chamada quando um índice é implantado em um endpoint particular. Depois que um índice é implantado com essas configurações, todas as solicitações da API gRPC para esse endpoint precisam incluir um cabeçalho de autorização contendo um JWT assinado pelo emissor (uma conta de serviço) e direcionado para o 101}público-alvo fornecido. O JWT assinado é transmitido como um token do portador no cabeçalho authorization da solicitação gRPC. Além de ser assinado pela conta de serviço, o JWT precisa incluir as seguintes declarações:

  • A declaração iss (emissor permitido) precisa ser o endereço de e-mail da conta de serviço, por exemplo:

    "iss": "SERVICE_ACCOUNT_ID@PROJECT_ID.iam.gserviceaccount.com"
    
  • As declarações aud (público-alvo) e sub (assunto) precisam ser definidas com o mesmo valor. Essa é uma string descritiva que identifica o público esperado para seu serviço, carga de trabalho ou app, por exemplo:

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

    Esse valor precisa corresponder ao argumento --audiences que foi transmitido no momento da implantação do índice.

  • A reivindicação iat (emitida em) precisa ser definida como o horário em que o token é emitido. A declaração exp (prazo de validade) precisa ser definida para pouco tempo depois (cerca de uma hora). Esses valores são expressos em tempo de época Unix, por exemplo:

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

O exemplo a seguir mostra essas declarações em um único payload JWT:

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

O payload do JWT é assinado usando a conta de serviço especificada na declaração iss. Ele é codificado em base64 para transmissão como um token do portador usando os metadados gRPC, conforme mostrado no exemplo a seguir, em que signedJwt é uma variável de ambiente que contém um JWT assinado:

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

Criar o JWT

  1. Verifique se você (o autor da chamada) pode usar o papel roles/iam.serviceAccountTokenCreator na conta de serviço.

  2. Crie um arquivo JSON chamado jwt_in.json que contenha o JWT bruto:

    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
    

    Substitua os seguintes valores:

    • SERVICE_ACCOUNT_ID: o ID da conta de serviço.
    • PROJECT_ID: o ID do projeto do Google Cloud.
    • AUDIENCES: uma string descritiva que identifica o público esperado para seu serviço, carga de trabalho ou app, por exemplo, "123456-my-app".

Assinar o JWT (API REST)

  1. Com a ferramenta jq, crie o payload da solicitação curl codificando o JWT em uma string:

    cat jwt_in.json | jq -Rsa >request.json
    
  2. Assine o token transmitindo o payload da solicitação para o método da API 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 \
       "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/$SA:signJwt"
    

    Substitua os seguintes valores:

    • SERVICE_ACCOUNT_ID: o ID da conta de serviço.
    • PROJECT_ID: o ID do projeto do Google Cloud.

    Armazene o valor signedJwt retornado em uma variável de ambiente chamada signedJwt.

Assinar o JWT (CLI gcloud)

Como alternativa, é possível assinar o JWT transmitindo o arquivo jwt_in.json diretamente para o método sign-jwt da CLI gcloud.

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

Substitua os seguintes valores:

  • SERVICE_ACCOUNT_ID: o ID da conta de serviço.
  • PROJECT_ID: o ID do projeto do Google Cloud.

O JWT assinado é retornado no arquivo de saída jwt_out. Armazene-o em uma variável de ambiente chamada signedJwt.

Enviar o JWT assinado para o endpoint do índice

Em uma VM do Compute Engine na mesma rede VPC, chame o endpoint MatchService gRPC, passando o token signedJwt no cabeçalho authorization, como mostrado no exemplo a seguir:

./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 executar o comando, configure as variáveis de ambiente a seguir:

  • TARGET_IP é o endereço IP do servidor de índice implantado. Para saber como recuperar esse valor, consulte Índices de consulta para encontrar os vizinhos mais próximos.
  • DEPLOYED_INDEX_ID: uma string especificada pelo usuário para identificar de maneira exclusiva o índice implantado. Ela precisa começar com uma letra e conter apenas letras, números ou sublinhados. Consulte DeployedIndex.id para ver as diretrizes de formato.

signedJwt é a variável de ambiente que contém o JWT assinado.

Solução de problemas

A tabela a seguir lista algumas mensagens de erro comuns do gRPC.

Mensagem de erro do gRPC Motivo
Cabeçalho de autorização não encontrado para o índice "INDEX_ID" Os metadados gRPC não contêm um cabeçalho de autorização
O formato do JWT é inválido O token é inválido e não pode ser analisado corretamente
Falha na autenticação do JWT O token expirou ou não está assinado pela conta de serviço correta
O emissor do JWT deve estar na lista de emissores permitidos O token iss não está em auth_config emissores permitidos
Falha na verificação de permissão do índice "INDEX_ID" A reivindicação do token aud ou sub não está em auth_config públicos-alvo

A seguir