You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

云函数加载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权限访问,优势包括:

  • 细粒度权限控制:仅授权云函数服务账户读取指定机密。
  • 版本管理:可追踪机密修改历史,支持回滚到旧版本。
  • 自动轮换:支持服务账户密钥自动轮换,降低泄露风险。
  • 审计日志:记录所有机密访问操作,便于合规审计。

实现思路

  1. 在Secret Manager中创建两个机密,例如googleads-yaml和ad-manager-service-account-key。
  2. 给云函数的服务账户授予roles/secretmanager.secretAccessor权限(或更细粒度的权限)。
  3. 从Secret Manager读取机密内容,修改YAML中的密钥路径(或直接将JSON密钥内容注入YAML,避免本地文件操作)。

方案二:使用云函数默认服务账户(无需手动管理密钥)

若Ad Manager API支持服务账户认证,可直接使用云函数的默认服务账户,无需存储任何密钥文件:

  1. 在Ad Manager控制台中,将云函数的默认服务账户添加为授权用户,授予API访问权限。
  2. 修改googleads.yaml配置,使用应用默认凭证(ADC),移除path_to_private_key_file字段:
    client_id: "你的客户端ID"
    client_secret: "你的客户端密钥"
    refresh_token: "你的刷新令牌"
    use_service_account: True
    
  3. 云函数会自动使用默认服务账户的凭证访问Ad Manager API,无需手动管理密钥。

内容的提问来源于stack exchange,提问作者hadilnc01

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 07:52:09