1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【AWS Organization】メンバーアカウントのルートユーザー認証情報が存在しているかを一覧する

Last updated at Posted at 2025-02-27

どのアカウントにルートユーザー認証情報が存在しているか一覧を取得して、スプシやスクリプトで処理したくなるけど、マネコンだと取れないし、ググってもよくわかんな~い
という訳で考えてみた、という記事です

→ 本編はこちら

前提

AWS Organization マスターアカウントでマネジメントコンソールへログインし、IAMコンソールの「アカウント設定」で「メンバーアカウントのための一元化されたルートアクセス」が有効であること。
image.png

あと、本記事に記載のAWS CLIコマンドは、AWS CLIバージョンが古いと出来ないようです。(AWS CLI 2.15.4 on Windowsだと出来なくて、2.24.13 on Windowsだと出来ることは確認できています)

マネコンで見れる

IAMコンソールの「ルートアクセス管理」で、添付画像のような形で見ることができる。

image.png

アカウントごとに、ルートユーザーアクセスキーおよびコンソールパスワードの存在有無の一覧が欲しくても、いちいちクリックして転記しなければならないのか。

AWS CLIでがんばる

以下のAWS CLIコマンド①~②をスクリプト等でメンバーアカウントごとにループ処理する;

①AWS Organization マスターアカウントでは、ルートユーザー認証情報の存在有無にかかわらずメンバーアカウントのルートユーザー認証情報を取得可能

$ aws sts assume-root --target-principal <member account id> --task-policy-arn "arn=arn:aws:iam::aws:policy/root-task/IAMAuditRootUserCredentials" --profile <cli profile name of master account>
{
    "Credentials": {
        "AccessKeyId": "*******",
        "SecretAccessKey": "*******",
        "SessionToken": "*******",
        "Expiration": "*******"
    }
}

※注意:メンバーアカウントの一時的認証情報が帰ってきているが、これをもって当該アカウントにルートユーザーアクセスキーが存在すると見なすことは出来ない
※注釈:ここで取れる認証情報はルートユーザーの一時的認証情報ではあるものの、--task-policy-arnで指定されたポリシーに記載のオペレーションしか出来ない。しかしながら、ルートユーザーにしか出来ない操作が出来る認証情報ではあるため、ルートユーザーアクセスキーと同じくらい厳重に管理すべき

②ルートユーザーの認証情報/MFAデバイス/コンソールパスワード、およびデジタル署名用証明書の存在を確認する

aws iam get-account-summary --profile <member account root user profile name by above temporary credential>
{
    "SummaryMap": {
        "GroupPolicySizeQuota": 5120,
        "InstanceProfilesQuota": 1000,
        "Policies": 10,
        "GroupsPerUserQuota": 10,
        "InstanceProfiles": 0,
        "AttachedPoliciesPerUserQuota": 10,
        "Users": 2,
        "PoliciesQuota": 1500,
        "Providers": 1,
        "AccountMFAEnabled": 1,
        "AccessKeysPerUserQuota": 2,
        "AssumeRolePolicySizeQuota": 2048,
        "PolicyVersionsInUseQuota": 10000,
        "GlobalEndpointTokenVersion": 1,
        "VersionsPerPolicyQuota": 5,
        "AttachedPoliciesPerGroupQuota": 10,
        "PolicySizeQuota": 6144,
        "Groups": 1,
        "AccountSigningCertificatesPresent": 0,
        "UsersQuota": 5000,
        "ServerCertificatesQuota": 20,
        "MFADevices": 3,
        "UserPolicySizeQuota": 2048,
        "PolicyVersionsInUse": 49,
        "ServerCertificates": 0,
        "Roles": 48,
        "RolesQuota": 1000,
        "SigningCertificatesPerUserQuota": 2,
        "MFADevicesInUse": 3,
        "RolePolicySizeQuota": 10240,
        "AttachedPoliciesPerRoleQuota": 10,
        "AccountAccessKeysPresent": 0,
        "AccountPasswordPresent": 1,
        "GroupsQuota": 300
    }
}

AccountMFAEnabled:1ならばルートユーザーのMFAが有効である
AccountAccessKeysPresent:1ならばルートユーザーのアクセスキーが存在している
AccountPasswordPresent:1ならばルートユーザーのコンソールサインイン用パスワードが存在している
AccountSigningCertificatesPresent:1ならばデジタル署名用証明書が存在している

