是否有一种支持的方法可以在不使用密钥文件的情况下使用 Google 云 Python SDK 对服务帐户进行身份验证?

Is there a supported way to authenticate a service account using the Google cloud Python SDK without using a keyfile?

我在 CI/CD 环境中操作,在该环境中,严禁将 JSON 密钥文件写入磁盘或将其包含在项目中。我所能做的就是将原始 JSON 数据注入到一个环境变量中,我们可以在运行时读回该变量。将 GOOGLE_APPLICATION_CREDENTIALS 设置为密钥文件路径的常用方法在这里不起作用,因为我们不能首先写入文件。它需要直接包含 JSON 数据作为字符串。

不幸的是,我发现的所有 Google 云文档都假定 JSON 密钥文件在身份验证之前存在。没有讨论如何直接通过变量值进行身份验证。 closest thing which I've found hints that setting the credentials explicitly is possible, but the linked page 只讨论了 Credentials 的内部属性 class.

幸运的是,我阅读 the code 的运气比阅读文档要好。在四处寻找之后,我发现 ServiceAccountCredentials._from_parsed_json_keyfile 可以让我做我想做的事。这是我的测试代码:

import os
import json
from oauth2client.service_account import ServiceAccountCredentials
from googleapiclient import discovery

# Prepare the service object
json_data = json.loads(os.getenv("MY_CREDENTIALS_STRING"))
credentials = ServiceAccountCredentials._from_parsed_json_keyfile(json_data, scopes='')
service = discovery.build('compute', 'v1', credentials=credentials)

# Test the service object
request = service.images().list(project='my-project')
response = request.execute()
print(response)

这行得通,但感觉像是破解。函数名称中的“_”告诉我它不是受支持的 API 的一部分,并且可能会在未来的版本中毫无警告地消失。

我没有找到完成此操作的官方方法。有吗?

使用classgoogle.oauth2.service_account。该成员是 from_service_account_info.

文档:link。 源代码:link.

from google.oauth2 import service_account

// load from a file
// service_account_info = json.load(open('service_account.json'))

// load from system environment
service_account_info = json.loads(os.getenv("MY_CREDENTIALS_STRING"))

credentials = service_account.Credentials.from_service_account_info(service_account_info)