ユーザーに一時的に権限を付与する Assume Role を使ってみる
Assume Role という機能があり使ってみたのでメモ。
参考
- AssumeRole について
- python で AssumeRole 操作
- python で bucket 操作
Assume Role とは
Assume には「引き受ける」という意味がある。
権限がないユーザーが一時的に権限を「引き受ける」事によって普段許可されていない事ができるようになる。
例えば S3 にアクセスするロールが適用されていないIAMユーザーでも、一時的にロールを適用することによって S3 にアクセスできるようになる。
なにが良いのか
- 多様なロールを適用したIAMユーザーを作成しなくて良いのでユーザー数が節約できる。
- 付与されるロールのには期限があるのでセキュリティ的によい。
- アクセスキー等が漏洩したとしてもロールを引き受けないと、そのIAMユーザーではできる事が限られる。
...とのこと。
準備
用意する設定は下記の通り。
1つのポリシーが直接アタッチされたユーザー。
2つのポリシーがアタッチされたロール。
- ロールを引き受けるユーザー
- ロールを引き受ける事を可能にするポリシー
- 引き受けられるロール。
- S3を扱うポリシー
- 引き受けるユーザーを信頼するポリシー
ユーザーがS3操作権限のあるロールを一時的に借りるが、お互いに信頼するポリシーも必要みたいな感じ。
手順
- ロールを引き受けるユーザーを作成する。
- 引き受けられるロールを作成する。
- ロールを引き受ける事を可能にするポリシーを作成する。
- ユーザーにポリシーをアタッチする。
ロールを引き受けるユーザーを作成する
まずは何の許可も持たないユーザーを作成します。
- IAMページを開く。
- サイドバーの「ユーザー」をクリックする。
- 「ユーザーを追加」をクリックする。
- 「ユーザー名」で「AssumeS3User」と入力して「次へ」をクリックする。
- とりあえず「ポリシーを直接アタッチする」を選択だけして何もアッタッチせずに「次へ」をクリックする。
- 「ユーザーの作成」をクリックする。
- 新しいユーザーのページに移動するのでARNを控えておく。
- ARNに含まれる12桁のIDを控えておく。
arn:aws:iam::123456789012:user/AssumeS3User
引き受けられるロールを作成する
信頼するアカウントIDを設定する。
- IAMページを開く。
- サイドバーの「ロール」をクリックする。
- 「ロールを作成」をクリックする。
- 「AWSアカウント」を選択する。
- 「別のAWSアカウント」を選択し先ほど控えた12桁のIDを入力する。
- 「次へ」をクリックする。
S3のポリシーを設定する。
- 「許可ポリシー」で「AmazonS3FullAccess」と検索し、表示されたポリシーにチェックをつけ「次へ」をクリックする。
- 「ロール名」に「AllowedAssumeS3Role」と入力し「ロールを作成」をクリックする。
ユーザーを全員ではなく特定のユーザーのみ信頼する。
- 上記で作成したロールのページの「信頼関係」タブを開く。
- 「信頼されたエンティティ」が以下のようになっているので「信頼ポリシーを編集」をクリックする。
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::123456789012:root" }, "Action": "sts:AssumeRole", "Condition": {} } ] }
- 作成したユーザーのARNに書き換え「ポリシーを更新」をクリックする。
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::123456789012:user/AssumeS3User" // ユーザーのARN }, "Action": "sts:AssumeRole", "Condition": {} } ] }
- 作成したロールの ARN をコピーして控えておく。
ロールを引き受ける事を可能にするポリシーを作成する
- サイドバーの「ポリシー」をクリックする。
- 「ポリシーを作成」をクリックする。
- Resource に先ほど作成したロールのARNを指定し下記のようにJSONを変更し「次のステップ: タグ」をクリックする。
{
"Version": "2012-10-17",
"Statement": {
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::123456789012:role/AllowedAssumeS3Role" // ロールのARN
}
}
- 今回はタグ付けしないのでそのまま「次のステップ: 確認」をクリックする。
- 「名前」に「AssumeS3RolePolicy」と入力し「ポリシーの作成」をクリックする。
ユーザーにポリシーをアタッチする
- 作成したユーザー AssumeS3User のページを開き「許可を追加」をクリックする。
- 「ポリシーを直接アタッチする」をクリックし「AssumeS3RolePolicy」を検索し表示されたポリシーにチェックをつけ「次へ」をクリックする。
- 「許可を追加」をクリックする。
以上で設定は終わりです。
確認する
アクセスキーを発行する
まずは作成したユーザーのアクセスキーを発行します。
- 作成したユーザーのページ
- セキュリティ認証情報
- アクセスキーを作成
- コマンドラインインターフェイス (CLI)
- 次へ → アクセスキーを作成
- アクセスキーとシークレットアクセスキーを控える
- 完了
python で確認する
権限を持たない状態でS3からファイルのダウンロードを試してみます。
import boto3
from boto3.session import Session
# Assume User
AWS_ACCESS_KEY_ID = 'xxxxxxxxxx'
AWS_SECRET_ACCESS_KEY = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
REGION_NAME = 'ap-northeast-1'
# To Switch Role
IAM_ROLE_ARN = 'arn:aws:iam::123456789012:role/AllowedAssumeS3Role'
IAM_ROLE_SESSION_NAME = 'hogehoge'
# Bucket Name
BUCKET_NAME = "hogehoge-bucket"
# download S3 File
s3 = boto3.resource(
's3',
aws_access_key_id=AWS_ACCESS_KEY_ID,
aws_secret_access_key=AWS_SECRET_ACCESS_KEY,
region_name=REGION_NAME,
)
bucket = s3.Bucket(BUCKET_NAME)
bucket.download_file('hoge.zip', 'hoge.zip')
結果は権限がないとの事。
botocore.exceptions.ClientError: An error occurred (403) when calling the HeadObject operation: Forbidden
今度は、ロールを一時的に借りてダウンロードを試してみます。
import boto3
from boto3.session import Session
# Assume User
AWS_ACCESS_KEY_ID = 'xxxxxxxxxx'
AWS_SECRET_ACCESS_KEY = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
REGION_NAME = 'ap-northeast-1'
# To Switch Role
IAM_ROLE_ARN = 'arn:aws:iam::123456789012:role/AllowedAssumeS3Role'
IAM_ROLE_SESSION_NAME = 'hogehoge'
# Bucket Name
BUCKET_NAME = "hogehoge-bucket"
# Call Security Token Service
client = boto3.client(
'sts',
aws_access_key_id=AWS_ACCESS_KEY_ID,
aws_secret_access_key=AWS_SECRET_ACCESS_KEY,
region_name=REGION_NAME,
)
# Get Role Info
response = client.assume_role(
RoleArn=IAM_ROLE_ARN,
RoleSessionName=IAM_ROLE_SESSION_NAME
)
# Get Session
session = Session(
aws_access_key_id=response['Credentials']['AccessKeyId'],
aws_secret_access_key=response['Credentials']['SecretAccessKey'],
aws_session_token=response['Credentials']['SessionToken'],
region_name=REGION_NAME
)
# Use Session Instead Of Boto3
s3 = session.resource("s3")
bucket = s3.Bucket(BUCKET_NAME)
bucket.download_file('hoge.zip', 'hoge.zip')
実行したら無事 hoge.zip がダウンロードできました。
追記
ロールの作成で「信頼されたエンティティタイプ」で「ウェブアイデンティティ」を選択すると、GCPのサービスアカウントにもロールの付与を許可できるみたいです。
ディスカッション
コメント一覧
まだ、コメントがありません