如何在GCP Cloud Function中注入两个不同服务账号(跨项目场景)
跨GCP项目访问Secrets的解决方案(无需注入多个服务账号)
Cloud Function不需要同时注入两个服务账号,通过以下两种安全合规的方式即可实现跨项目访问Secrets:
方案一:给Cloud Function默认服务账号添加跨项目权限
- 步骤1:确认
com-project-common项目中Cloud Function使用的服务账号,默认格式为com-project-common@appspot.gserviceaccount.com(如果是自定义服务账号则用对应账号) - 步骤2:切换到
com-project-data项目,为上述服务账号授予Secret Manager Secret Accessor角色(或更细粒度的secretmanager.versions.access权限)
命令行执行:gcloud projects add-iam-policy-binding com-project-data \ --member="serviceAccount:com-project-common@appspot.gserviceaccount.com" \ --role="roles/secretmanager.secretAccessor" - 步骤3:在Cloud Function代码中直接访问跨项目Secrets,路径格式为
projects/com-project-data/secrets/[你的Secret名称]/versions/latest
方案二:使用工作负载身份绑定(推荐,权限隔离更严格)
如果需要更精细的权限管控,可通过工作负载身份让Cloud Function扮演com-project-data项目中的专用服务账号:
- 步骤1:在
com-project-data项目中创建专用服务账号(例如secret-accessor@com-project-data.iam.gserviceaccount.com),并为其添加Secret Manager Secret Accessor角色 - 步骤2:在
com-project-common项目中,给Cloud Function的服务账号添加Service Account Token Creator角色,允许它扮演目标账号:gcloud projects add-iam-policy-binding com-project-common \ --member="serviceAccount:com-project-common@appspot.gserviceaccount.com" \ --role="roles/iam.serviceAccountTokenCreator" - 步骤3:在
com-project-data项目中,授权Cloud Function服务账号可以扮演目标专用账号:gcloud iam service-accounts add-iam-policy-binding secret-accessor@com-project-data.iam.gserviceaccount.com \ --member="serviceAccount:com-project-common@appspot.gserviceaccount.com" \ --role="roles/iam.serviceAccountUser" - 步骤4:在Cloud Function代码中通过身份模拟访问Secrets,以Python为例:
from google.auth import impersonated_credentials from google.cloud import secretmanager import google.auth def access_cross_project_secret(request): target_sa = "secret-accessor@com-project-data.iam.gserviceaccount.com" source_creds, _ = google.auth.default() target_creds = impersonated_credentials.Credentials( source_credentials=source_creds, target_principal=target_sa, target_scopes=["https://www.googleapis.com/auth/cloud-platform"], lifetime=3600 ) client = secretmanager.SecretManagerServiceClient(credentials=target_creds) secret_name = f"projects/com-project-data/secrets/[你的Secret名称]/versions/latest" response = client.access_secret_version(request={"name": secret_name}) return response.payload.data.decode("UTF-8")
关于“注入两个服务账号”的说明
Cloud Function本身不支持直接配置多个运行身份的服务账号。若强行通过代码加载两个服务账号的密钥文件,会大幅增加密钥管理风险,不符合GCP安全最佳实践,因此不推荐这种做法。
内容的提问来源于stack exchange,提问作者Alberto Ornelas
相关产品推荐
相关产品推荐

