AWS IAM Identity CenterにXX日以上ログインしていないユーザーを確認する【2025年7月以降Ver】

AWS IAM Identity CenterにXX日以上ログインしていないユーザーを確認する【2025年7月以降Ver】

2025.11.20

こんにちは。クラウド事業本部の木村です。

以前以下の記事にて、CloudTrail と Athenaを利用してXX日以上ログインしていない未使用ユーザーを特定する方法をご案内させていただいておりました。

https://dev.classmethod.jp/articles/using-athena-to-query-iam-identity-center-sign-in-logs/

こちらの方法で棚卸し未使用ユーザーの棚卸しを行っていたのですが、ある時からログインしていたユーザーの情報が取得できなくなっていることに気がつきました。

調べてみると以下アップデートの影響でCloudTrailのログの構成が変更されており、上記で作成したAthenaテーブルとクエリではログインしたユーザーが特定ができない状態となっていることが分かりました。

https://aws.amazon.com/jp/blogs/security/modifications-to-aws-cloudtrail-event-data-of-iam-identity-center/

今回のエントリーでは、アップデートされたCloudTrail構成に対応したAthenaテーブルの作成とクエリをご紹介し、XX日以上ログインしていない未使用のユーザーを特定できることを目指します。

前提

前回の記事ではControl Tower未使用となっておりましたが、今回検証に利用しているアカウントがControl Towerを有効化しているアカウントになりますのでControl Tower使用している環境で検証結果になります。使用していない場合と比較するとバケットの格納先が異なりますが、それ以外には特段の影響はございません。

  1. CloudTrail の証跡が有効
  2. AWS Organizations 利用中
  3. IAM Identity Center のアイデンティティソース:Identity Center Directory(AWS IAM Identity Center 提供の独自 ID ストア)
  4. AWS Control Tower を使用

未使用ユーザーの洗い出し方法について

ログインしていないユーザーを特定するために、全ユーザーリストからログイン記録のあったユーザーを取り除くことで期間内にログインされていない未使用ユーザーを確認していきます。

具体的には棚卸しを行うにあたって、以下工程を経ることで未使用ユーザーを洗い出していきます。

  1. Athenaでクエリを実施して特定期間にログインのあったユーザーのuseridentityを取得する
  2. IAM Identity Centerから全ユーザーリストを取得する
  3. 1と2の工程で取得したリストを突合する

では各工程を説明していきます。

0.Athenaテーブルの作成

Athenaでクエリする前段の作業として、テーブルを作成が必要になります。こちらは初回のみ実施すれば問題ないです。
以下のDDLにて、テーブルを作成してください。

CREATE EXTERNAL TABLE `cloudtrail_idc`(
  `eventversion` string,
  `useridentity` string,
  `eventtime` string,
  `eventsource` string,
  `eventname` string,
  `awsregion` string,
  `sourceipaddress` string,
  `useragent` string,
  `errorcode` string,
  `errormessage` string,
  `requestparameters` string,
  `responseelements` string,
  `additionaleventdata` string,
  `requestid` string,
  `eventid` string,
  `resources` string,
  `eventtype` string,
  `apiversion` string,
  `readonly` string,
  `recipientaccountid` string,
  `serviceeventdetails` string,
  `sharedeventid` string,
  `vpcendpointid` string
)
PARTITIONED BY (
  `region` string,
  `date` string
)
ROW FORMAT SERDE
  'org.openx.data.jsonserde.JsonSerDe'
WITH SERDEPROPERTIES (
  'serialization.format' = '1',
  'ignore.malformed.json' = 'true'
)
STORED AS INPUTFORMAT
  'com.amazon.emr.cloudtrail.CloudTrailInputFormat'
OUTPUTFORMAT
  'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
LOCATION
  '{CloudTrailログを格納しているS3 URI}'
TBLPROPERTIES (
  'classification'='cloudtrail',
  'compressionType'='gzip',
  'projection.date.format'='yyyy/MM/dd',
  'projection.date.interval'='1',
  'projection.date.interval.unit'='DAYS',
  'projection.date.range'='NOW-1YEARS,NOW',
  'projection.date.type'='date',
  'projection.enabled'='true',
  'projection.region.type'='enum',
  'projection.region.values'='us-east-1,us-east-2,us-west-1,us-west-2,af-south-1,ap-east-1,ap-south-1,ap-northeast-2,ap-southeast-1,ap-southeast-2,ap-northeast-1,ca-central-1,eu-central-1,eu-west-1,eu-west-2,eu-south-1,eu-west-3,eu-north-1,me-south-1,sa-east-1',
  'storage.location.template'='{CloudTrailログを格納しているS3 URI}/${region}/${date}'
);

