我正在尝试使用GCE默认服务帐户来签名GCS URL。我为计算默认服务帐户赋予了必要的“服务帐户令牌创建者”角色。当我尝试在以下Python代码中签名url时,出现错误:
import google.auth
import google.auth.iam
from google.auth.transport.requests import Request as gRequest
creds, _ = google.auth.default(request=gRequest(), scopes=[
'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 is a google.auth.compute_engine.credentials.Credentials
## creds.service_account_email is '<project-id>-compute@developer.gserviceaccount.com'
signer = google.auth.iam.Signer(
gRequest(), credentials=creds,
service_account_email=creds.service_account_email)
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'
是否不允许使用GCE默认SA?是否有其他不允许的默认SA(特别是Google App Engine Flexible SA)?
答案 0 :(得分:1)
您需要两个角色。您无法在Google Cloud Console中将其中之一授予默认的GCE服务帐户。记下您要使用的服务帐户电子邮件地址。
[UPDATE 01/19/2019]
创建凭据时,除非需要,否则它们不会被初始化(例如,不要求访问令牌)。要预先初始化凭据,请执行以下操作:
auth_url = "https://www.googleapis.com/oauth2/v4/token"
headers = {}
request = google.auth.transport.requests.Request()
creds.before_request(request, "POST", auth_url, headers)
[END UPDATE]
为您的服务帐户授予角色roles/iam.serviceAccounts.signBlob
gcloud projects add-iam-policy-binding <project-id> --member=serviceAccount:<project-id>-compute@developer.gserviceaccount.com --role=roles/iam.serviceAccounts.signBlob
现在,该服务帐户可以使用私钥对数据进行签名。
现在授予该服务帐户角色roles/iam.serviceAccountTokenCreator
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
现在,该服务帐户可以使用该服务帐户来创建令牌。在命令中,您将为第一个service_account_email授予使用第二个service_account_email的特权。将此视为委派。注意,一个角色在项目级别,另一个角色分配给服务帐户本身。
在我的代码中,我实际上创建了一个新的服务帐户,并使用该服务帐户的电子邮件地址进行签名。我向新服务帐户授予权限(使用第一个命令),并向我的凭据授予使用新服务帐户的权限(第二个命令)。