AWS 要授权给他人访问指定资源有哪几种方式呢?
- 创建一个 AWS 帐号让别人用,那是 AWS 干的事
- 在自己帐号下创建一个用户,把 Access Key ID 和 Secret Access Key 告诉别人。可为该用户限定权限,但任何获得那两个 Key 的人都能使用该用户。
- 创建一个 IAM Role, 并指定谁(帐号或 Role) 能以该 Role 的身份来访问。被 Assume 的 Role 可限定权限和会话有效期。
用 Assume Role 的方式具有更高的安全可控性,还不用维护 Access Key ID 和 Secret Access Key。比如在构建和部署时通常是有一个特定的 Account, 然后 Assume 到别的 IAM Role 去操作资源。
本文将详细介绍在帐号 A 创建一个 IAM Role(标注为 R) 并分配一些权限,然后允许另一个帐号 B 以 IAM Role - R 的身份来访问帐号 A 下的资源。IAM Role 将用 awscli 来创建,Assume Role 的过程用 awscli 和 boto3 Python 代码两种方式来演示。
帐号 A 下创建 IAM Role
首选要以帐号 A 登陆 AWS,不管哪种方式只要让 aws s3 cli
能正常工作就行。AWS 获得访问资格(Credentials) 的顺序可参照 Boto3 的文档 Configuring Credentials。
比如说在 ~/.aws/credentials
中配置了 profile A 和 B,分别对应帐号 A 和 B 的 profile 名称,在帐号 A 下创建 IAM Role 前用 export AWS_DEFAULT_PROFILE=A
指明当前为帐号 A
准备 role-trust-policy.json
这里的 123456789022
是帐号 B 的 Account ID, 如果允许更多的帐号可以往上面的 Principal
中添加。创建 test-assumed-role
$ aws iam create-role --role-name test-assumed-role --assume-role-policy-document file://role-trust-policy.json
再给新建的 test-assumed-role 加上 S3 的只读权限
$ aws iam attach-role-policy --role-name test-assumed-role --policy-arn arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess
帐号 B Assume 帐号 A 的 role(awscli)
在帐号 A 下创建好 test-assumed-role 后,现在为 awscli 切换到帐号 B 下,比如 export AWS_DEFAULT_PROFILE=B
。接着要用 aws sts assume-role
命令
$ aws sts assume-role --role-arn arn:aws:iam::123456789011:role/test-assumed-role --role-session-name awscli-session
其中的 123456789011
是,sts
是指 Security Token Service,执行后输出如下
这时候得到一组新的 AccessKeyId, SecretAccessKey 和 SessionToken,可以在 ~/.aws/credentials
中配置一个新的 profile C, 然后 export AWS_DEFAULT_PROFILE=C
来使用。或都用 export
分别导出三个环境变量 AWS_ACCESS_KEY_ID
, AWS_SECRET_ACCESS_KEY
, 和 AWS_SESSION_TOKEN
, 分别对应前面的三个值。
$ export AWS_ACCESS_KEY_ID=<Credentials.AccessKeyId>
$ export AWS_SECRET_ACCESS_KEY=<Credentials.SecretAccessKey>
$ export AWS_SESSION_TOKEN=<Credentials.SessionToken>
替换上面的 <Credentials.*> 为 aws sts assume-role ...
返回的实际的相应字符串
2024-02-01
一种更便捷一步到位的切换 role 的方式
这时候执行 aws s3 ls
获得的就是帐号 A 中的 S3 Bucket 列表
$ aws s3 ls
2021-09-10 12:09:35 bucket1-of-A
2019-12-03 15:55:35 bucket2-of-A
想访问超出 test-assumed-role
之外的权限将被提示 Access Denied
$ aws s3 cp Jenkinsfile s3://wfe-files
upload failed: ./test.txt to s3://bucket-of-A/test.txte An error occurred (AccessDenied) when calling the PutObject operation: Access Denied
任何时候都通过 aws sts get-caller-identity
来查看当前所使用的角色
aws sts get-caller-identity
{
"UserId": "EXYARBWXQYCCAUONCJHG:awscli-session",
"Account": "123456789011",
"Arn": "arn:aws:sts::123456789011:assumed-role/test-assumed-role/awscli-session"
}
帐号 B Assume 帐号 A 的 role(boto3)
awscli Assume 一个 IAM Role 的方式是重新获得一组 AccessKeyId, SecretAccessKey 和 SessionToken, 然后切换到被 Assumed 的 Role。用 Python 的 boto3 包实现是完全一样的。
帐号 B 登陆,调用 boto3 的 sts.assume_role() 函数切换到帐号 A 下的 IAM Role test-assumed-role,之后的操作就限定到 test-assumed-role 的约束中了。
当然,使用 Python 的话可以进一步封装,比如默认以帐号 B 登陆,然后执行一个函数 switch_role(role_arn)
后,后续的 boto3 client 就全部变成了 assumed role 的角色了
把 sts_res['Credentials']
转换为 session 要求的格式是简化,但是要注意以后 assume_role() 响应格式的变化有可能影响到程序的正常执行。
链接:
本文链接 https://yanbin.blog/how-to-assume-aws-iam-role/, 来自 隔叶黄莺 Yanbin Blog
[版权声明] 本文采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可。
好文,不错。baidu 里居然搜到你的文章。
哪位 robin? 为什么我自己在 baidu 里搜不到这篇 “assume site:yanbin.blog”