API Gateway のアクセスログに Cognito ユーザプールのユーザ情報を出力する方法を教えてください

この記事はアノテーション株式会社 AWS Technical Support Advent Calendar 2021のカレンダー | Advent Calendar 2021 - Qiita 9日目の記事です。

困っていた内容

ユーザー情報を Cognito ユーザプールで管理しており、API Gateway のオーソライザに Cognito ユーザプールを設定しています。
API Gateway の認可の際に、Cognito オーソライザから返されたクレーム(ユーザ情報)をアクセスログへ出力したいのですが、以下の様に設定しても出力結果が "-" となってしまいます。
どのように設定したらよいでしょうか?

アクセスログ形式

{
    "requestId": "$context.requestId",
    "claims": "$context.authorizer.claims"
}

ログ出力結果

{
    "requestId": "1cxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx",
    "claims": "-"
}

どう対応すればいいの?

$context.authorizer.claims.property を利用して、ログ出力したいクレームの特定のプロパティを指定してください。

$context.authorizer.claims のみ指定しても NULL ("-")としてログへ出力されますので、クレームのプロパティを必ず指定してください。

API Gateway マッピングテンプレートとアクセスのログ記録の変数リファレンス - Amazon API Gateway

$context.authorizer.claims.property
メソッドの呼び出し側が認証に成功した後に Amazon Cognito ユーザープールから返されるクレームのプロパティ。詳細については、「Amazon Cognito ユーザープールをオーソライザーとして使用して REST API へのアクセスを制御する」を参照してください。

注記 $context.authorizer.claims を呼び出すと NULL が返されます。

やってみた

API Gateway のアクセスログの設定方法は以下のブログを参照ください。

【新機能】Amazon API Gateway でアクセスログを記録する #reinvent

アクセスログ形式

API Gateway の API のステージから、以下のログ形式でクレームの特定のプロパティを出力するようにアクセスログ記録の設定を行います。
クレームの sub, aud, email, cognito:username を出力するようにしてみました。

{
    "requestId": "$context.requestId",
    "sub": "$context.authorizer.claims.sub",
    "aud": "$context.authorizer.claims.aud",
    "email": "$context.authorizer.claims.email",
    "username": "$context.authorizer.claims['cognito:username']"
}

マネージメントコンソール上だと、以下のような設定です。

ログ出力結果

認可トークンをヘッダに付与して API Gateway へリクエストを送ると Cognito が認可します。
その際に、認可トークンに対応する Cognito ユーザのクレームが API Gateway へレスポンスされ、
前述で設定したアクセスログの形式でログとして出力されます。

出力された CloudWatch Logs のログイベントを確認します。

{
    "requestId": "1cxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx",
    "sub": "23xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "aud": "4exxxxxxxxxxxxxxxxxx",
    "email": "xxxxxxxxxxxx@example.com",
    "username": "nakano"
}

上記のように認証されたユーザのクレームの中身が出力されています。

参考資料