使用Google Source Repository时,如何安全存储Google Cloud Functions服务账号私钥?
安全存储Google Cloud Functions访问私有Sheet的服务账号密钥方案
这问题我之前帮团队处理过,完全懂你不想把敏感的服务账号JSON丢进Git仓库的顾虑!给你几个Google生态里生产环境常用的靠谱方案,按推荐优先级排序:
1. 首选:Google Cloud Secret Manager(官方推荐)
这是Google专门为敏感信息存储设计的服务,完美适配Cloud Functions这类托管服务,优势拉满:
- 自动支持密钥轮转、审计日志,还能做细粒度的权限控制
- 完全不用在代码里碰密钥文件,全程通过API拉取
操作步骤:
- 把你的服务账号JSON上传到Secret Manager,创建一个新的Secret
- 给Cloud Functions的执行服务账号(默认是
你的项目ID@appspot.gserviceaccount.com)添加roles/secretmanager.secretAccessor权限,让它能读取这个Secret - 在函数代码里用Secret Manager的客户端库拉取密钥,比如Python示例:
from google.cloud import secretmanager import json from google.oauth2.service_account import Credentials from googleapiclient.discovery import build def access_secret(project_id, secret_id): client = secretmanager.SecretManagerServiceClient() secret_name = f"projects/{project_id}/secrets/{secret_id}/versions/latest" response = client.access_secret_version(request={"name": secret_name}) return response.payload.data.decode("UTF-8") def your_cloud_function(request): # 拉取服务账号密钥 service_account_json = access_secret("你的项目ID", "sheet-access-secret") creds = Credentials.from_service_account_info(json.loads(service_account_json)) # 初始化Sheets客户端 sheets_service = build('sheets', 'v4', credentials=creds) # 后续操作Sheet的逻辑...
2. 次选:加密的环境变量
如果觉得Secret Manager有点繁琐,也可以把服务账号JSON转成字符串存在Cloud Functions的环境变量里,但必须用Cloud KMS加密这个变量,避免明文泄露:
操作步骤:
- 先在Cloud KMS创建一个密钥环和加密密钥
- 部署函数时用base64编码JSON内容,并用KMS密钥加密环境变量:
gcloud functions deploy your-function-name \ --runtime python311 \ --trigger-http \ --set-env-vars SERVICE_ACCOUNT_JSON=$(cat path/to/your/service-account.json | base64) \ --kms-key projects/你的项目ID/locations/global/keyRings/你的密钥环/cryptoKeys/你的加密密钥
- 代码里解码并使用:
import os import base64 import json from google.oauth2.service_account import Credentials def your_cloud_function(request): encoded_json = os.environ.get("SERVICE_ACCOUNT_JSON") service_account_info = json.loads(base64.b64decode(encoded_json)) creds = Credentials.from_service_account_info(service_account_info) # 初始化Sheets客户端...
3. 最优无密钥方案:工作负载身份(Workload Identity)
这个方案彻底消除密钥管理的麻烦,完全不用服务账号JSON,是Google现在主推的无密钥架构:
核心思路:
不让Cloud Functions使用独立的服务账号密钥,而是直接让Cloud Functions的默认执行账号扮演你创建的Sheet访问服务账号(或者直接给默认账号加Sheet的访问权限),通过Google内部的身份验证流程获取访问凭证。
操作步骤:
- 给Cloud Functions的执行服务账号添加
roles/iam.serviceAccountTokenCreator权限,允许它扮演目标服务账号 - 在代码里直接用默认凭证初始化Sheets客户端,Google会自动处理身份验证:
from googleapiclient.discovery import build from google.auth import default def your_cloud_function(request): creds, _ = default() # 确保creds有访问Sheet的权限,可能需要给默认账号加Sheet的编辑/查看权限 sheets_service = build('sheets', 'v4', credentials=creds) # 后续操作...
额外注意事项
- 最小化权限:记得回头给你的服务账号瘦身!别留过大的权限,比如只给
roles/spreadsheets.editor(甚至更细的单Sheet权限)就行,遵循最小权限原则 - 本地测试避坑:本地开发时别把密钥硬编码,用
gcloud auth application-default login获取临时凭证,或者本地调用Secret Manager拉取密钥
内容的提问来源于stack exchange,提问作者Vadorequest
相关产品推荐
相关产品推荐

