Python 使用谷歌计算引擎默认服务帐户签署谷歌云存储URL

Python 使用谷歌计算引擎默认服务帐户签署谷歌云存储URL,python,google-cloud-storage,google-compute-engine,google-iam,Python,Google Cloud Storage,Google Compute Engine,Google Iam,我正在尝试使用GCE默认服务帐户对GCS URL进行签名。我给了计算默认服务帐户必要的“服务帐户令牌创建者”角色。在以下Python代码中尝试对url进行签名时,出现错误: 导入google.auth 导入google.auth.iam 从google.auth.transport.requests导入请求作为gRequest creds,z=google.auth.default(request=gRequest(),作用域=[ 'https://www.googleapis.com/auth

我正在尝试使用GCE默认服务帐户对GCS URL进行签名。我给了计算默认服务帐户必要的“服务帐户令牌创建者”角色。在以下Python代码中尝试对url进行签名时,出现错误:

导入google.auth
导入google.auth.iam
从google.auth.transport.requests导入请求作为gRequest
creds,z=google.auth.default(request=gRequest(),作用域=[
'https://www.googleapis.com/auth/cloud-platform',
'https://www.googleapis.com/auth/devstorage.read_write',
'https://www.googleapis.com/auth/logging.write',
'https://www.googleapis.com/auth/firebase',
'https://www.googleapis.com/auth/compute.readonly',
'https://www.googleapis.com/auth/userinfo.email',
])
##creds是一个google.auth.compute\u引擎.credentials.credentials
##creds.service\u帐户\u电子邮件是'-compute@developer.gserviceaccount.com'
signer=google.auth.iam.signer(
gRequest(),凭证=凭证,
服务\帐户\电子邮件=信用卡。服务\帐户\电子邮件)
signer.sign('stuff'))
错误:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  <TRUNCATED - my code>
  File "/usr/local/lib/python3.6/dist-packages/google/auth/iam.py", line 101, in sign
    response = self._make_signing_request(message)
  File "/usr/local/lib/python3.6/dist-packages/google/auth/iam.py", line 85, in _make_signing_request
    response.data))
google.auth.exceptions.TransportError: Error calling the IAM signBytes API: b'{\n  "error": {\n    "code": 400,\
n    "message": "Invalid service account email (default).",\n    "status": "INVALID_ARGUMENT"\n  }\n}\n'
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
文件“/usr/local/lib/python3.6/dist-packages/google/auth/iam.py”,第101行,符号中
响应=自我。发出签名请求(消息)
文件“/usr/local/lib/python3.6/dist packages/google/auth/iam.py”,第85行,在“签名请求”中
答复(数据))
google.auth.exceptions.TransportError:调用IAM signBytes API时出错:b'{\n“错误”:{\n“代码”:400\
n“消息”:“无效服务帐户电子邮件(默认)。”,\n“状态”:“无效\u参数”\n}\n}\n'

是否不允许使用GCE默认SA?是否有其他不允许的默认SA(特别是Google App Engine Flexible SA)?

您需要两个角色。其中一个您无法在谷歌云控制台中授予您的默认GCE服务帐户。记下您要使用的服务帐户电子邮件地址

[更新日期:2019年1月19日]

创建凭据时,在需要时才会初始化凭据(例如,不请求访问令牌)。要预初始化凭据,请执行以下操作:

auth_url = "https://www.googleapis.com/oauth2/v4/token"
headers = {}
request = google.auth.transport.requests.Request()
creds.before_request(request, "POST", auth_url, headers)
[结束更新]

授予您的服务帐户角色
roles/iam.servicecomports.signBlob

gcloud projects add-iam-policy-binding <project-id> --member=serviceAccount:<project-id>-compute@developer.gserviceaccount.com --role=roles/iam.serviceAccounts.signBlob
现在,此服务帐户可以使用此服务帐户创建令牌。在命令中,您授予第一个服务帐户电子邮件使用第二个服务帐户电子邮件的权限。将此视为授权。请注意,一个角色位于项目级别,另一个角色分配给服务帐户本身


在我的代码中,我实际上创建了一个新的服务帐户,并使用该服务帐户的电子邮件地址进行签名。我向新服务帐户授予权限(使用第一个命令),并向新服务帐户授予使用凭据的权限(使用第二个命令)

我给了计算默认服务帐户必要的“服务帐户令牌创建者”角色。我认为这实际上可能是因为试图在credentials对象有机会从元数据服务器获取服务帐户信息之前使用它。结果是,
creds.service\u account\u email
返回
“默认值”
,直到它获取该信息为止。@ScottCrunkleton-我不确定你想告诉我什么。我用你的service account email address问题的解决方案更新了我的答案。
gcloud iam service-accounts add-iam-policy-binding <project-id>-compute@developer.gserviceaccount.com --member=<project-id>-compute@developer.gserviceaccount.com --role=roles/iam.serviceAccountTokenCreator