无需密钥文件,用GCP服务账号模拟Workspace服务账号的方法
解决Cloud Run服务账号模拟Workspace服务账号时的「Gaia id not found」错误
遗漏的核心配置步骤
你遇到的「Gaia id not found」错误,本质是Workspace侧服务账号的域委派配置不完整,或者模拟逻辑参数有误,补充以下关键配置:
给Workspace服务账号绑定GCP服务账号的客户端ID
登录Google Admin控制台,进入「安全」→「API控制」→「域范围委派」,找到已启用Domain Delegation的Workspace服务账号,添加你的GCP服务账号对应的客户端ID(格式为[数字]-[随机字符串].apps.googleusercontent.com),同时确认勾选了所需的Directory API范围。确认Workspace服务账号的有效性
错误提示中的x@y.com必须是你Workspace域内已创建的服务账号邮箱,不能是GCP自动生成的xxx@project-id.iam.gserviceaccount.com格式账号——这类账号属于GCP,不属于你的Workspace域,无法被识别为Gaia账号。锁定Cloud Run的运行身份
确保Cloud Run服务运行时使用的是你配置了Service Account Token Creator权限的GCP服务账号,在Cloud Run控制台的「修订版本」→「安全」面板中确认服务账号配置正确。
修正后的Python实现代码
以下代码无需依赖本地密钥文件,直接使用Cloud Run的默认服务账号身份完成模拟:
from google.oauth2 import service_account from googleapiclient.discovery import build import google.auth import google.auth.transport.requests from google.auth import impersonated_credentials # 配置参数 TARGET_WORKSPACE_SA = "workspace-sa@your-domain.com" # Workspace侧服务账号邮箱 ADMIN_EMAIL = "admin@your-domain.com" # Workspace域管理员邮箱(API调用需管理员身份) SCOPES = [ "https://www.googleapis.com/auth/admin.directory.user.readonly", # 按需添加其他所需的Admin SDK范围 ] def get_impersonated_credentials(): # 获取Cloud Run默认服务账号凭据 source_creds, _ = google.auth.default() # 创建模拟Workspace服务账号的凭据 target_creds = impersonated_credentials.Credentials( source_credentials=source_creds, target_principal=TARGET_WORKSPACE_SA, target_scopes=SCOPES, delegates=[], ) # 绑定Workspace管理员身份(Admin SDK必须指定管理员subject) target_creds = target_creds.with_subject(ADMIN_EMAIL) # 刷新凭据获取令牌 request = google.auth.transport.requests.Request() target_creds.refresh(request) return target_creds def main(): creds = get_impersonated_credentials() # 构建Directory API客户端 directory_service = build("admin", "directory_v1", credentials=creds) # 示例调用:查询域内用户列表 user_results = directory_service.users().list( customer="my_customer", maxResults=10, orderBy="email" ).execute() users = user_results.get("users", []) if users: print("域内用户列表:") for user in users: print(f"- {user['primaryEmail']} ({user['name']['fullName']})") else: print("未找到任何用户") if __name__ == "__main__": main()
代码关键说明
- 使用
google.auth.default()直接获取Cloud Run运行环境的服务账号凭据,完全无需本地密钥文件 - 通过
impersonated_credentials.Credentials实现GCP服务账号向Workspace服务账号的身份模拟 with_subject(ADMIN_EMAIL)是必填项——Admin SDK的大部分接口要求以域管理员身份调用,即使使用服务账号模拟也需要指定管理员主体- 确保
TARGET_WORKSPACE_SA是你在Workspace域内创建并启用了Domain Delegation的服务账号
最后验证点
- 再次核对Workspace域范围委派页面,确认GCP服务账号的客户端ID已添加,且授权范围与代码中的
SCOPES一致 - 在GCP IAM中确认Cloud Run使用的服务账号拥有
roles/iam.serviceAccountTokenCreator权限 - 重新部署Cloud Run服务后测试代码,确保网络配置允许访问Google的OAuth2和Admin SDK API
内容的提问来源于stack exchange,提问作者jldupont
相关产品推荐
相关产品推荐

