Vector Search 支持使用自签名 JSON Web 令牌 (JWT) 进行身份验证的索引端点。 为了控制对索引端点的访问,它配置为仅接受由明确授权的 Google 服务账号颁发的已签名 JWT。 这意味着只有使用这些指定账号的客户端才能与端点进行交互。
本页面概述了使用 JSON Web 令牌 (JWT) 身份验证设置索引端点并对其运行查询所需的步骤。
限制
- 只有具备 VPC 对等互连或 Private Service Connect (PSC) 的专用端点才支持 JWT 身份验证。
- 只有使用 gRPC 调用的数据平面 RPC API(例如 MatchService)才支持 JWT 身份验证。本页面中的 RPC 示例使用开源
grpc_cli
工具将 gRPC 请求发送到所部署的索引服务器。 - 用于创建、部署和管理索引的 Admin API 使用预定义 IAM 角色进行保护。
创建索引并使用 JWT 进行查询
请按照以下步骤创建索引端点,并使用自签名 JWT 查询该端点。
创建索引
按照创建索引中的说明创建 Vector Search 索引。
创建专用端点
按照以下某个文档页面中的说明创建专用端点:
创建服务账号
创建服务账号并向其授予 Service Account Token Creator IAM 角色。
启用 IAM Service Account Credentials API 并创建服务账号:
gcloud services enable iamcredentials.googleapis.com --project="PROJECT_ID" gcloud iam service-accounts create SERVICE_ACCOUNT_ID --project="PROJECT_ID"
替换以下值:
- PROJECT_ID:要在其中创建服务账号的项目。
- SERVICE_ACCOUNT_ID:服务账号的 ID。
详细了解如何创建服务账号。
使用以下命令之一向您的服务账号授予
iam.serviceAccountTokenCreator
IAM 角色:以下命令授权您使用来自关联了服务账号的 Compute Engine 虚拟机的服务账号创建 JWT:
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"
替换以下值:
- SERVICE_ACCOUNT_ID:服务账号的 ID。
- PROJECT_ID:要在其中创建服务账号的项目。
以下命令授权您使用来自您自己的 Google 账号(在您的工作站上)的服务账号创建 JWT:
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
替换以下值:
- SERVICE_ACCOUNT_ID:服务账号的 ID。
- PROJECT_ID:要在其中创建服务账号的项目。
- EMAIL_ADDRESS:您的电子邮件地址。
使用 JWT 身份验证配置将索引部署到端点
将索引部署到专用端点,如以下示例所示:
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
替换以下值:
- INDEX_ENDPOINT_ID:索引端点的 ID。
- INDEX_ID:索引的 ID。
- DEPLOYED_INDEX_ID:用户指定的字符串,用于唯一标识已部署的索引。必须以字母开头,并且只包含字母、数字或下划线。如需了解格式准则,请参阅 DeployedIndex.id。
- DEPLOYED_INDEX_NAME:已部署索引的显示名称。
- AUDIENCES:用于标识服务、工作负载或应用的预期目标对象的描述性字符串,例如
"123456-my-app"
。 - SERVICE_ACCOUNT_ID:服务账号的 ID。
- PROJECT_ID:您的 Google Cloud 项目 ID。
- LOCATION:您在其中使用 Vertex AI 的区域。
使用自签名 JWT 查询索引
概括来讲,所需步骤如下:
- 创建 JWT 载荷。
- 使用先前创建的服务账号对令牌签名。
- 使用 gRPC 调用查询索引(在授权标头中传递令牌)。
创建 JWT 载荷
Vector Search 身份验证接受使用预先授权的服务账号签名的 JWT 以用于预定义的目标对象。服务账号和目标对象必须在索引部署到专用端点时,由调用者指定。
使用这些设置部署索引后,发送到该端点的所有 gRPC API 请求都需要包含一个授权标头,其中包含由颁发者(服务账号)签名并针对所提供的目标对象的 JWT。已签名的 JWT 在 gRPC 请求的 authorization
标头中以不记名令牌形式进行传递。除了由服务账号签名之外,JWT 还必须包含以下声明:
iss
(允许的颁发者)声明应该是服务账号电子邮件地址,例如:"iss": "SERVICE_ACCOUNT_ID@PROJECT_ID.iam.gserviceaccount.com"
aud
(目标对象)和sub
(主题)声明应设置为相同的值。这是用于标识服务、工作负载或应用的预期目标对象的描述性字符串,例如:"aud": "123456-my-app", "sub": "123456-my-app"
此值必须与在索引部署时传递的
--audiences
参数匹配。iat
(颁发时间)声明应设置为颁发令牌的时间。exp
(到期时间)声明应设置为随后的较短时间(大约一小时)。这些值以 Unix 纪元时间表示,例如:"iat": 1698966927, // unix time since epoch eg via date +%s "exp": 1698967527 // iat + a few mins (eg 600 seconds)
以下示例显示单个 JWT 载荷中的这些声明:
{
"iss": "SERVICE_ACCOUNT_ID@PROJECT_ID.iam.gserviceaccount.com",
"aud": "123456-my-app",
"sub": "123456-my-app",
"iat": 1698956084,
"exp": 1698960084
}
JWT 载荷使用 iss
声明中指定的服务账号进行签名。它采用 base64 编码,使用 gRPC 元数据以不记名令牌形式传输,如以下示例所示,其中 signedJwt
是包含已签名 JWT 的环境变量:
./grpc_cli call ... --metadata "authorization: Bearer $signedJwt"
创建 JWT
确保您(调用者)可以对服务账号使用
roles/iam.serviceAccountTokenCreator
角色。创建名为
jwt_in.json
且包含原始 JWT 的 JSON 文件: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
替换以下值:
- SERVICE_ACCOUNT_ID:服务账号的 ID。
- PROJECT_ID:您的 Google Cloud 项目 ID。
- AUDIENCES:用于标识服务、工作负载或应用的预期目标对象的描述性字符串,例如
"123456-my-app"
。
对 JWT 签名 (REST API)
使用
jq
工具,通过将 JWT 编码为字符串来创建curl
请求载荷:cat jwt_in.json | jq -Rsa >request.json
通过将请求载荷传递给 signJwt REST API 方法来对令牌签名。
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"
替换以下值:
- SERVICE_ACCOUNT_ID:服务账号的 ID。
- PROJECT_ID:您的 Google Cloud 项目 ID。
将返回的
signedJwt
值存储到名为signedJwt
的环境变量中。
对 JWT 签名 (gcloud CLI)
或者,您可以通过将 jwt_in.json
文件直接传递给 gcloud CLI sign-jwt
方法来对 JWT 签名。
gcloud iam service-accounts sign-jwt jwt_in.json jwt_out \
--iam-account=SERVICE_ACCOUNT_ID@PROJECT_ID.iam.gserviceaccount.com
替换以下值:
- SERVICE_ACCOUNT_ID:服务账号的 ID。
- PROJECT_ID:您的 Google Cloud 项目 ID。
已签名的 JWT 会在 jwt_out
输出文件中返回。将其存储到名为 signedJwt
的环境变量中。
将已签名的 JWT 发送到索引端点
从同一 VPC 网络中的 Compute Engine 虚拟机调用 MatchService
gRPC
端点(在 authorization
标头中传递 signedJwt
令牌),如以下示例所示:
./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"
如需运行此命令,您需要设置以下环境变量:
- TARGET_IP 是所部署的索引服务器的 IP 地址。如需了解如何检索此值,请参阅查询索引以获取最近邻。
- DEPLOYED_INDEX_ID:用户指定的字符串,用于唯一标识已部署的索引。必须以字母开头,并且只包含字母、数字或下划线。如需了解格式准则,请参阅 DeployedIndex.id。
signedJwt
是包含已签名 JWT 的环境变量。
问题排查
下表列出了一些常见 gRPC
错误消息。
gRPC 错误消息 | 原因 |
---|---|
找不到用于索引“INDEX_ID”的授权标头 | gRPC 元数据不包含授权标头 |
JWT 格式无效 | 令牌格式不正确,无法正确解析 |
JWT 身份验证失败 | 令牌已过期或者并非由正确的服务账号签名 |
JWT 颁发者应处于允许的颁发者列表中 | 令牌 iss 不在 auth_config 允许的颁发者中 |
针对索引“INDEX_ID”的权限检查失败 | 令牌 aud 或 sub 声明不在 auth_config 目标对象中 |
后续步骤
- 如需详细了解 JWT 和令牌声明结构,请参阅 RFC 7519。
- 详细了解如何创建自签名 JSON Web 令牌 (JWT)
- 了解如何更新和重建索引
- 了解如何监控索引