Cloud Run跨服务调用IAM配置问题:Terraform部署后持续403错误
Cloud Run跨服务调用403问题的正确IAM配置方案
核心问题定位
你遇到的问题本质是:尽管三个服务共享同一个服务账号,但Gateway发起请求时没有自动携带该服务账号的身份凭证,导致目标服务(auth-service、user-service)无法识别请求身份,因此即使配置了roles/run.invoker权限,仍会返回403未授权。
正确配置步骤
1. 确保目标服务的IAM绑定正确
首先要确认roles/run.invoker权限已绑定到共享服务账号,且作用于auth-service和user-service资源。以下是Terraform配置示例:
# 共享服务账号资源定义 resource "google_service_account" "cloud_run_shared" { account_id = "cloud-run-shared-sa" display_name = "Shared Service Account for Cloud Run Services" } # 给auth-service绑定invoker权限 resource "google_cloud_run_service_iam_binding" "auth_service_invoker" { service = google_cloud_run_service.auth-service.name location = google_cloud_run_service.auth-service.location role = "roles/run.invoker" members = [ "serviceAccount:${google_service_account.cloud_run_shared.email}", ] } # 给user-service绑定invoker权限 resource "google_cloud_run_service_iam_binding" "user_service_invoker" { service = google_cloud_run_service.user-service.name location = google_cloud_run_service.user-service.location role = "roles/run.invoker" members = [ "serviceAccount:${google_service_account.cloud_run_shared.email}", ] }
2. 在Gateway中手动附加身份令牌
Cloud Run服务之间的调用不会自动携带服务账号身份,必须在代码中主动获取ID令牌并附加到请求头:
- 获取令牌时,目标受众(
audience)必须设置为目标服务的完整URL(例如https://auth-service-xxxx.run.app) - 以下是Python示例代码:
import requests from google.auth import default from google.auth.transport.requests import Request def fetch_target_service_token(target_url): # 获取当前服务账号的默认凭证 credentials, _ = default() # 刷新凭证以获取有效的ID令牌 credentials.refresh(Request()) # 返回针对目标服务的ID令牌 return credentials.id_token # 调用auth-service示例 auth_service_endpoint = "https://auth-service-xxxx.run.app/api/verify" token = fetch_target_service_token(auth_service_endpoint) response = requests.get( auth_service_endpoint, headers={"Authorization": f"Bearer {token}"} )
3. 验证配置有效性
- 检查目标服务的IAM策略是否生效:
gcloud run services get-iam-policy auth-service --location=<你的服务区域>
- 查看Gateway服务日志,确认请求头中存在
Authorization: Bearer <token> - 查看目标服务日志,若认证成功,会显示类似
Authenticated user: serviceAccount:cloud-run-shared-sa@<你的项目ID>.iam.gserviceaccount.com的条目
关键误区澄清
- 共享服务账号≠自动认证:Cloud Run服务运行时使用服务账号身份,但发起跨服务请求时,不会自动附加身份凭证,必须手动获取并携带令牌。
- 放开
allUsers权限是临时解决方案:虽然能解决访问问题,但完全暴露服务,不符合生产环境安全要求,必须通过服务账号身份认证来限制访问。
内容的提问来源于stack exchange,提问作者SebastianG
相关产品推荐
相关产品推荐

