JSON 웹 토큰 인증

벡터 검색은 자체 서명 JSON 웹 토큰(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 역할을 부여합니다.

  1. 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

    서비스 계정 만들기에 대해 자세히 알아보세요.

  2. 다음 명령어 중 하나를 사용하여 서비스 계정에 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 인증 구성을 사용하여 엔드포인트에 색인 배포

  1. 다음 예시와 같이 색인을 비공개 엔드포인트에 배포합니다.

    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로 색인 쿼리

개략적으로 필요한 단계는 다음과 같습니다.

  1. JWT 페이로드를 만듭니다.
  2. 앞에서 만든 서비스 계정을 사용하여 토큰에 서명합니다.
  3. gRPC 호출을 사용하고 승인 헤더에 토큰을 전달하여 색인을 쿼리합니다.

JWT 페이로드 만들기

벡터 검색 인증은 사전 정의된 대상 그룹에 대해 사전 승인된 서비스 계정으로 서명된 JWT를 허용합니다. 색인이 비공개 엔드포인트에 배포된 경우 호출자가 서비스 계정과 대상 그룹을 지정해야 합니다. 이러한 설정으로 색인이 배포되면 해당 엔드포인트에 대한 모든 gRPC API 요청에는 발급기관(서비스 계정)이 서명하고 제공된 대상 그룹을 타겟으로 하는 JWT가 포함된 인증 헤더가 포함되어야 합니다. 서명된 JWT는 gRPC 요청의 authorization 헤더에 Bearer 토큰으로 전달됩니다. 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시간)으로 설정되어야 합니다. 이 값은 유닉스 시간으로 표현됩니다. 예를 들면 다음과 같습니다.

    "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 클레임에 지정된 서비스 계정을 사용하여 서명됩니다. 다음 예시에 표시된 것처럼 gRPC 메타데이터를 사용하여 Bearer 토큰으로 전송하도록 base64로 인코딩됩니다. 여기서 signedJwt는 서명된 JWT를 포함하는 환경 변수입니다.

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

JWT 만들기

  1. 사용자(호출자)가 서비스 계정에서 roles/iam.serviceAccountTokenCreator 역할을 사용할 수 있는지 확인합니다.

  2. 원시 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) 서명

  1. jq 도구로 JWT를 문자열로 인코딩하여 curl 요청 페이로드를 만듭니다.

    cat jwt_in.json | jq -Rsa >request.json
    
  2. 요청 페이로드를 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 \
       "http://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 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' 색인의 승인 헤더를 찾을 수 없음 gRPC 메타데이터에 승인 헤더가 없습니다.
JWT 형식이 잘못됨 토큰 형식이 잘못되어 올바르게 파싱할 수 없습니다.
JWT 인증 실패 토큰이 만료되었거나 올바른 서비스 계정으로 서명되지 않았습니다.
JWT 발급기관이 허용된 발급기관 목록에 있어야 함 iss 토큰이 auth_config 허용된 발급기관에 없습니다.
'INDEX_ID' 색인의 권한 검사 실패 토큰 aud 또는 sub 클레임이 auth_config 대상 그룹에 없습니다.

다음 단계