云函数加载GCS中YAML时引用JSON密钥失败及安全方案咨询
问题解决方法
1. 解决GCS中YAML引用JSON密钥的问题
核心原因:ad_manager.AdManagerClient.LoadFromString解析YAML时,path_to_private_key_file字段仅支持本地文件系统路径,GCS路径(gs://)或HTTP URL均不被该库识别,因此会报错找不到文件。
解决思路:将GCS中的JSON密钥文件下载到云函数的临时目录(/tmp,云函数允许读写该目录),动态修改YAML内容中的密钥路径为本地临时路径,再加载修改后的YAML。
具体实现代码
import yaml from googleads import ad_manager from google.cloud import storage def load_file_from_gcs(bucket_name, file_path): storage_client = storage.Client() bucket = storage_client.get_bucket(bucket_name) blob = bucket.get_blob(file_path) if blob is None: raise FileNotFoundError(f"The file '{file_path}' does not exist in the bucket '{bucket_name}'.") return blob def main(): bucket_name = "你的存储桶名称" yaml_file_path = "googleads.yaml" json_key_file_path = "service-account-creds.json" # 下载YAML内容 yaml_blob = load_file_from_gcs(bucket_name, yaml_file_path) yaml_content = yaml_blob.download_as_text() # 下载JSON密钥到临时目录 json_blob = load_file_from_gcs(bucket_name, json_key_file_path) local_json_path = "/tmp/service-account-creds.json" json_blob.download_to_filename(local_json_path) # 解析并修改YAML中的密钥路径 yaml_data = yaml.safe_load(yaml_content) yaml_data["path_to_private_key_file"] = local_json_path # 将修改后的YAML转回字符串并加载客户端 updated_yaml_content = yaml.safe_dump(yaml_data) client = ad_manager.AdManagerClient.LoadFromString(updated_yaml_content) # 后续业务逻辑...
说明
- 云函数的
/tmp目录为临时存储区,函数执行期间有效,执行结束后自动清理,适合存放临时凭证文件。 - 需确保云函数的服务账户拥有GCS存储桶的
storage.objects.get权限,可读取YAML和JSON文件。
2. 更安全的凭证存储替代方案
将凭证存放在GCS并非最优选择,因为GCS主打对象存储,缺乏凭证管理的专用安全特性。推荐以下两种方案:
方案一:使用Google Cloud Secret Manager
将googleads.yaml和服务账户JSON密钥分别存储为Secret Manager的机密,云函数通过IAM权限访问,优势包括:
- 细粒度权限控制:仅授权云函数服务账户读取指定机密。
- 版本管理:可追踪机密修改历史,支持回滚到旧版本。
- 自动轮换:支持服务账户密钥自动轮换,降低泄露风险。
- 审计日志:记录所有机密访问操作,便于合规审计。
实现思路
- 在Secret Manager中创建两个机密,例如
googleads-yaml和ad-manager-service-account-key。 - 给云函数的服务账户授予
roles/secretmanager.secretAccessor权限(或更细粒度的权限)。 - 从Secret Manager读取机密内容,修改YAML中的密钥路径(或直接将JSON密钥内容注入YAML,避免本地文件操作)。
方案二:使用云函数默认服务账户(无需手动管理密钥)
若Ad Manager API支持服务账户认证,可直接使用云函数的默认服务账户,无需存储任何密钥文件:
- 在Ad Manager控制台中,将云函数的默认服务账户添加为授权用户,授予API访问权限。
- 修改
googleads.yaml配置,使用应用默认凭证(ADC),移除path_to_private_key_file字段:client_id: "你的客户端ID" client_secret: "你的客户端密钥" refresh_token: "你的刷新令牌" use_service_account: True - 云函数会自动使用默认服务账户的凭证访问Ad Manager API,无需手动管理密钥。
内容的提问来源于stack exchange,提问作者hadilnc01
相关产品推荐
相关产品推荐

