💡

AssumeRole をやってみる

2023/02/26に公開

はじめに

セキュアに使用できる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]"

まとめ

アクセスキーの管理が楽になる + セキュアになるので、こちらを積極的に使っていきたいです。
スクリプトを活用すれば切り替える際の手間が楽になりますね。

参考

https://aws.amazon.com/jp/premiumsupport/knowledge-center/iam-assume-role-cli/
https://dev.classmethod.jp/articles/assume-role-deploy-iam-user-and-role/

Discussion