Dev Study
AWSサービスの内部原理 コース

128. Cognitoは3枚の切符を配る — IDトークン・アクセストークン・リフレッシュトークンの役割分担

サインインに成功したユーザーへCognitoが手渡す3枚のトークンを、「それぞれ何のための切符なのか」で腑分けし、短命な2枚と長命な1枚という非対称な設計を図で追っていきます。

① サインイン成功で、3枚まとめて配られる

ユーザーサインイン情報を提示
一度の認証で3枚を返す
Cognito ユーザープールログイン情報を検証し成功でセッション作成
IDトークンJWT・平文JSON化可
「誰か」を伝える
アクセストークンJWT・平文JSON化可
「何をしてよいか」を伝える
リフレッシュトークン暗号化・不透明
再発行の引換券
  • 公式の言い回し: 「Amazon Cognito creates a session and returns an ID token, an access token, and a refresh token for the authenticated user」。
  • ID・アクセストークンは base64url エンコードで、平文JSONにデコードできる。一方リフレッシュトークンは「encrypted, opaque to user pools users and administrators, and can only be read by your user pool」——中身を読めるのはユーザープール自身だけ。

認証が1回通ると、性質の異なる3枚の切符が同時に発行される。最初に押さえるべきは「3枚は用途が違う」という点で、同じものを3枚もらうわけではない。

② IDトークン=「誰か」を主張する切符

IDトークンのペイロード平文JSONにデコード可
まとめると
name / email本人属性
cognito:usernameプール内の名前
cognito:groups所属グループ
用途
身元の主張claims about the identity
本人情報の利用/本人確認信頼前に署名検証が必須
  • 公式定義: ID token は「a JSON Web Token (JWT) that contains claims about the identity of the authenticated user, such as `name`, `email`, and `phone_number`」。
  • `token_use` クレームの値は `id`。
  • ID・アクセス両方に `cognito:groups`(所属グループ)が入る。
  • 署名検証は必須:「you must verify the signature of the ID token before you can trust any claims」。

IDトークンは「このセッションの主は誰なのか」を運ぶ切符。中身は本人の属性クレームで、アプリが名前やメールを表示したり本人確認に使ったりするためのもの。

③ アクセストークン=「何をしてよいか」を許可する切符

アクセストークンのペイロード
役目
scopeOAuth 2.0 スコープ群
cognito:groups所属グループ
APIオペレーションの認可authorize API operations
独自スコープAPI Gateway等の外部API呼び出し
aws.cognito.signin.user.admin属性の読み書き/MFA設定/デバイス管理
  • 公式定義:「The purpose of the access token is to authorize API operations.」
  • `token_use` クレームの値は `access`。
  • API Gateway はアクセストークンでの認可をサポート——「Amazon API Gateway supports authorization with Amazon Cognito access tokens」。
  • `aws.cognito.signin.user.admin` スコープは「permission to read and write user attributes, list authentication factors, configure multi-factor authentication (MFA) preferences, and manage remembered devices」——Cognito のユーザー自身のプロフィール系API呼び出しを許可する。
  • IDトークンとアクセストークンは別の鍵で署名される。`kid` が一致しないため、アプリでは2枚を独立に検証する。

アクセストークンは「この持ち主に何をさせてよいか」を運ぶ切符。中身はスコープ(権限リスト)で、外部APIの呼び出しやCognito自身のセルフサービス操作の可否を決める。誰かを名乗る切符(ID)とは役割がきっぱり分かれている。

④ 短命な2枚 vs 長命な1枚 — 寿命の非対称

寿命の短い側毎回の証明用
短命が原則→漏れても被害は短時間
IDトークン既定1時間 / 5分〜1日
アクセストークン既定1時間 / 5分〜1日
寿命の長い側再発行の引換券
リフレッシュトークン既定30日 / 60分〜10年
ID/アクセスより桁違いに長い
  • ID token:「You can set the ID token expiration to any value between 5 minutes and 1 day.」既定は1時間。
  • Access token:「You can set the access token expiration to any value between 5 minutes and 1 day.」既定は1時間。
  • Refresh token:「By default, the refresh token expires 30 days after your application user signs into your user pool」/「you can set the application's refresh token expiration to any value between 60 minutes and 10 years」。
  • 有効期限はいずれもアプリクライアント単位で設定する。