{CloudTrailログを格納しているS3 URI}としている部分については、それぞれの環境のS3 URIに置き換えてクエリを実行してください。

実行すると以下のようにテーブルが作成されます。

クエリエディタ___Athena___ap-northeast-1

1. Athenaでクエリを実施して特定期間にログインのあったユーザーのuseridentityを取得する

作成したAthenaテーブルに対してクエリを行うことで、特定の期間にログインがあったユーザーを特定していきます。

IAM Identity Centerのログインの記録はFederateイベントに記録されていますので、対象のイベントに対してクエリを実行します。

アップデート後のCloudTrailログではユーザーIDにて特定のユーザーを識別しますので、ユーザーIDを取得するようにしています。

SELECT
  json_extract_scalar(useridentity, '$.onbehalfof.userid') as userId,
  COUNT(*) as login_count,
  MAX(eventtime) as last_login
FROM cloudtrail_idc
WHERE region = 'ap-northeast-1'
  AND date BETWEEN '{start_date}' AND '{end_date}'
  AND eventname = 'Federate'
  AND json_extract_scalar(useridentity, '$.type') = 'IdentityCenterUser'
GROUP BY
  json_extract_scalar(useridentity, '$.onbehalfof.userid')
ORDER BY login_count DESC;

{start_date}と{end_date}は未使用と判定する基準日を基準に設定してください。

本日が2025/11/19が基準日で90日以内に利用されていなければ未使用と判定する場合の例では、

AND date BETWEEN '2025/08/22' AND '2025/11/19'

と設定します。

CloudTrailのログがアップデートされた2025/07中旬以前の日程を指定した場合は該当するデータがないとの表示になりますのでご注意ください。アップデート以前のログイン情報を取得する必要がある場合については以下記事の内容を参考にご確認ください。

https://dev.classmethod.jp/articles/using-athena-to-query-iam-identity-center-sign-in-logs/

上記のクエリを実行することで以下のように期間内にログインがあったユーザーIDを取得することができます。

クエリエディタ___Athena___ap-northeast-1

CSVをダウンロードすると以下のような形式となります。

"userId","login_count","last_login"
"977XXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX","39","2025-11-06T17:37:44Z"
"97aXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX","39","2025-11-19T08:52:09Z"

このように期間内にログインした記録のあるユーザーを確認することができます。

IAM Identity Centerから全ユーザーリストを取得する

続いてIAM Identity Centerからユーザーリストを取得していきます。

こちらの作業はIAM Identity Centerを管理しているアカウントもしくは委任しているアカウントにて実施してください。

まずIAM Identity Center のインスタンス情報を取得します。

STORE_ID=$(aws sso-admin list-instances --query "Instances[0].IdentityStoreId" --output text --no-paginate)
echo "Identity Store ID: ${STORE_ID}"

INSTANCE_ARN=$(aws sso-admin list-instances --query "Instances[0].InstanceArn" --output text)
echo "Instance ARN: ${INSTANCE_ARN}"

その後、ユーザー名とユーザーIDを取得します。

#!/bin/bash
echo "UserName,UserID" > "IdentityCenter-UserName.csv"
aws identitystore list-users \
  --identity-store-id "${STORE_ID}" | \
  jq -r '.Users[] | "\(.UserName),\(.UserId)"' >> "IdentityCenter-UserName.csv

上記実行すると以下のようなcsvを出力することが可能です。

UserName,UserID
kimura.test2,178XXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
kimura.test,977XXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
kimura.yuta,97aXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX

これでIAM Identity Centerのユーザーリストを取得することができました。

取得したリストを突合する

リストが取得できればあとは突合することで未使用ユーザーを確認できます。

今回実行した例ですとkimura.yutakimura.testというユーザーがログインの履歴が残っておりましたので、ログインの履歴のなかったkimura.test2が未使用のユーザーであるということが分かります。

今回は検証環境のため数が少ないので必要なかったのですが、通常の環境ではExcel等で突合するのが良さそうです。

まとめ

今回はIAM Identity Centerのユーザーの棚卸し方法についてまとめさせていただきました。
IAM等と比較するとコンソールからなど、簡単に確認する機能がないためどうしても一手間かかってしまいます。

ユーザー管理は定期的に実施することになりますので、手間を削減できるようにLambdaを定期で実行してQuick Suiteから確認できるような仕組みを近いうちにご紹介できればと思います。

以上、クラウド事業本部の木村がお届けしました。

この記事をシェアする

FacebookHatena blogX

関連記事