IAM 権限を絞る前に「実際にどの API を使っているか」を CloudTrail・Access Analyzer で調べてみた
製造ビジネステクノロジー部の小林です。
IAM ポリシーを最小権限に近づけようとして、フルアクセスや広めのポリシーを絞り込む場面はよくあります。このとき悩ましいのが「実際にはどのアクションを使っているのか」が分からないまま削ってしまうことです。使っているアクションまで巻き込んで消すと、権限を絞った直後にアプリが動かなくなります。
そこで今回は、IAM 権限を絞る前に「そのロールやユーザーが実際にどの API を呼んでいるか」を調べる方法を、SES を例に実際に手を動かして確認してみました。使用するのは CloudTrail(イベント履歴・Athena・CloudTrail Lake)、IAM Access Analyzer のポリシー生成、IAM の最終アクセス情報です。
やってみた
CloudTrail のイベント履歴で、対象ロールが呼んでいる SES の API を見ます。マネジメントコンソールの CloudTrail → イベント履歴で、属性「イベントソース」を ses.amazonaws.com で絞り込みます。

ここで GetSendQuota や GetAccount といったイベント名が出てくれば、「送信だけじゃなくレート問い合わせも使っている」と分かります。イベント履歴は直近 90 日ぶんしか遡れないので、月次バッチのようにたまにしか動かない処理を取りこぼさないよう注意したいところです。

もっとまとまった期間を集計したいときは、トレイルを S3 に出しておいて Athena で集計するのが便利です。CloudTrail 用テーブルに対して、こんなクエリでイベント名ごとの回数を数えられます。
-- SES を呼んでいるのは「どのアクション・どのロールか」をまとめて見る。
-- 送信(SendRawEmail/SendEmail)はデータイベントのため、
-- SESでデータイベント記録を有効にしていない限りここには出てこない点に注意。
SELECT
eventname,
useridentity.sessioncontext.sessionissuer.username AS role,
count(*) AS cnt
FROM <テーブル名>
WHERE eventsource = 'ses.amazonaws.com'
AND from_iso8601_timestamp(eventtime) > current_date - interval '90' day -- 遡る期間。長期運用ほど広めに取る
GROUP BY 1, 2
ORDER BY cnt DESC;
eventsourceをses.amazonaws.comに絞って、SES 関連のイベントだけを対象にしています- ここに
GetSendQuotaのような読み取り系が出てくれば、送信だけでなくそのアクションも実際に使われている、と分かります

権限を絞りたい対象ロールが分かっているなら、上の集計で正確なロール名を確認してから、そのロールだけに絞り込みます。
-- 上の集計で確認した実在のロール名に置き換えてから絞り込む。
SELECT eventname, count(*) AS cnt
FROM cloudtrail_logs
WHERE eventsource = 'ses.amazonaws.com'
AND useridentity.sessioncontext.sessionissuer.username = 'my-app-role' -- 集計で確認した実際のロール名
AND from_iso8601_timestamp(eventtime) > current_date - interval '90' day
GROUP BY eventname
ORDER BY cnt DESC;
ここで対象ロールのアクションだけが表示されれば、それがそのロールに残すべき権限の候補です
CloudTrail Lake で SQL 検索する
同じ SQL でも、Athena のようにテーブル定義や S3・ワークグループを準備せずに済ませたいなら CloudTrail Lake が楽です。イベントデータストアにイベントをためておき、コンソール上からそのまま SQL を投げられるマネージドな仕組みです。
イベントデータストアを作ったら、「クエリを実行」から SQL を書きます。CloudTrail Lake は Trino ベースの SQL で、FROM にはイベントデータストアの ID を指定します。Athena とはカラム名が少し違うので、こんな形になります。
-- 対象ロールが呼んだ SES の API を、イベント名ごとに集計する(CloudTrail Lake / Trino SQL)。
-- FROM には自分のイベントデータストア ID を入れる。
SELECT eventName, count(*) AS cnt
FROM <event-data-store-id>
WHERE eventSource = 'ses.amazonaws.com'
AND userIdentity.sessionContext.sessionIssuer.userName = 'your-role-name' -- 調べたいロール名に置き換える
AND eventTime > '2026-07-01 00:00:00' -- 遡りたい期間の開始日時
GROUP BY eventName
ORDER BY cnt DESC

イベントデータストアの取り込み・保持に応じた料金がかかるので、常設するか調査のときだけ使うかは用途に合わせて考えるとよさそうです。
ざっと眺めるだけならイベント履歴、SQL で数えたいけど準備は最小限にしたいなら Lake、すでに Athena 基盤があるなら Athena、という使い分けがおすすめです。
IAM Access Analyzer でポリシーを生成する
次に、CloudTrail の実績からポリシー案を自動で作ってもらう方法です。IAM Access Analyzer のポリシー生成は、指定期間(最大 90 日)の CloudTrail イベントを解析して、そのロールが実際に使ったアクションだけを含むポリシーテンプレートを作ってくれます。
IAM コンソールで対象ロールを開き、権限タブから「アクセス許可を生成」を選び、解析対象の期間、参照する CloudTrail の証跡(トレイル)、Access Analyzer がトレイルにアクセスするためのサービスロールを指定します。

解析が終わると、使用実績のあるサービス・アクションをもとにしたポリシー案が表示されます。
(今回の検証では追加のポリシーはありませんでした)


IAM の最終アクセス情報で当たりを付ける
ロールやポリシーの画面から、どのサービスに最近アクセスしたか、サービスによってはどのアクションを最後に使ったかまで確認できます。

これも過去に実際に使用された実績前提なので、たまにしか使わないアクションは期間の取り方次第で取りこぼします。細かいアクション単位まで追いたいなら、やはり CloudTrail のログを確認するのが確実です。
まとめ
IAM 権限を絞る前に「実際にどの API を使っているか」を調べる方法を、SES を例に試してみました。
おすすめの流れは、まず IAM の最終アクセス情報でどのサービスを使っているか当たりを付け、次に CloudTrail で実際に呼ばれている API を洗い出し、最後に Access Analyzer でポリシー案を作らせる、という三段階です。
CloudTrail での洗い出しは、ざっと眺めるだけならイベント履歴、SQL で集計したいけれど準備は最小限にしたいなら CloudTrail Lake、すでに Athena 基盤があるなら Athena、と状況に応じて使い分けるとよいでしょう。
権限を絞る前のひと手間として、実際の利用ログを確認する習慣をつけておきたいですね。
この記事がどなたかの参考になれば幸いです。