3枚の非対称な寿命こそがこの設計の核心。証明に毎回使う2枚を短命にして漏洩時の被害窓を狭め、そのぶん長命な1枚だけを厳重に守ればよい、という役割分担になっている。これはメッセージング編の可視性タイムアウトやSTSの一時認証情報と同じく「寿命の設計そのものが安全装置になる」という原理の再登場でもある。

⑤ リフレッシュトークン=再証明を省く鍵

長命なリフレッシュトークン
ローテーション無効(既定)InitiateAuth等
新しいID/アクセストークンを再発行、リフレッシュトークンは流用
AuthFlow=REFRESH_TOKEN_AUTH
またはGetTokensFromRefreshToken
新しいID/アクセストークンセッション継続
  • 用途:「You can use the refresh token to retrieve new ID and access tokens.」
  • ローテーション無効時のフロー: `InitiateAuth`/`AdminInitiateAuth` で `AuthFlow` に `REFRESH_TOKEN_AUTH` を渡し、`AuthParameters` の `REFRESH_TOKEN` に手持ちのリフレッシュトークンを入れる。「Amazon Cognito returns new ID and access tokens」。
  • `GetTokensFromRefreshToken` はローテーションの有効・無効を問わず使える汎用API。ローテーション無効時はこのAPIと`REFRESH_TOKEN_AUTH`のどちらでも再発行できるが、ローテーション有効時は`GetTokensFromRefreshToken`が唯一の選択肢になる(⑥参照)。
  • リフレッシュトークンを revoke すると、そのトークンから再発行した全ID/アクセストークンも失効する(公式表現は「will revoke all ID and access tokens that Amazon Cognito issued from refresh requests with that token」)。

リフレッシュトークンの用途はただ一つ——ID/アクセストークンが切れたときに再ログインなしで新しい2枚をもらうこと。ユーザー体験としての「ログインしっぱなし」は、この長命な引換券が裏で短命な2枚を刷り直し続けることで成り立っている。

⑥ ローテーション — 引換券自体を刷り直す

リフレッシュトークン v1
元のv1は無効化(グレース期間中のみ猶予)
ローテーション有効(推奨)新ID/アクセス+新リフレッシュv2を返却
以後v2を次回に使用
グレース期間最大60秒/RetryGracePeriodSeconds
リトライを許容
リフレッシュトークン v2以後v3, v4…と継続
  • 挙動:「your client can invalidate the original refresh token and issue a new refresh token with each token refresh」——使うたびに旧トークン無効化+新トークン発行。
  • グレース期間:「you can also configure a grace period for the original refresh token of up to 60 seconds」——コンソールでは「a number of seconds, up to 60」、API(`CreateUserPoolClient`/`UpdateUserPoolClient`)では `RefreshTokenRotation.RetryGracePeriodSeconds` パラメータで指定する。
  • ローテーション有効時は `REFRESH_TOKEN_AUTH` フローは使えない:「Refresh token rotation isn't compatible with the authentication flow `REFRESH_TOKEN_AUTH`」。`GetTokensFromRefreshToken` に切り替える必要がある(※⑤のREFRESH_TOKEN_AUTHはローテーション無効時の既定挙動)。
  • 公式は有効化を推奨:「As a security best practice, enable refresh token rotation on your app clients.」

ローテーションを有効にすると、長命な1枚さえも使うたびに新品へ差し替わり、盗まれた古い引換券は(短いグレース期間を除いて)すぐ使えなくなる。④で見た「短い寿命を反復して安全性を作る」原理を、いちばん長命なトークンにまで適用した仕上げがローテーションである。

まとめ:3枚の使い分けの原則

IDトークン
「誰か」を伝える
アクセストークン
「何をしてよいか」を伝える
リフレッシュトークン
「また証明し直さなくていい」鍵
寿命の非対称設計
本人確認 / 権限付与の分離認証暗号編と同じ原理
寿命そのものが安全装置STSの一時認証情報・可視性タイムアウトと同型

IDトークン=「誰か」、アクセストークン=「何をしてよいか」、リフレッシュトークン=「また証明し直さなくていい」ための鍵。3枚の非対称な寿命設計は、STSの一時認証情報やメッセージング編の可視性タイムアウトと同じく、「寿命そのものを安全装置として設計する」という一貫した原理の表れである。

公式ドキュメントで詳しく ↗