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 调用查询索引(在授权标头中传递令牌)。
Python
创建和签署 JWT 载荷
此示例使用 Python IAM API 凭据库的 sign_jwt
方法获取已签名令牌。如需详细了解如何安装和使用此库,请参阅 IAM API 客户端库文档。
from google.cloud import iam_credentials_v1
from datetime import datetime, timezone
import json
def sign_jwt(issuer: str, audience: str):
client = iam_credentials_v1.IAMCredentialsClient()
payload = {
'aud': audience,
'sub': audience,
'iss': issuer,
'iat': int(datetime.now(timezone.utc).timestamp()),
'exp': int(datetime.now(timezone.utc).timestamp()) + 600,
}
response = client.sign_jwt(name="projects/-/serviceAccounts/" + issuer,
payload=json.dumps(payload))
return response.signed_jwt
sign_jwt("SERVICE_ACCOUNT_ID@PROJECT_ID.iam.gserviceaccount.com",
"AUDIENCES")
命令行
创建 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
声明中指定的服务账号进行签名。
创建 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 发送到索引端点
Python
如需了解如何安装或更新 Vertex AI SDK for Python,请参阅安装 Vertex AI SDK for Python。 如需了解详情,请参阅 Python API 参考文档。
命令行
从同一 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)
- 了解如何更新和重建索引
- 了解如何监控索引