退職者のAWSアクティビティ監査 ── CloudTrailイベント履歴とAthenaによるユーザー単位の操作追跡

目次

概要

退職した従業員のAWSアカウントが適切に無効化されておらず、退職後もリソースの作成や設定変更が行われていた――こうしたケースは、アクセス管理の不備によって実際に発生しうるセキュリティ上の問題です。請求の異常な増加をきっかけに発覚することも多く、その場合は「誰が・いつ・どのリソースを作成・変更したのか」を迅速に特定する必要があります。

本記事では、特定のIAMユーザーのすべてのアクティビティを追跡するために、CloudTrailイベント履歴とAmazon Athenaを活用したユーザー単位の操作監査の方法を解説します。コスト異常の検知やリソース構成の管理に適した他のサービスとの使い分けも整理します。

退職者のIAMユーザーによるリソース作成をCloudTrailとAthenaで調査するフロー図
退職者のIAMユーザーによるリソース作成をCloudTrailとAthenaで調査するフロー図

この記事のメリット

  • 退職者や不審なユーザーのAWSアクティビティを特定するための調査手順を理解できる
  • CloudTrailイベント履歴を使ったユーザー名ベースのフィルタリング方法を習得できる
  • Athenaを使ったCloudTrailログのテーブル作成とSQLクエリによる包括的な分析方法を学べる
  • イベントソースによるパーティショニングで効率的にクエリを実行する手法を理解できる
  • Cost Explorer・Config Aggregator・Cost Anomaly Detectionとの役割の違いを正確に判断できるようになる

執筆者とキャラクター紹介

執筆者:土肥(とひ)

株式会社ジェニュインの代表であり元エンジニア。これまでオンプレミスと AWS 環境のインフラ業務を担当。AWS 認定資格の学習で得た知識を、ハンズオンとともに解説するのが得意。直近では新人の教育も行っており、これから技術を学ぶ方が納得できる解説を心がけています。基礎編・Cloud Practitioner の記事では、解説役としても登場します。

土肥

クラウドおさる

クラウドおさる

はじめましてでござる。弊猿はクラウドおさる。IT インフラが異常に発達した猿山から、雲に乗って地上の AWS を学びに降りてきたのでござる。

クラウドおさる

基礎編や Cloud Practitioner の記事では、とひさんに素朴な疑問をぶつける役でござるな。Security - Specialty などの記事では、要所でワンポイントや注意点をひとこと添えるでござる。

クラウドおさる

猿山にもデータセンターや監視当番があって、地上で起きることはだいたい猿山にも同じ仕組みがあるのでござる。例え話がつい猿山に寄るのは、弊猿の癖でござる。

技術解説

ユーザー単位のアクティビティ監査が必要な場面

退職者や異動者のアカウント管理が不十分な場合、以下のようなリスクが発生します。

  • 退職後もAWSリソースの作成・変更が可能な状態が続く
  • 不要なリソースが作成され、意図しないコストが発生する
  • セキュリティグループの変更やIAMポリシーの改変により、セキュリティリスクが高まる

こうした問題の調査では、特定のユーザーが行ったすべての操作を洗い出す必要があります。アクセスキーの漏洩調査がアクセスキーIDを軸にするのに対し、ユーザー単位の監査はIAMユーザー名を軸にしてコンソール操作とAPI操作の両方を追跡する点が異なります。

調査手段の比較

特定ユーザーのアクティビティを監査するための手段と、混同しやすい他のサービスを比較します。

サービス確認できる内容ユーザー単位の操作監査
CloudTrailイベント履歴過去90日間の管理イベント(ユーザー名でフィルタリング可能)適している(簡易調査)
Amazon Athena + CloudTrailログS3に保存されたCloudTrailログに対するSQL分析適している(包括的な調査)
Cost Explorerサービス別・アカウント別のコスト推移と内訳不向き(コスト中心で操作履歴は含まない)
AWS Config Aggregatorリソースの構成変更履歴とコンプライアンス状態不向き(リソース中心でユーザーの操作履歴は対象外)
Cost Anomaly Detectionコストの異常な変動の検知とアラート不向き(コスト異常の検知のみで、原因となったリソースや操作の特定はできない)

なぜCost Explorerでは不十分なのか

Cost Explorerはサービス別・期間別のコスト推移を可視化するツールです。請求額の増加は確認できますが、「誰がどのリソースを作成したか」という操作レベルの情報は含まれていません。コスト増加の原因を特定するには、CloudTrailログによるAPI操作の調査が必要です。

