简体   繁体   English

以编程方式获取 GCP 上的当前服务帐户

[英]Programmatically get current Service Account on GCP

Is there a way to programmatically access the email of the currently used Service Account on a GCP instance when no GOOGLE_APPLICATION_CREDENTIALS is set?当没有设置GOOGLE_APPLICATION_CREDENTIALS时,有没有办法以编程方式访问 GCP 实例上当前使用的服务帐户的 email? (ie. when using the default Service Account) (即使用默认服务帐户时)

I've looked through the GCP documentation, but the only resource I found can't be used with the default Service Account when no GOOGLE_APPLICATION_CREDENTIALS is set.我查看了 GCP 文档,但我发现的唯一资源在未设置GOOGLE_APPLICATION_CREDENTIALS时无法与默认服务帐户一起使用。 I know that it is possible to do so using gcloud (see this SO question or documentation ), however these solutions aren't applicable when running on a ContainerOptimisedOS .我知道可以使用gcloud这样做(请参阅此 SO 问题文档),但是这些解决方案在ContainerOptimisedOS上运行时不适用。 I've spent a couple of weeks back and forth with the GCP support team, but they concluded with not being able to help me and redirected me to Stack Overflow for help.我已经与 GCP 支持团队来回交流了几周,但他们最终无法帮助我,并将我重定向到 Stack Overflow 寻求帮助。

The solution of John works great, on any language without any external library. John 的解决方案适用于任何语言,无需任何外部库。 However, it works only on Google Cloud environment, when a metadata server is deployed.但是,当部署了元数据服务器时,它仅适用于 Google Cloud 环境。 You can't perform this test on your computer.您无法在计算机上执行此测试。

I propose just bellow a piece of Python code (with Google OAuth library, but it works in other languages that have this library) to ask the library the current credential.我建议只使用一段 Python 代码(使用 Google OAuth 库,但它适用于具有该库的其他语言)来询问库当前的凭证。 If the credential is a service account (from GOOGLE_APPLICATION_CREDENTIALS on your computer, the ADC (Application Default Credential) or from the metadata server), you have the email printed, else, you have warning message because you use your user account credential如果凭据是服务帐户(来自计算机上的 GOOGLE_APPLICATION_CREDENTIALS、ADC(应用程序默认凭据)或元数据服务器),则您打印了 email,否则,您会收到警告消息,因为您使用了用户帐户凭据

    import google.auth

    credentials, project_id = google.auth.default()

    if hasattr(credentials, "service_account_email"):
      print(credentials.service_account_email)
    else:
        print("WARNING: no service account credential. User account credential?")

Note that if the default service account is used this method will print default instead of the entire email address.请注意,如果使用默认服务帐户,此方法将打印default而不是整个 email 地址。


EDIT 1编辑 1

    ctx := context.Background()
    credential,err := google.FindDefaultCredentials(ctx)
    content := map[string]interface{}{}

    json.Unmarshal(credential.JSON,&content)
    if content["client_email"] != nil {
      fmt.Println(content["client_email"])
    } else {
      fmt.Println("WARNING: no service account credential. User account credential?")
    }

Just adding to the accepted answer.只是添加到已接受的答案中。 As stated in the answer this seems to return "default":如答案中所述,这似乎返回“默认”:

import google.auth

credentials, project_id = google.auth.default()
# returns "default"
print(credentials.service_account_email) 

I found to get the email name of the GSA currently active (via the metadata api) I had to manually refresh first:我发现要获取当前活动的 GSA 的 email 名称(通过元数据 api),我必须先手动刷新:

import google.auth
import google.auth.transport.requests

credentials, project_id = google.auth.default()
request = google.auth.transport.requests.Request()
credentials.refresh(request=request)
# returns "mygsa@myproject.iam.gserviceaccount.com"
print(credentials.service_account_email) 

I'm using workload ID.我正在使用工作负载 ID。 I think maybe there is a race condition and I'm trying to read the service_account_email property before the creds get initialized for the first time when the pod starts?我认为可能存在竞争条件,我正在尝试在 pod 启动时第一次初始化 creds 之前读取service_account_email属性?

The _retrieve_info() function is called when refresh() is called and it appears this is the function that grabs the email name.调用refresh()时会调用_retrieve_info() function,看起来这是获取 email 名称的 function。

If I had my script sleep for a few seconds on start up would service_account_email eventually be populated with the email name of the GSA or does that not happen until you manually refresh or initialize a client API or something?如果我让我的脚本在启动时休眠几秒钟, service_account_email最终会填充 GSA 的 email 名称,或者直到您手动刷新或初始化客户端 API 或其他什么时才会发生这种情况?

If you are interested in getting the exact email and not just the "default" alias (when you are using the compute engine), you can fetch it using the credentials metadata.如果您有兴趣获得确切的 email 而不仅仅是“默认”别名(当您使用计算引擎时),您可以使用凭证元数据获取它。 This was particularly helpful in determining which service account is being used by AI Platform jobs.这对于确定 AI Platform 作业正在使用哪个服务帐户特别有用。

    import google.auth
    from google.auth.transport.requests import Request
    from google.auth.compute_engine import _metadata
    
    if hasattr(credentials, "service_account_email"):
        print(credentials.service_account_email)

        # edits made on top of the top answer's code
        info = _metadata.get_service_account_info(Request(),
                service_account=credentials.service_account_email)

        print(f"Service account email: {info.email}")
        print(f"Service account aliases: {info.aliases}")
        print(f"Service account scopes: {info.scopes}")

    else:
        print("WARNING: no service account credentials available.")

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 GCP 服务帐号命名 - GCP service account naming 如何获取 GCP 服务帐户 SignedJWT,以便我可以调用接受 GCP 身份验证的第 3 方服务 - How to Get GCP Service Account SignedJWT so I can call a 3rd party service that accepts GCP auth GCP - 存储服务帐户访问问题 - GCP - Storage Service Account Access Issue GCP - 从本地计算机模拟服务帐户 - GCP - Impersonate Service Account from Local Machine Gcp支持从firebase绑定服务账号? - Gcp support binding service account from firebase? 如何使用服务帐户从 python 代码访问 GCP 云 function? - How I can get access to GCP cloud function from python code using service account? GCP 中的服务帐户和服务代理有什么区别 - What is the difference between service account and service agent in GCP GCP:如何向 Firestore 集合上的服务帐户授予角色? - GCP: How to grant a role to a service account on a Firestore collection? GCP-IAM - 如何授予对组织中所有服务帐户的访问权限? - GCP-IAM - How to grant access to all service account in organization? GCP 限制服务帐户有条件访问单个实例 - GCP limit service account to have conditional access to a single instance
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM