List Assignment API で AWS SSO ユーザーを楽チン棚卸し!
はじめに
AWS Organizations 配下の各 AWS アカウントにどのワークフォースユーザー(SSO ユーザー)がどの権限で利用することができるかを把握するためには、IAM Identity Center の「AWS アカウント」「許可セット」「グループ」「ユーザー」の関係性を理解する必要がありますが、毎回頭がこんがらかります。
弊社では自社サービスや社内システムの各種アカウントの棚卸しを定期的に(毎年年始に)行っており、AWS アカウント、ワークフォースユーザーも対象としています。
いよいよアドベントカレンダーの季節、12 月となりその棚卸しの時期が近づいてきて、気が重くなり始めていた最中、朗報がありました!
AWS IAM アイデンティティセンター向けの List Assignment API を発表いたします。この API では、どのユーザーがどの AWS アカウントとアプリケーションにアクセスできるのかを表示します。これらの API を使用すると、特定のユーザーまたはグループがアクセスできるすべての AWS アカウントとアプリケーションを一覧表示できます。(略)これまで手動による監査に費やしていた時間と労力を節約できます。
え!すごない?!これは革命かもしれない!早速試すしかない!
ということで、年始に控えている次回の棚卸しを楽チンにするため、やってみました!
前準備
動作環境
$ aws --version
aws-cli/2.15.0 Python/3.11.6 Darwin/23.1.0 source/x86_64 prompt/off
AWS CLI で SSO できるようにしておく
なるべく個別に IAM を発行したくないので、AWS CLI で AWS Organizations の管理アカウントに SSO し、IAM Identity Center に対して AWSAdministratorAccess 権限で AWS CLI コマンドを実行できるようにしておきます。
※具体的な手順は末尾の「参考にした情報」を参照。
ListAccountAssignmentsForPrincipal API でワークフォースユーザーを棚卸し
「ワークフォースユーザー名
x アカウント名
x 許可セット名
」の組み合わせの一覧を取得することを目指します。
コマンド
#!/bin/bash -eux
# 管理アカウントで AWSAdministratorAccess 権限をもつワークフォースユーザーのプロファイル
export AWS_DEFAULT_PROFILE="AWSAdministratorAccess-xxxxxxxxxxxx"
# AWS アカウントの ID と名称のキャッシュ
cache_aws_accounts=./cache_aws_accounts.txt
cat /dev/null > $cache_aws_accounts
# 許可セットの ARN と名称のキャッシュ
cache_permission_sets=./cache_permission_sets.txt
cat /dev/null > $cache_permission_sets
# IAM Identity Center の アイデンティティーストア ID
identity_store_id=$(aws sso-admin list-instances \
--query "Instances[0].IdentityStoreId" \
--output text \
--no-paginate)
# IAM Identity Center のインスタンス ARN
instance_arn=$(aws sso-admin list-instances \
--query "Instances[0].InstanceArn" \
--output text \
--no-paginate)
# ワークフォースユーザの一覧取得
aws identitystore list-users \
--identity-store-id "$identity_store_id" \
--query "Users[].[UserName,UserId]" \
--output text \
| while read user_name user_id; do
# ワークフォースユーザが利用可能な AWS アカウント ID と許可セット ARN の一覧取得
aws sso-admin list-account-assignments-for-principal \
--instance-arn "$instance_arn" \
--principal-id "$user_id" \
--principal-type USER \
--query "AccountAssignments[].[AccountId,PermissionSetArn]" \
--output text \
| sort \
| uniq \
| while read account_id permission_set_arn; do
# AWS アカウント名の取得
account_name=$(grep "$account_id" $cache_aws_accounts | cut -d "," -f 2)
if [ -z "$account_name" ]; then
account_name=$(aws organizations describe-account \
--account-id "$account_id" \
--query "Account.Name" \
--output text)
echo "${account_id},${account_name}" >> $cache_aws_accounts
fi
# 許可セット名の取得
permission_set_name=$(grep "$permission_set_arn" $cache_permission_sets | cut -d "," -f 2)
if [ -z "$permission_set_name" ]; then
permission_set_name=$(aws sso-admin describe-permission-set \
--instance-arn "$instance_arn" \
--permission-set-arn "$permission_set_arn" \
--query "PermissionSet.Name" \
--output text)
echo "${permission_set_arn},${permission_set_name}" >> $cache_permission_sets
fi
# 出力
echo "${user_name},${account_name},${permission_set_name}"
done
done \
| sort
実行結果
ワークフォースユーザー名,アカウント名,許可セット名
の一覧を取得できました!
aws-management@example.com,Audit,AWSAdministratorAccess
aws-management@example.com,Log Archive,AWSAdministratorAccess
aws-management@example.com,Management,AWSAdministratorAccess
aws-management@example.com,Management,AWSServiceCatalogEndUserAccess
aws-management@example.com,xxxxxx-develop,AWSOrganizationsFullAccess
aws-management@example.com,xxxxxx-production,AWSOrganizationsFullAccess
taro.yamada@example.com,Audit,AWSReadOnlyAccess
taro.yamada@example.com,Log Archive,AWSReadOnlyAccess
taro.yamada@example.com,Management,AWSReadOnlyAccess
taro.yamada@example.com,xxxxxx-develop,AWSAdministratorAccess
taro.yamada@example.com,xxxxxx-develop,AWSPowerUserAccess
taro.yamada@example.com,xxxxxx-develop,AWSReadOnlyAccess
taro.yamada@example.com,xxxxxx-production,AWSAdministratorAccess
taro.yamada@example.com,xxxxxx-production,AWSPowerUserAccess
taro.yamada@example.com,xxxxxx-production,AWSReadOnlyAccess
:
従来の画面とにらめっこしながら行う棚卸し作業とは比較にならないくらいめちゃくちゃ楽チンです!
今回の List Assignment API の発表は今年一番嬉しいアップデートの1つだったのではないかと思います!
おまけ:各 API のレスポンスの形式
コマンドの組み立てを理解するには各 API がどんなレスポンス(項目)を返してくるかの理解が必要です。今後の自分のためにも整理しておきます。
IAM Identity Center 情報の取得
$ aws sso-admin list-instances
{
"Instances": [
{
"CreatedDate": "2023-12-15T00:00:00.000000+09:00",
"IdentityStoreId": "d-xxxxxxxxxx",
"InstanceArn": "arn:aws:sso:::instance/ssoins-xxxxxxxxxxxxxxxx",
"OwnerAccountId": "xxxxxxxxxxxx",
"Status": "ACTIVE"
}
]
}
ワークフォースユーザーの一覧取得
$ aws identitystore list-users \
--identity-store-id "$identity_store_id"
{
"Users": [
{
"UserName": "taro.yamada@example.com",
"UserId": "xxxxxxxxxx-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"Name": {
"FamilyName": "Yamada",
"GivenName": "Taro"
},
"DisplayName": "Taro Yamada",
"Emails": [
{
"Value": "taro.yamada@example.com",
"Type": "work",
"Primary": true
}
],
"IdentityStoreId": "d-xxxxxxxxxx"
},
...
]
}
ワークフォースユーザが利用可能な AWS アカウント ID と許可セット ARN の一覧取得
$ aws sso-admin list-account-assignments-for-principal \
--instance-arn "$instance_arn" \
--principal-id "$principal_id" \
--principal-type USER
{
"AccountAssignments": [
{
"AccountId": "xxxxxxxxxxxx",
"PermissionSetArn": "arn:aws:sso:::permissionSet/ssoins-xxxxxxxxxxxxxxxx/ps-xxxxxxxxxxxxxxxx",
"PrincipalId": "xxxxxxxxxx-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"PrincipalType": "GROUP"
},
...
]
}
AWS Organozations に属する AWS アカウント情報の取得
$ aws organizations describe-account \
--account-id "$account_id"
{
"Account": {
"Id": "xxxxxxxxxxxx",
"Arn": "arn:aws:organizations::xxxxxxxxxxxx:account/o-xxxxxxxxxx/xxxxxxxxxxxx",
"Email": "xxxxxx@example.com",
"Name": "Management",
"Status": "ACTIVE",
"JoinedMethod": "INVITED",
"JoinedTimestamp": "2023-12-15T00:00:00.000000+09:00"
}
}
許可セット情報の取得
$ aws sso-admin describe-permission-set \
--instance-arn "$instance_arn" \
--permission-set-arn "$permission_set_arn"
{
"PermissionSet": {
"CreatedDate": "2023-12-15T00:00:00.000000+09:00",
"Description": "Provides full access to AWS services and resources",
"Name": "AWSAdministratorAccess",
"PermissionSetArn": "arn:aws:sso:::permissionSet/ssoins-xxxxxxxxxxxxxxxx/ps-xxxxxxxxxxxxxxxx",
"SessionDuration": "PT2H"
}
}
参考にした情報
私たち BABY JOB は、子育てを取り巻く社会のあり方を変え、「すべての人が子育てを楽しいと思える社会」の実現を目指すスタートアップ企業です。圧倒的なぬくもりと当事者意識をもって、こどもと向き合う時間、そして心のゆとりが生まれるサービスを創出します。baby-job.co.jp/
Discussion