私の GCP プロジェクトでは、docker コンテナで (connexion を使用して) Python API を実行しています。API Gateway を使用して (API キーを使用して) API を公開したいと考えています。
で docker コンテナーをデプロイすると、ゲートウェイ経由で API 呼び出し--ingress internal
が行われます。Access is forbidden.
そのため、API ゲートウェイは Google Run コンテナにアクセスできません。を使用する--ingress all
と、すべてが期待どおりに機能しますが、内部 API は Web からアクセスできますが、これは私が望んでいるものではありません。
このためのサービス アカウントを作成しました。
gcloud iam service-accounts create $SERVICE_ACCOUNT_ID \
# --description="the api gateway user" \
# --display-name="api gateway user"
... アカウントにrun.invoker
許可を与えました:
gcloud projects add-iam-policy-binding $PROJECT_ID \
--role=roles/run.invoker --member \
serviceAccount:$SERVICE_ACCOUNT_EMAIL
...そして、サービス アカウントを使用して API 構成を作成しました。
gcloud api-gateway api-configs create $CONFIG_ID \
--api=$API_ID --openapi-spec=$API_DEFINITION \
--project=$PROJECT_ID --backend-auth-service-account=$SERVICE_ACCOUNT_EMAIL
しかし、API Gateway から docker API にアクセスできません。ここで何が欠けていますか?API Gateway が内部的に接続できるように、API を保護するにはどうすればよいですか。
Update1: 実行サービスにもロールを適用しました:
gcloud run services add-iam-policy-binding $SERVICE_ID \
--region $REGION --member="serviceAccount:$SERVICE_ACCOUNT_EMAIL" \
--role="roles/run.invoker"
Update2: John Hanley のリクエストによる追加情報:
私のゲートウェイ yml は次のようになります。
swagger: '2.0'
info:
title: "title"
description: "description"
version: "0.1"
schemes:
- https
x-google-backend:
address: <CLOUD_RUN_SERVICE_URL>
paths:
/api:
post:
operationId: api
consumes:
- application/json
produces:
- application/json
security:
- api_key: []
parameters:
- in: body
name: request
description: request
required: true
schema:
$ref: '#/definitions/Request'
responses:
200:
description: "success"
400:
description: "bad data"
503:
description: "internal error"
definitions:
Request:
properties:
parameter1:
type: string
parameter1:
type: string
required:
- parameter1
securityDefinitions:
api_key:
type: "apiKey"
name: "key"
in: "query"
gcloud api-gateway api-configs describe api-config --api api-api
createTime: '2021-06-12T15:02:27.382098034Z'
displayName: api-config
gatewayServiceAccount: projects/-/serviceAccounts/apigatewayuser@projectid.iam.gserviceaccount.com
name: projects/722514052893/locations/global/apis/api-api/configs/api-config
serviceConfigId: api-config-3hytlxf4gfvzj
state: ACTIVE
updateTime: '2021-06-12T15:05:09.778404414Z'
gcloud api-gateway gateways describe api-gateway --location europe-west1
apiConfig: projects/722514052893/locations/global/apis/api-api/configs/api-config
createTime: '2021-06-12T15:06:03.383002459Z'
defaultHostname: api-gateway-97x27n6l.ew.gateway.dev
displayName: api-gateway
name: projects/projectid/locations/europe-west1/gateways/api-gateway
state: ACTIVE
updateTime: '2021-06-12T15:07:37.590520122Z'
gcloud run services describe api --region europe-west1
✔ Service api in region europe-west1
URL: https://api-o3rf5h4boa-ew.a.run.app
Ingress: internal
Traffic:
100% LATEST (currently api-00010-lig)
Last updated on 2021-06-12T17:42:49.913232Z by myemail@gmail.com:
Revision api-00010-lig
Image: gcr.io/projectid/api
Port: 8080
Memory: 512Mi
CPU: 1000m
Concurrency: 80
Max Instances: 100
Timeout: 300s
Cloud Run で直接デバッグを試みました:
gcloud iam service-accounts keys create $KEY_FILE --iam-account=$SERVICE_ACCOUNT_EMAIL
gcloud auth activate-service-account $SERVICE_ACCOUNT_EMAIL --key-file $KEY_FILE
BEARER=$(gcloud auth print-identity-token $SERVICE_ACCOUNT_EMAIL)
curl --header "Content-Type: application/json" \
--header "Authorization: bearer $BEARER" \
--request POST \
--data '{"parameter1":"somedata"}' \
$SERVICE_URL/api
結果は依然として禁止されています:
<!DOCTYPE html>
<html lang=en>
<meta charset=utf-8>
<meta name=viewport content="initial-scale=1, minimum-scale=1, width=device-width">
<title>Error 403 (Forbidden)!!1</title>
<style>
*{margin:0;padding:0}html,code{font:15px/22px arial,sans-serif}html{background:#fff;color:#222;padding:15px}body{margin:7% auto 0;max-width:390px;min-height:180px;padding:30px 0 15px}* > body{background:url(//www.google.com/images/errors/robot.png) 100% 5px no-repeat;padding-right:205px}p{margin:11px 0 22px;overflow:hidden}ins{color:#777;text-decoration:none}a img{border:0}@media screen and (max-width:772px){body{background:none;margin-top:0;max-width:none;padding-right:0}}#logo{background:url(//www.google.com/images/branding/googlelogo/1x/googlelogo_color_150x54dp.png) no-repeat;margin-left:-5px}@media only screen and (min-resolution:192dpi){#logo{background:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) no-repeat 0% 0%/100% 100%;-moz-border-image:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) 0}}@media only screen and (-webkit-min-device-pixel-ratio:2){#logo{background:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) no-repeat;-webkit-background-size:100% 100%}}#logo{display:inline-block;height:54px;width:150px}
</style>
<a href=//www.google.com/><span id=logo aria-label=Google></span></a>
<p><b>403.</b> <ins>That’s an error.</ins>
<p>Access is forbidden. <ins>That’s all we know.</ins>
したがって、問題はサービス アカウントが Cloud Run アプリケーションにアクセスできないことにあります。run.invoker
役割が実行サービスに追加されたため、これが機能しない理由はわかりません。