なぜConfig Aggregatorでは不十分なのか

AWS Config Aggregatorは、複数のアカウントやリージョンにまたがるリソースの構成情報を集約するサービスです。リソースの設定変更履歴やコンプライアンス状態を確認できますが、誰がその変更を行ったかという操作者の情報の追跡には適していません。

なぜCost Anomaly Detectionでは不十分なのか

Cost Anomaly Detectionは機械学習を使ってコストの異常な変動を自動検知するサービスです。「コストが通常と異なるパターンで増加している」ことを検知できますが、その原因となった具体的な操作やリソースの特定はできません。

CloudTrailイベント履歴の特徴

CloudTrailイベント履歴は、AWSアカウントで行われたAPI操作を記録するサービスです。ユーザー単位の監査に関連する特徴を整理します。

  • 過去90日間の管理イベントがデフォルトで記録される(追加費用なし)
  • ユーザー名でフィルタリングして特定ユーザーの操作を検索できる
  • 時間範囲を指定して検索対象を絞り込める
  • コンソール操作もAPI操作も管理イベントとして記録される

90日間のイベント履歴は簡易的な調査には十分ですが、大量のイベントを効率的に分析したい場合や、90日を超える期間の調査が必要な場合は、S3に保存されたCloudTrailログをAthenaでクエリする方法が適しています。

CloudTrailログでユーザーを特定するフィールド

CloudTrailログのJSONには、操作を実行したユーザーの情報が userIdentity オブジェクトに記録されます。ユーザー単位の監査で注目すべきフィールドは以下の通りです。

フィールド説明監査での用途
userIdentity.userNameIAMユーザー名特定ユーザーの操作をフィルタリング
userIdentity.arnユーザーのARNユーザーの一意な識別
eventTimeAPI呼び出しの日時操作のタイムラインの把握
eventName実行されたAPIアクション名リソースの作成・変更・削除の特定
eventSourceAPIを提供するAWSサービス操作対象のサービスの特定
awsRegionAPI呼び出しが行われたリージョン操作が行われたリージョンの特定
sourceIPAddressAPI呼び出し元のIPアドレス退職後のアクセス元の確認

Athenaによるイベントソース別パーティショニング

CloudTrailログをAthenaで分析する際、イベントソース(eventsource)でパーティショニングすると、特定のサービスに絞ったクエリを効率的に実行できます。

パーティショニングを使わない場合、クエリはすべてのCloudTrailログファイルをスキャンするため、データ量に比例して実行時間とコストが増加します。イベントソースでパーティショニングすると、例えば ec2.amazonaws.com のイベントだけを対象にクエリを実行でき、スキャン対象のデータ量を大幅に削減できます。

パーティショニングなし(全データスキャン)とイベントソース別パーティショニング(対象サービスのみスキャン)の比較図
パーティショニングなし(全データスキャン)とイベントソース別パーティショニング(対象サービスのみスキャン)の比較図
フリーランス案件
クラウドおさる
クラウドキャリアフリーランス

AWS の実務経験があるなら、単価を上げにいく

AWS に特化したフリーランスエージェントです。以下は取り扱い案件の一例です。設計・SRE・セキュリティ・生成 AI の領域で、専門を掛け合わせるほど単価が上がります。

横にスクロールできます。掲載時点の情報のため、募集が終了している場合があります。条件の近い案件をご紹介しますので、お気軽にご相談ください。

実践

ここでは、退職者のIAMユーザーが行ったAWSアクティビティを、CloudTrailイベント履歴とAthenaの2つの方法で調査する手順を説明します。

前提条件

  • CloudTrailのイベント履歴は、確認したいリージョンで開きます(本記事では ap-northeast-1(東京))
  • Athenaのクエリは、CloudTrailログが保存されているS3バケットと同じリージョンで実行します
  • 以下のリソースが作成済みであること
リソース種別リソース名用途
CloudTrail証跡任意ログをS3バケットに配信する証跡
S3バケットCloudTrailログ保存用CloudTrailログの保存先
S3バケットAthenaクエリ結果保存用Athenaのクエリ結果の保存先
IAMユーザー調査対象ユーザー(例: former-employee)監査対象となるユーザー

ステップ1: CloudTrailイベント履歴でユーザーの操作を確認する

まず、CloudTrailコンソールのイベント履歴を使って、特定のIAMユーザーの操作を簡易的に確認します。

  • AWSマネジメントコンソールにログインし、リージョンがap-northeast-1(東京)であることを確認します
  • 上部の検索バーにCloudTrailと入力し、表示された「CloudTrail」を選択します
  • 左側ナビゲーションの「イベント履歴」を選択します
