问题描述
我相信我已经走到了尽头,但我希望得到专家的验证。
我本周开始学习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请求时,您应该始终包含令牌,这就是您现在正在做的事情。