KeycloakとCognitoにおけるJWTトークン検証の違い
はじめに
JWT(JSON Web Token)を用いた認証・認可において、トークン検証はセキュリティの要となります。
本記事では、Keycloak と Amazon Cognito における
トークン検証の違いと、実務での考え方を整理します。
JWT検証の基本
JWTの仕様(RFC 7519)では、主に以下の検証を行います。
- 署名検証(改ざん防止)
- 有効期限(exp)
- 発行元(iss)
- Audience(aud)
この中でも「aud(Audience)」は重要な概念です。
Audience(aud)とは何か
aud は以下を意味します。
このトークンが「どのシステム向けに発行されたか」
これにより、以下を防ぎます:
- 別システムへのトークン使い回し
- 意図しないAPIアクセス
Keycloakのトークン検証
特徴
- access token に
audが含まれるケースが多い - audienceベースでの検証が前提になっている
検証の基本方針
-
audが期待する値かをチェック - 必要に応じて role / scope を確認
👉 「このAPI向けのトークンか?」を aud で厳密に判定
Cognitoのトークン検証
特徴
- access token に
audが含まれないことがある - 代わりに
client_idが使われる
検証の基本方針
-
iss(発行元) -
exp(有効期限) client_idscope
👉 audではなく client_id を軸に検証する設計
両者の違いまとめ
| 観点 | Keycloak | Cognito |
|---|---|---|
| audの有無 | あり(基本) | 無い場合あり |
| 検証の軸 | aud | client_id / scope |
| 設計思想 | リソース(API)中心 | クライアント中心 |
| 柔軟性 | 高い(audience制御) | シンプル |
なぜこの違いが生まれるのか
Keycloak
- マイクロサービスやAPI単位の制御を重視
- 「どのAPI向けか」を明確にする設計
Cognito
- クライアントアプリ中心の設計
- 「どのアプリから来たか」を重視
実務での注意点
① audが無い=不正ではない
Cognitoでは仕様上あり得るため、
単純に「audが無い=NG」とするのは誤りです。
② 代替検証が必要
audが無い場合は以下で担保します:
client_idscopeiss
👉 「誰向けのトークンか」を別の形で必ず確認する
③ Keycloakの実装をそのまま流用しない
よくあるミス:
- Keycloak前提で aud チェックを書いている
- Cognitoに切り替えたら動かない
👉 プロバイダごとに検証戦略を変える必要あり
実装方針の一例
if (provider === 'keycloak') {
// audチェック
}
if (provider === 'cognito') {
// client_idチェック
}
まとめ
- Audience検証は「トークンの宛先チェック」
- Keycloakは aud を中心に検証
- Cognitoは client_id を中心に検証
- 重要なのは「audがあるか」ではなく
👉 「誰向けのトークンかを検証できているか」
おわりに
JWT検証は「仕様通り」だけでなく、
プロバイダの設計思想を理解することが重要です。
KeycloakとCognitoの違いを正しく理解し、
安全な認証・認可設計を行いましょう。
必要なら👇も追加できます
- NestJSでの実装コード(ガチ実務レベル)
- セキュリティレビュー対策の観点
- 図解(めちゃくちゃ分かりやすくなる)