CloudTrailコンソールの「イベント履歴」画面の初期表示
CloudTrailコンソールの「イベント履歴」画面の初期表示
  • 検索フィルターのドロップダウンで「ユーザー名」を選択します
  • フィルターの入力欄に調査対象のIAMユーザー名(例: former-employee)を入力します
  • 時間範囲を調査対象の期間に設定します(例: 過去30日間)
ユーザー名フィルターに「former-employee」を入力し、イベント一覧が表示された状態
ユーザー名フィルターに「former-employee」を入力し、イベント一覧が表示された状態

フィルタリング結果から、そのユーザーが実行したAPI操作の一覧が表示されます。RunInstances、CreateSecurityGroup、PutBucketPolicy などのリソース作成・変更に関するイベントに注目します。

  • 詳細を確認したいイベントのイベント名をクリックします
  • イベントの詳細画面で、リクエストパラメータやレスポンス要素を確認します
イベント詳細画面(イベント名、イベント時間、ユーザー名、ソースIPアドレスなどが表示された状態)
イベント詳細画面(イベント名、イベント時間、ユーザー名、ソースIPアドレスなどが表示された状態)

イベント履歴は過去90日間の管理イベントのみが対象です。データイベント(S3オブジェクトレベルの操作など)を確認するには、証跡でデータイベントのログ記録を有効にした上でAthenaでクエリする必要があります。

ステップ2: CloudTrailコンソールからAthenaテーブルを作成する

イベント履歴での簡易調査に加え、より包括的な分析を行うためにAthenaテーブルを作成します。

  • CloudTrailログが保存されているS3バケットと同じリージョンに切り替えます
  • CloudTrailコンソールの左側ナビゲーションから「イベント履歴」を選択します
  • 画面上部の「Athena テーブルを作成」をクリックします
  • 「ストレージの場所」ドロップダウンでCloudTrailログが保存されているS3バケットを選択します
  • 「Athena テーブル名」は cloudtrail_logs_<バケット名> の形で自動生成されます(変更はAthena側で行います)
  • ダイアログには実行される CREATE EXTERNAL TABLE 文がそのまま表示されます。内容を確認して「テーブルを作成」をクリックします
「Amazon Athena でテーブルを作成」ダイアログ(ストレージの場所を選択し、生成されるDDLが表示された状態)
「Amazon Athena でテーブルを作成」ダイアログ(ストレージの場所を選択し、生成されるDDLが表示された状態)

この操作により、選択したS3バケットのCloudTrailログに対応するAthenaテーブルが default データベースに自動作成されます。以降のクエリでは、このテーブル名を使います。

ステップ3: Athenaのクエリ結果保存先を確認する

