Cloud Run服务无法关联指定服务账户,默认使用Compute Engine账户问题
问题描述
- 已按照Cloud Run官方指引为服务绑定了具备Automotive Maps API访问权限的指定服务账户,但从Cloud Shell用
curl调用服务时,日志显示服务使用的是默认Compute Engine服务账户,而非绑定的目标账户 - 本地运行应用时,通过设置
GOOGLE_APPLICATION_CREDENTIALS指向服务账户密钥,使用应用默认凭据(ADC)可正常访问Automotive Maps API - 部署到Cloud Run后,执行以下命令调用服务:
curl -H "Authorization: Bearer $(gcloud auth print-identity-token)" https://cloudrunsampleretry-qwuy73xdsq-uc.a.run.app
返回错误:
io.grpc.StatusRuntimeException: PERMISSION_DENIED: Request had insufficient authentication scopes.
- 已知官方明确禁止在Cloud Run服务中设置
GOOGLE_APPLICATION_CREDENTIALS环境变量,不清楚Cloud Run配置哪里出错导致ADC未使用绑定的服务账户
排查与解决步骤
1. 验证Cloud Run服务账户绑定状态
执行命令查看当前服务绑定的服务账户:
gcloud run services describe cloudrunsampleretry-qwuy73xdsq-uc --region=us-central1 --format='value(spec.template.spec.serviceAccountName)'
- 检查输出是否为你指定的目标服务账户(格式为
[账户名]@[项目ID].iam.gserviceaccount.com) - 如果不符,重新部署服务并指定服务账户:
gcloud run deploy cloudrunsampleretry-qwuy73xdsq-uc --image=[你的镜像地址] --service-account=[目标服务账户邮箱] --region=us-central1
2. 确认服务账户权限与OAuth范围
- 确保目标服务账户已被纳入Automotive Maps API白名单并拥有访问权限
- Cloud Run默认会为服务账户添加
https://www.googleapis.com/auth/cloud-platform范围,该范围已覆盖Automotive Maps API的访问需求,无需额外添加特殊范围
3. 检查应用代码的ADC使用逻辑
- 确保代码未硬编码凭据路径或强制加载特定密钥文件,直接使用Google客户端库的默认凭据获取方式:
- Java:
GoogleCredentials.getApplicationDefault() - Python:
google.auth.default()
- Java:
- 代码中绝对不要设置
GOOGLE_APPLICATION_CREDENTIALS环境变量,避免覆盖Cloud Run提供的内置凭据
4. 区分调用身份与服务内部身份
- 你用
gcloud auth print-identity-token生成的令牌是Cloud Shell用户身份,仅用于验证你是否有权访问Cloud Run服务;Cloud Run服务内部调用Automotive Maps API时,使用的是服务自身绑定的服务账户凭据 - 报错信息是服务内部调用API时的权限问题,而非你调用Cloud Run的权限问题
- 可以在服务中添加日志打印当前凭据的账户信息,确认是否为目标账户:
- Java示例:
System.out.println(GoogleCredentials.getApplicationDefault().getAuthentication().getPrincipal()); - Python示例:
credentials, _ = google.auth.default(); print(credentials.service_account_email)
- Java示例:
5. 确认部署更新生效
- Cloud Run部署后可能存在短暂缓存,重新部署后等待2-3分钟再测试
- 查看服务的修订版本,确认最新版本使用的是正确的服务账户
内容的提问来源于stack exchange,提问作者Xueming Zhang
相关产品推荐
相关产品推荐

