如果你想要讓別人能夠存取你 AWS 帳號上的資源,最安全的做法,就是新增一個 IAM Role,並透過 Assume Role 的方式,將這個 Role 賦予給對方。對方可以透過 STS (Security Token Service) 來取得這個 Role 的暫時性憑證,並使用這個憑證來存取你的資源。
舉個例子,假設你想讓 Development
帳號可以讀取 Production
帳號底下的的 S3 資源,可以怎麼做?
首先在 Production
帳號中新增一個讀取 S3 Bucket 的 Policy,並命名為 read_my_bucket
:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::my-bucket"
},
{
"Effect": "Allow",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::my-bucket/*"
}
]
}
然後一樣在 Production
帳號新增一個 Role,並命名為 delegate_read_my_bucket
,並且在 Trust Relationship 設定讓該 Role 能被 Development
帳號使用:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<DEVELOPMENT_ACCOUNT_ID>:root"
},
"Action": "sts:AssumeRole"
}
]
}
設定完成之後,將剛剛新增的 Policy 附加到 Role 上。此時帳號 Development
就可以透過 AssumeRole
API 來取得一個暫時性的 Credential,並且使用該 Credential 來讀取 S3 Bucket。
--role-session-name
參數取一個你喜歡的名字即可。
aws sts assume-role --role-arn arn:aws:iam::<PRODUCTION_ACCOUNT_ID>:role/delegate_s3_bucket_role --role-session-name "my-s3-session"
指令的結果如下:
{
"Credentials": {
"SecretAccessKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
"SessionToken": "AQoDYXdzEGcaEXAMPLE2gsYULo+Im5ZEXAMPLEe...",
"Expiration": "2014-12-11T23:08:07Z",
"AccessKeyId": "AKIAIOSFODNN7EXAMPLE"
}
}
將上述資訊設成環境變數,就可以在 Development
帳號中讀取 Production
的 S3 Bucket 了:
export AWS_ACCESS_KEY_ID="AKIAIOSFODNN7EXAMPLE"
export AWS_SECRET_ACCESS_KEY="wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
export AWS_SESSION_TOKEN="AQoDYXdzEGcaEXAMPLE2gsYULo+Im5ZEXAMPLEe..."
嘗試用 Python SDK 來印出 Bucket 底下所有的物件。
import os
import boto3
session = boto3.Session(
aws_access_key_id=os.environ["AWS_ACCESS_KEY_ID"],
aws_secret_access_key=os.environ["AWS_SECRET_ACCESS_KEY"],
aws_session_token=os.environ["AWS_SESSION_TOKEN"],
)
s3 = session.resource("s3")
my_bucket = s3.Bucket("my-bucket")
for my_bucket_object in my_bucket.objects.all():
print(my_bucket_object.key)