无法生成服务令牌:iam.serviceAccounts.getOpenIdToken权限被拒求助
Cloud Run服务间认证:获取ID令牌报403权限错误的排查与解决
问题描述
在进行Cloud Run服务间认证操作时,无论是通过API调用还是Python库获取身份令牌,均返回403错误,提示权限iam.serviceAccounts.getOpenIdToken在资源上被拒绝(或资源不存在)。
API调用报错:
$ curl "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/identity?audience=abc-def-api-4yuwqeg56fq-ew.a.run.app" -H "Metadata-Flavor: Google" Failed to generate identity token; IAM returned 403 Forbidden: Permission 'iam.serviceAccounts.getOpenIdToken' denied on resource (or it may not exist).
Python库调用报错:
>>> id_token = google.oauth2.id_token.fetch_id_token(auth_req, audience) Traceback (most recent call last): File "/usr/local/lib/python3.10/dist-packages/google/auth/compute_engine/credentials.py", line 377, in _call_metadata_identity_endpoint id_token = _metadata.get(request, path, params=params) File "/usr/local/lib/python3.10/dist-packages/google/auth/compute_engine/_metadata.py", line 182, in get raise exceptions.TransportError( google.auth.exceptions.TransportError: ('Failed to retrieve http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/identity?audience=https%3A%2F%2Fabc-def-api-4yuwqeg56fq-ew.a.run.app&format=full from the Google Compute Engine metadata service. Status: 403 Response: b"Failed to generate identity token; IAM returned 403 Forbidden: Permission \'iam.serviceAccounts.getOpenIdToken\' denied on resource (or it may not exist).\n"', <google.auth.transport.requests._Response object at 0x7f4c9f9aa7d0>) The above exception was the direct cause of the following exception: Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/local/lib/python3.10/dist-packages/google/oauth2/id_token.py", line 340, in fetch_id_token id_token_credentials.refresh(request) File "/usr/local/lib/python3.10/dist-packages/google/auth/compute_engine/credentials.py", line 398, in refresh self.token, self.expiry = self._call_metadata_identity_endpoint(request) File "/usr/local/lib/python3.10/dist-packages/google/auth/compute_engine/credentials.py", line 380, in _call_metadata_identity_endpoint six.raise_from(new_exc, caught_exc) File "<string>", line 3, in raise_from google.auth.exceptions.RefreshError: ('Failed to retrieve http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/identity?audience=https%3A%2F%2Fabc-def-api-4yuwqeg56fq-ew.a.run.app&format=full from the Google Compute Engine metadata service. Status: 403 Response: b"Failed to generate identity token; IAM returned 403 Forbidden: Permission \'iam.serviceAccounts.getOpenIdToken\' denied on resource (or it may not exist).\n"', <google.auth.transport.requests._Response object at 0x7f4c9f9aa7d0>) >>>
排查与解决步骤
1. 为服务账号添加Service Account Token Creator角色
iam.serviceAccounts.getOpenIdToken权限包含在Service Account Token Creator角色中,需给当前使用的服务账号(Cloud Run绑定的服务账号或本地测试账号)添加该角色:
- 命令行操作:
gcloud projects add-iam-policy-binding YOUR_PROJECT_ID \ --member="serviceAccount:YOUR_SERVICE_ACCOUNT_EMAIL" \ --role="roles/iam.serviceAccountTokenCreator" - 控制台操作:进入Google Cloud控制台IAM页面,找到目标服务账号,点击编辑,添加
Service Account Token Creator角色并保存。
2. 验证Audience参数的正确性
- 确保
audience是目标Cloud Run服务的完整HTTPS URL(必须包含https://前缀),例如https://abc-def-api-4yuwqeg56fq-ew.a.run.app,避免因URL拼写错误或缺少协议头触发资源不存在提示。 - 确认目标Cloud Run服务已正常部署且URL可访问。
3. 确认当前使用的服务账号身份
- 在Cloud Run内部环境,可通过以下命令查看当前服务使用的服务账号:
curl http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/email -H "Metadata-Flavor: Google" - 本地测试时,用
gcloud auth list查看当前授权账号,若不符则通过gcloud auth activate-service-account切换到有权限的服务账号。
4. 等待IAM权限生效
IAM权限变更通常需要1-2分钟才能完全生效,添加角色后请等待片刻再重试操作。
内容的提问来源于stack exchange,提问作者Moni
相关产品推荐
相关产品推荐

