複数の AWS アカウントに対して IAM ロールが特定のアクションを許可しているかどうか確認するシェルスクリプトを作成してみた
複数の AWS アカウントの IAM ロールに対して、特定のアクションが許可されているかどうかを確認するシェルスクリプトを作成したため、備忘録も兼ねてブログにします。
以前に公開した次のブログの内容を複数のアカウントで確認できるようにしました。
IAM ロールが特定アクションを許可しているか確認するスクリプト
複数のアカウントに対して IAM ロールが特定アクションを許可しているか確認するシェルスクリプトです。例外処理は含めていないため、あくまでサンプルと理解していただけますと幸いです。
#!/bin/bash
# 調査対象のAWSアカウント一覧
ACCOUNT_ID_LIST=(111122223333 444455556666)
# 調査対象のAWSアカウントで事前に作成しているIAMロール名
ROLE_NAME="test-tool-access-role"
# AWS CloudTrailに記録されるセッション名
ROLE_SESSION_NAME=" test-tool"
# IAMロールで許可されているかどうか確認するアクション
ACTION_NAME="iam:CreateRole iam:AttachRolePolicy iam:PutRolePolicy"
for account_id in "${ACCOUNT_ID_LIST[@]}"; do
echo "### Account ID: ${account_id}"
# AssumeRoleにより一時的なクレデンシャルを取得
assume_role_output=$(aws sts assume-role --role-arn arn:aws:iam::$account_id:role/$ROLE_NAME --role-session-name $ROLE_SESSION_NAME)
access_key_id=$(echo "${assume_role_output}" | jq -r '.Credentials.AccessKeyId')
secret_access_key=$(echo "${assume_role_output}" | jq -r '.Credentials.SecretAccessKey')
session_token=$(echo "${assume_role_output}" | jq -r '.Credentials.SessionToken')
# IAMロール一覧を取得してIAM Policy SimulatorでACTION_NAMEの許可があるか確認
AWS_ACCESS_KEY_ID=$access_key_id AWS_SECRET_ACCESS_KEY=$secret_access_key AWS_SESSION_TOKEN=$session_token \
aws iam list-roles --query='Roles[?!(starts_with(RoleName,`AWSServiceRoleFor`))].[Arn]' --output text \
| while read role_arn; do
echo "${role_arn}"
AWS_ACCESS_KEY_ID=$access_key_id AWS_SECRET_ACCESS_KEY=$secret_access_key AWS_SESSION_TOKEN=$session_token \
aws iam simulate-principal-policy \
--policy-source-arn ${role_arn} \
--action-names ${ACTION_NAME} \
--query EvaluationResults[].[EvalActionName,EvalDecision] \
--output text
done
done
本スクリプトを実行するアカウントから調査対象のアカウントに AssumeRole して調査します。そのため、事前に調査対象のアカウントでスクリプト実行アカウントを信頼する IAM ロールを作成しておく必要があります。
2024 年 9 月 28 日時点の AWS CloudShell では追加のソフトウェアのインストールの必要なく実行できます。
実行結果例を一部抜粋して掲載します。
allowed は許可、implicitDeny は暗黙的な拒否を示します。
$ sh test-tool.sh
### Account ID: 444455556666
(略)
arn:aws:iam::444455556666:role/test-access-role
iam:CreateRole implicitDeny
iam:AttachRolePolicy implicitDeny
iam:PutRolePolicy implicitDeny
arn:aws:iam::444455556666:role/test-admin-role-for-idc
iam:CreateRole allowed
iam:AttachRolePolicy allowed
iam:PutRolePolicy allowed
(略)
### Account ID: 111122223333
(略)
arn:aws:iam::111122223333:role/test-access-role
iam:CreateRole implicitDeny
iam:AttachRolePolicy implicitDeny
iam:PutRolePolicy implicitDeny
arn:aws:iam::111122223333:role/test-org-aggregator-role
iam:CreateRole implicitDeny
iam:AttachRolePolicy implicitDeny
iam:PutRolePolicy implicitDeny
(略)
変数は値を変更して利用する必要があります。
変数名 | 説明 |
---|---|
ACCOUNT_ID_LIST | 調査対象の AWS アカウント一覧を指定 |
ROLE_NAME | 調査対象の AWS アカウントで事前に作成している IAM ロール名を指定 |
ROLE_SESSION_NAME | AWS CloudTrail に記録されるセッション名を指定 |
ACTION_NAME | IAM ロールで許可されているかどうか確認するアクションを指定 |
ACCOUNT_ID_LIST
調査対象の AWS アカウント一覧を指定します。
AWS アカウント数が多い場合は、別ファイルで管理したほうが楽かもしれません。
また、AWS Organizations 環境の場合は AWS Organizations の API を利用してアカウント一覧を取得する方法もあります。次のブログがその方法を利用しています。
ROLE_NAME
調査対象の AWS アカウントで利用する IAM ロール名を指定します。IAM ロールは事前に作成しておく必要があります。
本ブログのスクリプトで実行している IAM ロールを対象とした IAM Policy Simulator の実行に必要な権限は次のユーザーガイドに記載があります。
IAM ロールにアタッチする IAM ポリシーのポリシー例です。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"iam:GetContextKeysForCustomPolicy",
"iam:GetRole",
"iam:GetPolicyVersion",
"iam:SimulatePrincipalPolicy",
"iam:SimulateCustomPolicy",
"iam:GetPolicy",
"iam:ListAttachedRolePolicies",
"iam:ListRoles",
"iam:ListRolePolicies",
"iam:GetRolePolicy",
"iam:GetContextKeysForPrincipalPolicy"
],
"Resource": "*"
}
]
}
IAM ロールの信頼ポリシー例です。スクリプトを実行するアカウントを信頼します。下記例の root の記載はアカウント内の全ての IAM ユーザーや IAM ロールなどに対する信頼のため、スクリプトを実行する主体が限られている場合は信頼する条件を絞ったほうが良いと思います。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::111122223333:root"
},
"Action": "sts:AssumeRole"
}
]
}
上記の内容を設定する CloudFormation テンプレートも掲載します。パラメータの TrustedAccountID は信頼ポリシーで指定するスクリプト実行アカウントの ID を指定します。
AWSTemplateFormatVersion: 2010-09-09
Description: Create IAM Role
Parameters:
IAMRoleName:
Type: String
Description: IAM Role Name
Default: test-tool-access-role
IAMPolicyName:
Type: String
Description: IAM Policy Name
Default: test-tool-access-policy
TrustedAccountID:
Type: String
Description: Trusted Account ID
Default: 111122223333
Metadata:
AWS::CloudFormation::Interface:
ParameterGroups:
- Label:
default: AWS IAM Role
Parameters:
- IAMRoleName
- IAMPolicyName
- TrustedAccountID
Resources:
IAMRole:
Type: "AWS::IAM::Role"
Properties:
RoleName: !Ref IAMRoleName
Path: "/"
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Principal:
AWS:
- !Sub "arn:aws:iam::${TrustedAccountID}:root"
Action: "sts:AssumeRole"
ManagedPolicyArns:
- !Ref IAMPolicy
IAMPolicy:
Type: 'AWS::IAM::ManagedPolicy'
Properties:
ManagedPolicyName: !Ref IAMPolicyName
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- 'iam:GetContextKeysForCustomPolicy'
- 'iam:GetRole'
- 'iam:GetPolicyVersion'
- 'iam:SimulatePrincipalPolicy'
- 'iam:SimulateCustomPolicy'
- 'iam:GetPolicy'
- 'iam:ListAttachedRolePolicies'
- 'iam:ListRoles'
- 'iam:ListRolePolicies'
- 'iam:GetRolePolicy'
- 'iam:GetContextKeysForPrincipalPolicy'
Resource: '*'
ROLE_SESSION_NAME
AssumeRole により調査対象アカウントで AWS CLI を実行する際に AWS CloudTrail に記録されるセッション名を指定します。
調査対象アカウントで記録される IAM Policy Simulator の CloudTrail イベント例ですイベント名は SimulatePrincipalPolicy であり、イベント履歴画面では「ユーザー名」として記録されています。
1 つの SimulatePrincipalPolicy イベントの詳細です。
{
"eventVersion": "1.10",
"userIdentity": {
"type": "AssumedRole",
"principalId": "AROAYS2EXAMPLEEXAMPLE:test-tool",
"arn": "arn:aws:sts::444455556666:assumed-role/test-tool-access-role/test-tool",
"accountId": "444455556666",
"accessKeyId": "ASIAYS2NR3GH7D7EFJVR",
"sessionContext": {
"sessionIssuer": {
"type": "Role",
"principalId": "AROAYS2EXAMPLEEXAMPLE",
"arn": "arn:aws:iam::444455556666:role/test-tool-access-role",
"accountId": "444455556666",
"userName": "test-tool-access-role"
},
"attributes": {
"creationDate": "2024-09-28T14:35:37Z",
"mfaAuthenticated": "false"
}
}
},
"eventTime": "2024-09-28T14:36:52Z",
"eventSource": "iam.amazonaws.com",
"eventName": "SimulatePrincipalPolicy",
"awsRegion": "us-east-1",
"sourceIPAddress": "18.176.236.26",
"userAgent": "aws-cli/2.17.57 md/awscrt#0.21.2 ua/2.0 os/linux#6.1.109-118.189.amzn2023.x86_64 md/arch#x86_64 lang/python#3.12.6 md/pyimpl#CPython exec-env/CloudShell cfg/retry-mode#standard md/installer#exe md/distrib#amzn.2023 md/prompt#off md/command#iam.simulate-principal-policy",
"requestParameters": {
"policySourceArn": "arn:aws:iam::444455556666:role/test-tool-access-role",
"actionNames": [
"iam:CreateRole",
"iam:AttachRolePolicy",
"iam:PutRolePolicy"
]
},
"responseElements": null,
"requestID": "44430e83-9474-471a-a9a3-9d67e89f85ca",
"eventID": "9829d500-6d6e-4b96-8d12-967247c56d0c",
"readOnly": true,
"eventType": "AwsApiCall",
"managementEvent": true,
"recipientAccountId": "444455556666",
"eventCategory": "Management",
"tlsDetails": {
"tlsVersion": "TLSv1.3",
"cipherSuite": "TLS_AES_128_GCM_SHA256",
"clientProvidedHostHeader": "iam.amazonaws.com"
}
}
ACTION_NAME
IAM ロールで許可されているかどうか確認するアクションを指定します。複数指定できます。
aws iam simulate-principal-policy
コマンドのaction-names
オプションで指定する値となります。
- simulate-principal-policy — AWS CLI 2.17.61 Command Reference
- simulate-principal-policy — AWS CLI 1.34.29 Command Reference
以上で、シェルスクリプトに関する説明は終わりです。
さいごに
AssumeRole を利用して、複数の AWS アカウントの IAM ロールに対して IAM Policy Simulator を実行する機会があったため、作成したシェルスクリプトを紹介しました。今回は IAM Policy Simulator の利用でしたが、調査したい内容によってはシェルスクリプトで AWS CLI 実行ではなく、AWS Config の高度なクエリで楽に実現できる場合もあると思います。また、AWS Organizations 環境の場合は、AWS Resource Explorer も活用できるかもしれません。
以上、このブログがどなたかのご参考になれば幸いです。