如何使用 IAM Role 進行跨帳號的資源存取

程式技術
•

如果你想要讓別人能夠存取你 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)

參考資料

Allen
written by
Allen

持續努力中的後端打工仔,在下班後喜歡研究各種不同的技術。稍微擅長 PHP,並偶爾涉獵前端開發。個性就像動態語言般隨興,但渴望做事能像囉嗦的靜態語言那樣嚴謹。

則留言
顯示更多留言
新增留言
訪客 2026 年 10 月 16 日