ベクトル検索は、自己署名 JSON Web Token(JWT)を使用して認証済みインデックス エンドポイントをサポートします。インデックス エンドポイントへのアクセスを制御するために、特別に承認された Google サービス アカウントによって発行された署名付き JWT のみを受け入れるように構成されています。つまり、指定されたアカウントを使用するクライアントのみが、エンドポイントと通信できます。
このページでは、JSON ウェブトークン(JWT)認証を使用してインデックス エンドポイントを設定し、それに対してクエリを実行するために必要な手順について説明します。
制限事項
- JWT 認証は、VPC ピアリングまたは Private Service Connect(PSC)を使用するプライベート エンドポイントでのみサポートされます。
- JWT 認証は、gRPC を使用して呼び出されるデータプレーン RPC API(MatchService など)でのみサポートされます。このページの RPC の例では、オープンソースの
grpc_cli
ツールを使用して、デプロイされたインデックス サーバーに gRPC リクエストを送信します。 - インデックスの作成、デプロイ、管理用の Admin API は、事前定義された IAM ロールを使用して保護されています。
インデックスに対してクエリを実行する JWT の作成と使用
インデックス エンドポイントを作成し、自己署名 JWT を使用してクエリを実行する手順は次のとおりです。
インデックスの作成
インデックスを作成するの手順に沿って、ベクトル検索インデックスを作成します。
プライベート エンドポイントを作成する
次のいずれかのドキュメント ページの手順に沿って、プライベート エンドポイントを作成します。
サービス アカウントを作成する
サービス アカウントを作成し、サービス アカウント トークン作成者の 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 VM からサービス アカウントを使用して 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 ペイロードを作成する
ベクトル検索認証は、事前定義されたオーディエンスについて、事前承認されたサービス アカウントで署名された 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
(有効期限)クレームは少し後(約 1 時間)に設定する必要があります。これらの値は、次のように 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 を含む
jwt_in.json
という名前の 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 VM から、次の例に示すように、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」の Authorization ヘッダーが見つかりません | gRPC メタデータに認証ヘッダーが含まれていません |
JWT の形式が無効です | トークンが不正な形式で、正しく解析できません |
JWT 認証に失敗しました | トークンの有効期限が切れているか、正しいサービス アカウントによって署名されていません |
JWT 発行者が、許可された発行者のリストに含まれている必要があります | トークン iss は、許可された発行元 auth_config にありません |
インデックス「INDEX_ID」の権限チェックが失敗しました | トークン aud または sub クレームが auth_config オーディエンスにありません。 |
次のステップ
- JWT とトークン クレーム構造の詳細について、RFC 7519 を確認する。
- 自己署名 JSON ウェブトークン(JWT)を作成する方法を学習する。
- インデックスの更新と再構築の方法を学ぶ。
- インデックスのモニタリング方法を学習する