※注意:ルートユーザーアクセスキーが無効化されていても、存在していればAccountAccessKeysPresentは1になる

リストするサンプルコード

# pip install boto3
# pip install -U boto3

import boto3

ORGANIZATION_MASTER_ACCOUNT_ID = '<enter your organization master account id>'

_session = boto3.Session(profile_name='organization master account')
_orgclient = _session.client('organizations')
_stsclient = _session.client('sts', region_name='us-east-1', endpoint_url="https://sts.us-east-1.amazonaws.com")

def list_organizations_accounts(NextToken=None):
    response = _orgclient.list_accounts(NextToken=NextToken) if NextToken else _orgclient.list_accounts()
    accounts =response['Accounts']
    if 'NextToken' in response:
        accounts.extend(list_organizations_accounts(response['NextToken']))
    return accounts

with open('member_account_rootuser_credential_summary.tsv', 'w') as f:
  f.write(f'accountId\taccountName\tAccountMFAEnabled\tAccountAccessKeysPresent\tAccountPasswordPresent\tAccountSigningCertificatesPresent\n')

for account in list_organizations_accounts():
    accountId = account['Id']
    accountName = account['Name']
    if accountId == ORGANIZATION_MASTER_ACCOUNT_ID:
       continue
    print(f'Account ID: {accountId}, Account Name: {accountName}')

    rootUserCredential = _stsclient.assume_root(
      TargetPrincipal=accountId,
      TaskPolicyArn={
          'arn': 'arn:aws:iam::aws:policy/root-task/IAMAuditRootUserCredentials'
      },
      DurationSeconds=123
    )
    # {'Credentials': {'AccessKeyId': '***', 'SecretAccessKey': '***', 'SessionToken': '***'}}

    iam_client = boto3.Session(
      aws_access_key_id=rootUserCredential['Credentials']['AccessKeyId'],
      aws_secret_access_key=rootUserCredential['Credentials']['SecretAccessKey'],
      aws_session_token=rootUserCredential['Credentials']['SessionToken'],
      region_name='us-east-1'
    ).client('iam')

    account_summary = iam_client.get_account_summary()
    summaryMap = account_summary['SummaryMap']

    AccountMFAEnabled = summaryMap['AccountMFAEnabled']
    AccountAccessKeysPresent = summaryMap['AccountAccessKeysPresent']
    AccountPasswordPresent = summaryMap['AccountPasswordPresent']
    AccountSigningCertificatesPresent = summaryMap['AccountSigningCertificatesPresent']

    print(f'AccountMFAEnabled: {AccountMFAEnabled}, AccountAccessKeysPresent: {AccountAccessKeysPresent}, AccountPasswordPresent: {AccountPasswordPresent}, AccountSigningCertificatesPresent: {AccountSigningCertificatesPresent}')

    with open('member_account_rootuser_credential_summary.tsv', 'a') as f:
      f.write(f'{accountId}\t{accountName}\t{AccountMFAEnabled}\t{AccountAccessKeysPresent}\t{AccountPasswordPresent}\t{AccountSigningCertificatesPresent}\n')

boto3でやる時の注意点

2025年2月27日現在、STSのグローバルエンドポイントではAssumeRoleオペレーションに対応していないので、APIからエラーが返ってくる。

なので、以下のようにboto3 clientオブジェクトを生成する際にリージョンとエンドポイントURLを指定する必要がある。

_stsclient = _session.client('sts', region_name='us-east-1', endpoint_url="https://sts.us-east-1.amazonaws.com")

結果

以下のような、アカウントIDごとにアカウント名と、ルートユーザー認証情報およびコンソールサインインパスワードの存在有無、ルートユーザーMFA、デジタル署名用証明書の有無がのったTSVファイルが得られる。

member_account_rootuser_credential_summary.tsv
accountId	accountName	AccountMFAEnabled	AccountAccessKeysPresent	AccountPasswordPresent	AccountSigningCertificatesPresent
****	****	0	0	1	0
****	****	0	0	1	0
****	****	0	0	1	0
****	****	0	0	0	0

ちなみに わたしは ねこちゃん 大好きマンです

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?