模拟类似于GST的“ sts承担角色”的行为,以便在本地环境中设置全局身份验证

问题描述

我相信我已经走到了尽头,但我希望得到专家的验证。

我本周开始学习GCP,我正在尝试实现以前可以通过AWS云平台实现的功能。由于我对GCP一无所知,请与我裸露。

问题:

在本地计算机上,配置动态获取的,短暂的凭据以使用公共云api进行身份验证(静态密钥已成问题)

当经过身份验证的人工用户(GCP:IAM用户,AWS:IAM用户)假冒非人类身份(GCP:IAM Service Accout,AWS:IAM角色)时,

通过一种方式,公共云平台提供的客户端SDK在调用公共云平台API时会将这些凭据用作默认(模拟的非人类)身份。

让我们说,在我的本地计算机上: 我有一个经过身份验证的用户A ,该用户需要代表 ServiceAccount / Role B 调用公共云api。

平台:

AWS-已解决

GCP-未解决

AWS解决方案

在AWS中,问题说明将为: 我希望在我通过本地用户身份验证的本地计算机上,以本地IWS客户端SDK的IAM-ROLE-B身份调用AWS API。

解决方案如下:

1-授权用户A通过用户A上的IAM角色策略在IAM-ROLE-B上执行sts:AssumeRole

2-授权用户A通过用户B上的IAM承担角色策略在IAM-ROLE-B上执行sts:AssumeRole

3-例如,使用aws cli对AWS STS API进行AssumeRole操作调用。这将返回我:访问密钥ID和b。秘密访问密钥

4-在〜/ .aws / .creds文件中进行设置,所有SDK均默认为这些凭据

GCP中的壁垒

当我尝试为GCP模拟相同的行为时,会出现问题。

从我通过身份验证为用户A的本地计算机上,我希望我的本地GCP客户端SDK以SERVICE-ACCOUNT-B的形式调用GCP API

由于我需要动态的短期信用凭证,因此我不能使用静态且太不安全的服务帐户密钥文件,并且我们知道不使用它的充分理由。

我知道的唯一其他选择是通过projects.serviceAccounts.generateAccessToken“模拟”服务帐户(代表SERVICE-ACCOUNT-B进行呼叫)。从AWS的类比中,我在步骤3中收到访问密钥ID和访问密钥密钥, 我可以全局设置(供客户端SDK使用)。

在使用GCP的情况下,projects.serviceAccounts.generateAccessToken调用为我提供了AccessToken,这基本上是一种短暂的身份验证,可以代表SERVICE-ACCOUNT-B进行调用。

尽管我可以将此访问令牌注入到我打算对以后的GCP调用中进行的请求中,但是有什么方法可以将其全局设置为由GCP客户端SDK自动获取,而无需修改我的代码库并以某种方式将这个令牌注入我的代码中?

回顾我是GCP的新手这一事实,我是否还在朝着正确的方向思考?还是我完全搞砸了GCP身份验证概念,并以错误的方式解决问题?

高度赞赏任何解决问题的建议和想法(无静态键)。

解决方法

否,使用gcloud,API请求或客户端库时在GCP中寻找的方法不可能像AWS中那样。正如您已经提到的,最好的方法是impersonating service accounts

您应该考虑到,每次模拟服务帐户时,都应明确地进行此操作,因为您无法像在AWS中那样存储凭证,例如:

gcloud compute instances create sample_vm --zone=us-central1-a \
  --machine-type=n1-standard-1 --image=centos-8-v20200811 \
  --image-family centos-8 --image-project=centos-cloud  \
  --impersonate-service-account=impersonated@project_id.iam.gserviceaccount.com

或使用客户端库时:

from google.cloud import storage
from google.auth import impersonated_credentials
import google.auth

target_scopes=[ 'https://www.googleapis.com/auth/devstorage.read_only' ]

my_credentials,project = google.auth.default()

impersonated_credentials = impersonated_credentials.Credentials(
    source_credentials=my_credentials,target_principal='impersonate@project.iam.gserviceaccount.com',target_scopes=target_scopes,lifetime=60)

client = storage.Client(credentials=impersonated_credentials)
blobs = client.list_blobs('bucket_name')
for blob in blobs:
    print(blob.name) 

最后,在执行API请求时,您应该始终包含令牌,这就是您现在正在做的事情。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...