AssumeRole をやってみる
はじめに
セキュアに使用できるAssumeRoleを使ってみます。
アクセスキーを発行する必要はありますが、RoleARN必要なことやExternalIDを設定することでより安全に使用できます。
awscliから操作をするので、最初にIAM権限を持ったcredentials情報を使って操作します。
環境
awscli: 2.10.1
AssumeRole用のIAMユーザ作成
IAM_USERNAME="Test-user"
aws iam create-user --user-name ${IAM_USERNAME}
IAM_USER_ARN=$(aws iam get-user --user-name ${IAM_USERNAME} --query 'User.Arn' --output text)
IAMRoleの作成
IAMロールの信頼関係を定義したJsonファイルを作成
Principalには、許可したいIAMユーザのARNを指定
AssumeRoleをする際には、ExternalIDをオプションとして付与し、ここに入力した値が必要となります
EXTERNAL_ID="forTestuser"
cat <<EOT > "Assume-role-trust-policy.json"
{
"Version": "2012-10-17",
"Statement": {
"Effect": "Allow",
"Principal": {
"AWS": "${IAM_USER_ARN}"
},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
"sts:ExternalId": "${EXTERNAL_ID}"
}
}
}
}
EOT
ロールに作成時に、先程の信頼関係を定義したJsonファイルを指定
アタッチするポリシーは、ReadOnlyAccessとしました
ROLE_NAME="ReadOnly-Assume-role"
ROLE_ATTACH_POLICY_ARN="arn:aws:iam::aws:policy/ReadOnlyAccess"
ROLE_ARN="$(aws iam create-role --role-name ${ROLE_NAME} --assume-role-policy-document file://Assume-role-trust-policy.json --query 'Role.Arn' --output text)"
aws iam attach-role-policy --role-name ${ROLE_NAME} --policy-arn ${ROLE_ATTACH_POLICY_ARN}
aws iam list-attached-role-policies --role-name ${ROLE_NAME}
IAMユーザ用 Policy作成
AssumeRoleする権限のみを付与
作成したRoleのみ許可するために、リソースポリシーを設定
${ROLE_ARN} を参照するために、先にロールを作成しています。
cat <<EOT > "AssumeRole-policy.json"
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"sts:AssumeRole"
],
"Resource": "${ROLE_ARN}"
}
]
}
EOT
--output text でダブルクォーテーションを外してます。
Policy_Arn="$(aws iam create-policy --policy-name AssumeRole-policy --policy-document file://AssumeRole-policy.json --query 'Policy.Arn' --output text)"
IAMポリシーをTest-userにアタッチする
アタッチポリシーに問題がないかチェックする
aws iam attach-user-policy --user-name ${IAM_USERNAME} --policy-arn ${Policy_Arn}
aws iam list-attached-user-policies --user-name ${IAM_USERNAME}
アクセスキー
作成したユーザのアクセスキーを環境変数に登録します
この段階では、Test-userはAssumeRoleの権限しかないため、ec2 describe-instances は権限エラーとなります
user_credentials="$(aws iam create-access-key --user-name ${IAM_USERNAME})"
export AWS_ACCESS_KEY_ID="$(echo $user_credentials | jq -r '.AccessKey.AccessKeyId')"
export AWS_SECRET_ACCESS_KEY="$(echo $user_credentials | jq -r '.AccessKey.SecretAccessKey')"
export AWS_DEFAULT_REGION=ap-northeast-1
aws sts get-caller-identity
aws ec2 describe-instances --query "Reservations[*].Instances[*].[VpcId, InstanceId, ImageId, InstanceType]"
AssumeRole
AssumeRoleを実行します。
ここで、EXTERNAL_IDが違う場合においても弾かれます。
ROLE_SESSION_NAME=session-test
sts_credentials="$(aws sts assume-role \
--role-arn "${ROLE_ARN}" \
--role-session-name "${ROLE_SESSION_NAME}" \
--external-id "${EXTERNAL_ID}" \
--duration-seconds 3600 \
--query "Credentials" \
--output "json")"
export AWS_ACCESS_KEY_ID="$(echo $sts_credentials | jq -r '.AccessKeyId')"
export AWS_SECRET_ACCESS_KEY="$(echo $sts_credentials | jq -r '.SecretAccessKey')"
export AWS_SESSION_TOKEN="$(echo $sts_credentials | jq -r '.SessionToken')"
get-caller-identityでAssumeRoleされているか確認後、ec2 describe-instancesでテストします。
aws sts get-caller-identity
aws ec2 describe-instances --query "Reservations[*].Instances[*].[VpcId, InstanceId, ImageId, InstanceType]"
まとめ
アクセスキーの管理が楽になる + セキュアになるので、こちらを積極的に使っていきたいです。
スクリプトを活用すれば切り替える際の手間が楽になりますね。
参考
Discussion