Amazon Cognitoのログは、CloudTrailの管理イベント、ユーザープールから配信するユーザーアクティビティログと通知エラーログ、Post Authenticationトリガーで自前に残す記録の3系統に分かれる構成です。この記事では、それぞれで何が記録されて何が残らないかを整理し、CloudTrailでサインイン失敗を集計するクエリ、SetLogDeliveryConfigurationによる配信設定、AdminListUserAuthEventsで特定ユーザーの履歴を引く手順を、2026年10月時点の公式ドキュメントに沿って示します。ログイン画面の見た目を変えたい場合は、AWS Cognito Hosted UI(マネージドログイン)のカスタマイズ・日本語化と実装手順が該当します。最後に、監査要件ごとにどの系統を組み合わせるかの判断条件をまとめました。
まとめ:Cognitoのログは監査の目的で3系統を組み合わせる
結論から書くと、管理者の設定変更と大まかなサインイン失敗の傾向はCloudTrailで足ります。ただしCloudTrailには利用者のユーザー名が残らず、記録されるのはsubだけです。誰がいつどこからサインインしたかを利用者単位で追うには、Plusプランで脅威保護を監査専用モード以上にし、ユーザーアクティビティログを配信する必要があります。
Plusの費用を避けたい場合は、Post Authenticationトリガーで成功したサインインを自前で記録する方法が現実的です。この方法では失敗したサインインが残らないため、失敗の監視はCloudTrail側で補います。メールやSMSが届かない調査には、Plus不要の通知エラーログを有効にしておくと原因を追えます。
Cognitoで取れるログ3系統の記録項目と保持期間の違いを確認する
ユーザープールとアプリクライアントの構築がまだの場合は、Cognitoで認証基盤を実装する手順:ユーザープール構築からJWT検証までで土台を作ってから進めてください。ログの設定はどれも既存のプールに後から追加できます。
CloudTrail・ログ配信・Lambdaトリガーで取れる範囲の比較
| 系統 | 必要なプラン | 利用者の特定 | 失敗の記録 |
|---|---|---|---|
| CloudTrail | 全プラン | subのみ | 残る |
| ユーザーアクティビティログ | Plus+脅威保護 | ユーザー名とsub | 残る |
| 通知エラーログ | 全プラン | 対象外 | 送信失敗のみ |
| Post Authentication | 全プラン | 属性を自由に記録 | 残らない |
保持期間も系統ごとに異なる仕様です。CloudTrailのイベント履歴は過去90日まで、ユーザーアクティビティの履歴はCognito側に2年間保存されます。配信先のCloudWatch LogsやS3に送ったログは、配信先で決めた期間だけ残ります。
CloudTrailにユーザー名が残らずsubだけが記録される仕様と伏せ字
CognitoとCloudTrailの連携に関する公式ガイドには、利用者に関するリクエストではUserSubを記録し、UserNameは記録しないと書かれています。パスワードやトークンなど利用者の情報を含みやすい項目は、HIDDEN_DUE_TO_SECURITY_REASONSという値に置き換えられます。
CloudTrailイベントの例を見ると、マネージドログインのサインアップではusernameもpasswordも伏せ字です。監査の場面で「このメールアドレスの利用者のサインイン」をCloudTrailだけで検索することはできず、後述のListUsersでsubと突き合わせる手間がかかります。
CloudTrailでCognitoの管理操作とサインイン失敗を検索して集計する
CognitoのユーザープールAPIはすべて管理イベントとしてCloudTrailに記録される仕様です。API呼び出しはeventTypeがAwsApiCall、マネージドログインやOAuthのエンドポイントへのリクエストはAwsServiceEventになり、login_POSTやToken_POSTのようなイベント名で残ります。証跡の設計や料金そのものはCloudTrailとは?証跡設計と料金実額・Lake新規受付終了後の構成をCLIで解説で扱っています。
イベント履歴の90日分をlookup-eventsで絞り込んで確認する
証跡を作っていなくても、CloudTrailのイベント履歴で過去90日の管理イベントを無料で見られます。リージョン単位で検索するため、ユーザープールがあるリージョンを指定してください。
# 東京リージョンのCognitoユーザープールのイベントを新しい順に50件取得する
aws cloudtrail lookup-events \
--region ap-northeast-1 \
--lookup-attributes AttributeKey=EventSource,AttributeValue=cognito-idp.amazonaws.com \
--start-time 2026-10-01T00:00:00Z \
--max-results 50 \
--query 'Events[].{time:EventTime,name:EventName}' \
--output table
イベント履歴の検索で指定できる属性は1つだけです。「Cognitoのイベントのうちエラーになったもの」のような複合条件で絞るなら、次の手順で証跡をCloudWatch Logsへ送る構成にします。
証跡のCloudWatch Logs配信とLogs Insightsでの認証失敗集計
証跡の配信先にCloudWatch Logsを指定すると、公式ガイドに載っているクエリでCognitoのイベントを分析できます。次のクエリは、NotAuthorizedExceptionになったリクエストを送信元IPアドレスとイベント名で集計し、多い順に並べます。
filter eventSource = "cognito-idp.amazonaws.com" and errorCode = "NotAuthorizedException"
| stats count(*) as failures by sourceIPAddress, eventName
| sort failures desc
| limit 25
特定のIPアドレスからInitiateAuthの失敗が集中していれば、パスワードの総当たりやリスト型攻撃を疑う判断材料です。同じ考え方でeventName = 'ForgotPassword'に変えると、リセット要求の多いIPアドレスも洗い出せます。クエリ言語の書き方やスキャン量による課金はCloudWatch Logs Insightsの料金と使い方|スキャン課金・limit上限・3つのクエリ言語にまとめています。
サインイン失敗のsubからListUsersで該当するユーザーを特定する
失敗したリクエストのsubはadditionalEventData.subに入ります。まずLogs Insightsでsubを取り出します。
fields @timestamp, eventName, additionalEventData.sub as sub, sourceIPAddress
| filter eventSource = "cognito-idp.amazonaws.com" and errorCode = "NotAuthorizedException"
| sort @timestamp desc
| limit 25
取り出したsubを、list-usersのCLIリファレンスにある--filterで検索すると、ユーザー名やメールアドレスが分かります。
aws cognito-idp list-users \
--user-pool-id ap-northeast-1_EXAMPLE \
--filter 'sub = "a1b2c3d4-5678-90ab-cdef-EXAMPLE22222"' \
--query 'Users[].{name:Username,attrs:Attributes}'
存在しないユーザー名でのサインイン失敗にはsubが無いため、この方法では特定できません。調査の件数が多い場合は、ListUsersのリクエスト数がクォータに触れないよう、subの重複を除いてから照会してください。
ユーザーアクティビティログのSetLogDeliveryConfiguration配信設定
ユーザープールのログのエクスポートに関する公式ガイドによると、ユーザープールから外部へ配信できるログは2種類です。メールとSMSの送信エラーを記録するuserNotificationと、サインインなどの認証操作を記録するuserAuthEventsで、1つのプールで両方を同時に設定できます。
| 項目 | userNotification | userAuthEvents |
|---|---|---|
| ログレベル | ERROR | INFO |
| 配信先 | CloudWatch Logs | Logs・S3・Firehoseの1つ |
| Plusプラン | 不要 | 必要 |
| 設定方法 | APIかSDKのみ | APIかコンソール |
配信はベストエフォートで、配信量や配信先のクォータによっては欠ける可能性があると明記されています。監査証跡として法的な完全性が求められる用途では、この点を前提に設計してください。IDプールにはログのエクスポート機能がありません。
Plusプランと脅威保護の監査専用モードをCLIで有効にする
ユーザーアクティビティログは、脅威保護が監査専用かフル機能のモードで動いているときだけ生成されます。update-user-poolのCLIリファレンスでは、機能プランを--user-pool-tier、脅威保護のモードを--user-pool-add-onsで指定します。
# 現在の設定を退避する(update-user-poolは指定しなかった項目を既定値に戻す)
aws cognito-idp describe-user-pool \
--user-pool-id ap-northeast-1_EXAMPLE > userpool-backup.json
# 退避した既存設定もすべて渡したうえで、Plusプランと監査専用モードを指定する
aws cognito-idp update-user-pool \
--user-pool-id ap-northeast-1_EXAMPLE \
--user-pool-tier PLUS \
--user-pool-add-ons AdvancedSecurityMode=AUDIT
上の2行目だけを本番で実行すると、メッセージテンプレートやLambdaトリガーなど既存の設定が既定値に戻るおそれがあります。IaCで管理しているプールなら、CloudFormationやTerraformの定義側で変更する方が安全です。AUDITはリスクを評価してログに残すだけで、サインインを止めません。脅威保護の公式ガイドは、自動応答を有効にする前に監査専用で2週間以上運用することを推奨しています。
配信先のロググループを作りlog-configurationsで2種類を設定する
CloudWatch Logsに両方を送る例です。set-log-delivery-configurationのCLIリファレンスのとおり、--log-configurationsは最大2件まで指定できます。
# 配信先のロググループを作り、保持期間を決める
aws logs create-log-group --log-group-name /aws/vendedlogs/cognito/notification
aws logs create-log-group --log-group-name /aws/vendedlogs/cognito/activity
aws logs put-retention-policy \
--log-group-name /aws/vendedlogs/cognito/activity --retention-in-days 365
# 通知エラー(ERROR)と認証イベント(INFO)の配信を設定する
aws cognito-idp set-log-delivery-configuration \
--user-pool-id ap-northeast-1_EXAMPLE \
--log-configurations \
'LogLevel=ERROR,EventSource=userNotification,CloudWatchLogsConfiguration={LogGroupArn=arn:aws:logs:ap-northeast-1:123456789012:log-group:/aws/vendedlogs/cognito/notification}' \
'LogLevel=INFO,EventSource=userAuthEvents,CloudWatchLogsConfiguration={LogGroupArn=arn:aws:logs:ap-northeast-1:123456789012:log-group:/aws/vendedlogs/cognito/activity}'
# 設定内容を確認する
aws cognito-idp get-log-delivery-configuration --user-pool-id ap-northeast-1_EXAMPLE
配信先のロググループで満たすべき条件は3つです。KMSで暗号化したロググループは指定できず、ユーザープールと同じアカウントに置く必要があります。また、リソースポリシーが5120文字を超える場合は、名前が/aws/vendedlogsで始まるロググループを使う必要があります。上の例は最初からこの接頭辞で作ったものです。配信にはサービスにリンクされたロールが自動で作られ、設定する側のIAMにはlogs:CreateLogDeliveryやlogs:PutResourcePolicyなどの権限が必要です。長期保管や他システムへの転送が目的なら、S3かData Firehoseを配信先にします。Firehoseの構成はAmazon Data Firehoseとは?旧Kinesis Data Firehoseとの違い・配信先・料金と実装判断を解説で解説しています。
配信された認証イベントからサインイン失敗とリスク判定を抽出する
配信されるイベントは、messageの中にeventType(SignInやSignUpなど)、eventResponse、userName、userSub、ipAddress、riskDecision、countryなどを持つJSONです。公式ガイドは、このスキーマは変更されうるもので、値がnullの項目もあると注記しています。サインインに失敗した利用者とIPアドレスの組み合わせは、次のクエリで集計できます。
fields @timestamp, message.userName, message.ipAddress, message.riskDecision
| filter message.eventType = "SignIn" and message.eventResponse = "Fail"
| stats count(*) as fails by message.userName, message.ipAddress
| sort fails desc
| limit 50
注意点として、配信されるのはINFOレベルのイベントだけで、スロットリングのようなWARNINGやERRORのメッセージは含まれません。メールアドレスなどの属性も入らないため、必要ならuserSubをキーに後から属性を引きます。
AdminListUserAuthEventsで特定ユーザーのサインイン履歴を調べる
「この利用者のアカウントが乗っ取られていないか」を問い合わせ単位で調べるなら、配信設定を待たずにCognito側に保存された履歴を直接引けます。適応型認証の公式ガイドによると、脅威保護を有効にしたプールではイベントの履歴が2年間保持され、コンソールのユーザーの詳細画面でも確認できます。
admin-list-user-auth-eventsで直近の認証履歴をCLI取得
aws cognito-idp admin-list-user-auth-events \
--user-pool-id ap-northeast-1_EXAMPLE \
--username taro \
--max-results 10 \
--query 'AuthEvents[].{at:CreationDate,type:EventType,result:EventResponse,risk:EventRisk.RiskDecision,ip:EventContextData.IpAddress}'
オプション名はadmin-list-user-auth-eventsのCLIリファレンスで確認できます。脅威保護を有効にしていないプールでは、UserPoolAddOnNotEnabledExceptionが返ります。
boto3でNextTokenを辿り全件をCSVへ書き出す監査用スクリプト
AdminListUserAuthEventsのAPIリファレンスでは、1回で返る件数は最大60件です。監査資料として全件が必要なときは、NextTokenを辿ります。このAPIはIAMで認可するため、実行するのは運用担当の端末か管理用のバックエンドに限ります。
import csv
import boto3
client = boto3.client("cognito-idp", region_name="ap-northeast-1")
def export_auth_events(user_pool_id: str, username: str, path: str) -> int:
"""1人分の認証イベントを全件CSVに書き出し、件数を返す"""
rows, token = [], None
while True:
params = {"UserPoolId": user_pool_id, "Username": username, "MaxResults": 60}
if token:
params["NextToken"] = token
res = client.admin_list_user_auth_events(**params)
for e in res["AuthEvents"]:
ctx = e.get("EventContextData", {})
rows.append([
e["CreationDate"].isoformat(), e["EventType"], e["EventResponse"],
e.get("EventRisk", {}).get("RiskDecision", ""),
ctx.get("IpAddress", ""), ctx.get("Country", ""), e["EventId"],
])
token = res.get("NextToken")
if not token:
break
with open(path, "w", newline="", encoding="utf-8") as f:
w = csv.writer(f)
w.writerow(["at", "type", "result", "risk", "ip", "country", "event_id"])
w.writerows(rows)
return len(rows)
print(export_auth_events("ap-northeast-1_EXAMPLE", "taro", "taro_auth_events.csv"))
出力したevent_idは、そのサインインで発行されたIDトークンとアクセストークンのペイロードにも入ります。アプリのアクセスログにトークンのイベントIDを残しておけば、不審な操作がどのサインインに由来するかを辿れます。
Plusプラン無しで履歴を残すPost Authenticationトリガーの実装
LiteやEssentialsのプールでも、成功したサインインはPost AuthenticationのLambdaトリガーで記録できます。Cognitoは認証の完了後、トークンを渡す前にこのLambdaを呼び出します。
サインイン成功をJSON構造化ログでCloudWatch Logsへ出力する
// Node.js 22 ランタイム想定。Post Authentication トリガーに設定する
export const handler = async (event) => {
const attrs = event.request.userAttributes ?? {};
console.log(JSON.stringify({
type: "cognito_sign_in",
userPoolId: event.userPoolId,
clientId: event.callerContext.clientId,
userName: event.userName,
sub: attrs.sub,
newDeviceUsed: event.request.newDeviceUsed ?? null,
triggerSource: event.triggerSource,
}));
// イベントをそのまま返さないと認証が完了しないことがある
return event;
};
JSONで出力しておけば、Logs InsightsでuserNameやclientIdごとの集計がそのまま書けます。newDeviceUsedは、ユーザープールの端末記憶の設定がAlwaysかUser Opt-Inのときだけ値が入ります。
トリガー方式で記録できない認証失敗とサインインを止めないための注意点
このトリガーは認証が成功した後にしか呼ばれないため、パスワードの誤りやロックアウトは記録されません。失敗の監視は前述のCloudTrailのクエリで補います。サインイン失敗が続いたときのロックアウトの仕様はCognitoのパスワードリセット実装:ForgotPasswordと管理者リセット・ロックアウト設計で解説しています。
もう1つの注意点は、Lambdaが例外を投げたりイベントを返さなかったりすると、利用者のサインインまで失敗することです。外部のデータベースに書き込む処理を入れる場合は、例外を握りつぶしてログ出力だけ残すか、SQSなどに投げて非同期で処理し、記録の失敗で認証を止めない作りにします。
Cognitoのログ設計を判断する条件と見送るべき場面を整理する
ここまでの仕様を踏まえ、要件ごとにどの系統を組み合わせるかを言い切ります。Cognitoの機能プランと料金の全体像はAmazon Cognito(コグニート)とは?料金・できること・使い方をCLIとコード例で解説で確認できます。
監査要件が利用者単位ならPlus、傾向把握ならCloudTrailで足りる
ISMSや取引先のセキュリティ監査で「利用者ごとのサインイン履歴を一定期間提出できること」が求められる業務システムなら、Plusにして脅威保護を監査専用で動かし、ユーザーアクティビティログをS3へ配信する構成を選びます。履歴が2年分Cognito側にも残り、リスク判定まで付くため、問い合わせ対応と監査資料の両方に使える構成です。Cognitoの料金ページにあるとおりPlusには直接サインインの無料枠が無く、MAU課金がEssentialsより上がる点は予算に入れておきます。
一方、必要なのが「総当たりの兆候を掴む」「設定変更の操作者を追う」程度なら、CloudTrailの証跡とLogs Insightsのクエリで足ります。利用者を特定する場面は月に数回というなら、subからListUsersで引く運用で困りません。成功したサインインの時刻だけ残したい会員サービスは、Post Authenticationトリガーで十分です。どの構成でも、メール未着の問い合わせに備えて通知エラーログは有効にしておくことを勧めます。
フェデレーション利用者が中心の構成とPlusを見送るべきケース
脅威保護はフェデレーションでのサインインには使えないと公式ガイドに明記されています。Entra IDなどのSAML連携で社員がサインインする構成では、ユーザーアクティビティログのリスク判定は効かず、Plusの費用に見合いません。この場合はCloudTrailのSAML2Response_POSTと、IdP側のサインインログで監査する方が筋が通ります。連携の構成はCognito SAML連携の手順:Entra IDでSSOを組む設定と属性マッピングで解説しています。SAMLでサインインした社員にS3などへの一時認証情報を渡すIDプールの実装はCognito IDプールの実装手順:一時認証情報の発行とロール選択・ユーザープールとの違いで扱っています。
大量のリクエストによる攻撃を止めたい場合も、脅威保護はリクエスト量を見ないため役割が異なる機能です。レート制限はAPI GatewayにAWS WAFを関連付ける手順:Web ACLのルール設計・WCU計算とCognito保護にあるWAFの関連付けで対処します。ログの取得から不正検知、既存IdPとの統合まで含めて認証基盤を設計し直したい場合は、認証基盤・ID管理システム開発でご相談いただけます。
よくある質問
Cognitoのログ設定と監査の進め方で、実装前によく確認される点をまとめました。
CloudTrailでCognitoのサインインを見ても誰か分からないのはなぜですか?
Cognitoは利用者に関するリクエストでsubだけを記録し、ユーザー名は記録しない仕様です。マネージドログインのイベントでもusernameは伏せ字になります。additionalEventData.subの値をListUsersの--filterで検索すると、ユーザー名やメールアドレスが分かります。
IDプールの操作はCloudTrailに記録されますか?
GetIdやGetCredentialsForIdentityなど5つの操作はデータイベントとして扱われ、既定では記録されません。証跡でデータイベントを有効にし、Cognito IDプールのイベントセレクターを追加すると記録され、その分の追加料金がかかります。それ以外のIDプールのAPIは管理イベントとして既定で記録されます。
ユーザーアクティビティログを複数の配信先に送れますか?
送れません。ユーザーアクティビティログの配信先はCloudWatch Logs・S3・Data Firehoseのどれか1つです。CloudWatch LogsとS3の両方に残したい場合は、Firehoseを配信先にし、Firehoseの先で振り分ける構成にします。通知エラーログはCloudWatch Logsにしか送れません。
ログ配信の設定にかかる費用はどのくらいですか?
公式ガイドが費用として挙げているのは、配信先のCloudWatch Logs・S3・Firehoseでのデータの取り込みと取得の料金です。CloudWatch Logsへの配信はCloudWatchの料金ページのVended Logsの区分で計算します。ユーザーアクティビティログにはPlusプランのMAU料金も前提として必要です。
不正アクセスを疑ったとき最初にどのログを確認すべきですか?
まずCloudTrailのイベント履歴で、ユーザープールの設定変更や管理者APIの実行が無いかを確認します。次に、該当する利用者の認証イベントをAdminListUserAuthEventsかコンソールで見て、見覚えのない国やIPアドレスからの成功が無いかを調べる流れです。アプリ側のログも含めた調査の手順は不正アクセスの調べ方|ログの確認方法と痕跡を見つけるコマンド例にまとめています。
関連記事
- Cognitoで認証基盤を実装する手順:ユーザープール構築からJWT検証まで:ログ設定の前提になるユーザープールとトークン検証の全体像。
- CloudTrailとは?証跡設計と料金実額・Lake新規受付終了後の構成をCLIで解説:Cognitoのイベントを長期保存する証跡の設計。
- Cognitoのパスワードリセット実装:ForgotPasswordと管理者リセット・ロックアウト設計:サインイン失敗が続いたときのロックアウト仕様。
- Cognito MFAの設定手順:TOTP・SMS・メールの有効化と必須化の判断:脅威保護のリスク判定と組み合わせるMFAの設定。
- API認証の設計|方式選定マトリクスとトークン寿命・監査ログの決め方:認証まわりで残す監査ログの決め方。