Athenaのクエリを実行するには、クエリ結果の保存先が設定されている必要があります。

  • 上部の検索バーにAthenaと入力し、表示された「Athena」を選択します
  • 左側ナビゲーションの「クエリエディタ」を選択します
  • 初回アクセスの場合、「最初のクエリを実行する前に、Amazon S3 でクエリ結果の場所を設定する必要があります」というメッセージが表示されます。「設定を編集」をクリックします
  • 「クエリ設定」タブが開きます。「クエリ結果の暗号化」カードの「管理」をクリックします
  • 「クエリ結果の場所と暗号化を管理する」ダイアログで、「Location of query result」にS3バケットのパスを入力します(例: s3://aws-athena-query-results-123456789012-ap-southeast-2/)
  • 「保存」をクリックします
Athenaのクエリ結果の場所を設定するダイアログ(S3パスを入力した状態)
Athenaのクエリ結果の場所を設定するダイアログ(S3パスを入力した状態)

結果の保存先バケットは、あらかじめクエリを実行するリージョンに作成しておきます。

ステップ4: 特定ユーザーのすべてのアクティビティを抽出する

Athenaクエリエディタで以下のクエリを実行し、調査対象ユーザーのアクティビティを分析します。

4-1. ユーザーのすべての操作を時系列で取得する

対象ユーザーが過去30日間に実行したすべてのAPI操作を時系列で取得します。

SELECT
    eventtime,
    eventname,
    eventsource,
    awsregion,
    sourceipaddress,
    errorcode
FROM cloudtrail_logs_<バケット名>
WHERE useridentity.username = 'former-employee'
    AND eventtime >= '2026-02-20T00:00:00Z'
    AND eventtime <= '2026-03-22T23:59:59Z'
ORDER BY eventtime ASC;
Athenaクエリエディタでのクエリ実行結果(ユーザーの操作一覧が時系列で表示された状態)
Athenaクエリエディタでのクエリ実行結果(ユーザーの操作一覧が時系列で表示された状態)

左側の「データ」パネルは、パネル右上の折りたたみボタンで閉じられます。結果の列が多いときは閉じたほうが見やすくなります。

このクエリにより、対象ユーザーが実行したすべてのAPI操作が時系列で表示されます。退職日以降の操作が含まれていないかを重点的に確認します。

4-2. リソースを作成・変更した操作を抽出する

リソースの作成や変更に関連する操作を重点的に確認します。

SELECT
    eventtime,
    eventname,
    eventsource,
    awsregion,
    requestparameters,
    responseelements
FROM cloudtrail_logs_<バケット名>
WHERE useridentity.username = 'former-employee'
    AND (
        eventname LIKE 'Create%'
        OR eventname LIKE 'Run%'
        OR eventname LIKE 'Put%'
        OR eventname LIKE 'Modify%'
        OR eventname LIKE 'Update%'
        OR eventname LIKE 'Attach%'
    )
    AND eventtime >= '2026-02-20T00:00:00Z'
    AND eventtime <= '2026-03-22T23:59:59Z'
ORDER BY eventtime ASC;

Create%、Run%(EC2インスタンスの起動)、Put%(設定の適用)、Modify%・Update%(設定変更)、Attach%(リソースの関連付け)を対象にすることで、リソースの作成や設定変更を網羅的に抽出できます。requestparameters と responseelements から、作成されたリソースの具体的な情報(インスタンスID、セキュリティグループIDなど)を確認します。

4-3. サービス別の操作件数を集計する

対象ユーザーがどのサービスをどの程度操作したかを集計します。

SELECT
    eventsource,
    COUNT(*) AS event_count
FROM cloudtrail_logs_<バケット名>
WHERE useridentity.username = 'former-employee'
    AND eventtime >= '2026-02-20T00:00:00Z'
    AND eventtime <= '2026-03-22T23:59:59Z'
GROUP BY eventsource
ORDER BY event_count DESC;
Athenaクエリ結果(サービス別の操作件数が降順で表示された状態)
Athenaクエリ結果(サービス別の操作件数が降順で表示された状態)

操作件数が多いサービスから優先的に詳細を調査します。例えば ec2.amazonaws.com の件数が多ければ、EC2インスタンスの作成やセキュリティグループの変更が行われている可能性があります。

4-4. アクセス元IPアドレスを確認する

対象ユーザーがどのIPアドレスからアクセスしていたかを確認します。

SELECT
    sourceipaddress,
    COUNT(*) AS access_count,
    MIN(eventtime) AS first_access,
    MAX(eventtime) AS last_access
FROM cloudtrail_logs_<バケット名>
WHERE useridentity.username = 'former-employee'
    AND eventtime >= '2026-02-20T00:00:00Z'
    AND eventtime <= '2026-03-22T23:59:59Z'
GROUP BY sourceipaddress
ORDER BY access_count DESC;

退職日以降のアクセスで、社内ネットワークのIPアドレスとは異なるIPアドレスからの操作が確認された場合、退職後に外部からアクセスされていた可能性があります。

ステップ5: イベントソースでパーティショニングしたテーブルで効率的にクエリする

大量のCloudTrailログを分析する場合、イベントソースでパーティショニングしたテーブルを作成することで、クエリのスキャン対象を限定し、実行速度とコストを改善できます。

以下のDDLで、イベントソースをパーティションキーとしたテーブルを作成します。

CREATE EXTERNAL TABLE cloudtrail_logs_partitioned (
    eventversion STRING,
    useridentity STRUCT<
        type: STRING,
        principalid: STRING,
        arn: STRING,
        accountid: STRING,
        invokedby: STRING,
        accesskeyid: STRING,
        username: STRING,
        sessioncontext: STRUCT<
            attributes: STRUCT<
                mfaauthenticated: STRING,
                creationdate: STRING>,
            sessionissuer: STRUCT<
                type: STRING,
                principalid: STRING,
                arn: STRING,
                accountid: STRING,
                username: STRING>,
            ec2roledelivery: STRING,
            webidfederationdata: STRUCT<
                federatedprovider: STRING,
                attributes: MAP<STRING, STRING>>>>,
    eventtime STRING,
    eventname STRING,
    awsregion STRING,
    sourceipaddress STRING,
    useragent STRING,
    errorcode STRING,
    errormessage STRING,
    requestparameters STRING,
    responseelements STRING,
    additionaleventdata STRING,
    requestid STRING,
    eventid STRING,
    readonly STRING,
    resources ARRAY<STRUCT<
        arn: STRING,
        accountid: STRING,
        type: STRING>>,
    eventtype STRING,
    apiversion STRING,
    recipientaccountid STRING,
    serviceeventdetails STRING,
    sharedeventid STRING,
    vpcendpointid STRING,
    tlsdetails STRUCT<
        tlsversion: STRING,
        ciphersuite: STRING,
        clientprovidedhostheader: STRING>
)
PARTITIONED BY (eventsource STRING)
ROW FORMAT SERDE 'org.apache.hive.hcatalog.data.JsonSerDe'
LOCATION 's3://<CloudTrailログのバケット名>/AWSLogs/<アカウントID>/CloudTrail/';

<CloudTrailログのバケット名> と <アカウントID> は実際の値に置き換えてください。

テーブル作成後、パーティションを読み込みます。

MSCK REPAIR TABLE cloudtrail_logs_partitioned;

パーティショニングされたテーブルを使うと、特定のサービスに限定したクエリを効率的に実行できます。

SELECT
    eventtime,
    eventname,
    awsregion,
    requestparameters
FROM cloudtrail_logs_partitioned
WHERE eventsource = 'ec2.amazonaws.com'
    AND useridentity.username = 'former-employee'
    AND (
        eventname LIKE 'Create%'
        OR eventname LIKE 'Run%'
        OR eventname LIKE 'Modify%'
    )
ORDER BY eventtime ASC;

このクエリは ec2.amazonaws.com のパーティションのみをスキャンするため、全データスキャンに比べて大幅に高速に実行できます。

ステップ6: 調査結果を整理する

Athenaのクエリ結果から以下の項目を整理し、対応を進めます。

確認項目対応内容
退職日以降に作成されたリソースリソースを特定し、不要であれば削除する
セキュリティグループやIAMポリシーの変更変更内容を確認し、不正な変更を元に戻す
退職日以降のアクセス元IPアドレス社外からのアクセスがないかを確認し、記録する
操作件数が多いサービス影響範囲を優先的に調査する
対象ユーザーのIAMアカウント速やかに無効化・削除する

まとめ

退職者のAWSアクティビティを監査する際は、CloudTrailイベント履歴での簡易調査と、Amazon AthenaによるCloudTrailログのSQL分析を組み合わせて実施します。

  • CloudTrailイベント履歴 は過去90日間の管理イベントをユーザー名でフィルタリングでき、簡易的な調査に適しています
  • Amazon Athena を使うと、S3に保存されたCloudTrailログに対してSQLクエリを実行し、リソースの作成・変更操作やアクセス元IPアドレスを包括的に分析できます
  • イベントソースによるパーティショニング を活用すると、特定サービスに絞ったクエリを効率的に実行でき、スキャン対象のデータ量を削減できます
  • Cost Explorer はコストの可視化、Config Aggregator はリソース構成の管理、Cost Anomaly Detection はコスト異常の検知に適しており、いずれもユーザー単位の操作監査には向いていません
  • 退職者のアカウント管理が不十分な場合に備え、CloudTrailの証跡を有効にしてS3にログを保存しておくことが重要です

参照先

フリーランス案件
クラウドおさる
クラウドキャリアフリーランス

AWS の実務経験があるなら、単価を上げにいく

AWS に特化したフリーランスエージェントです。以下は取り扱い案件の一例です。設計・SRE・セキュリティ・生成 AI の領域で、専門を掛け合わせるほど単価が上がります。

横にスクロールできます。掲載時点の情報のため、募集が終了している場合があります。条件の近い案件をご紹介しますので、お気軽にご相談ください。

この記事が気に入ったら
フォローしてね!

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

株式会社ジェニュイン(https://genuine-pt.jp)の代表取締役.

2018年〜インフラエンジニアとしてキャリアをスタートし、オンプレミスのネットワーク・サーバ環境で3年半、クラウド環境で4年半の8年間エンジニアとして従事。
2021年に佐藤氏の創業した株式会社Luxyを引き継ぎ、代表に就任。
その後アガルートグループ内の株式会社ジェニュインと合併。
合併後同社代表に就任。

目次