128. Cognitoは3枚の切符を配る — IDトークン・アクセストークン・リフレッシュトークンの役割分担
サインインに成功したユーザーへCognitoが手渡す3枚のトークンを、「それぞれ何のための切符なのか」で腑分けし、短命な2枚と長命な1枚という非対称な設計を図で追っていきます。
① サインイン成功で、3枚まとめて配られる
- 公式の言い回し: 「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 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トークンは「このセッションの主は誰なのか」を運ぶ切符。中身は本人の属性クレームで、アプリが名前やメールを表示したり本人確認に使ったりするためのもの。
③ アクセストークン=「何をしてよいか」を許可する切符
- 公式定義:「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 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の一時認証情報と同じく「寿命の設計そのものが安全装置になる」という原理の再登場でもある。
⑤ リフレッシュトークン=再証明を省く鍵
- 用途:「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枚を刷り直し続けることで成り立っている。
⑥ ローテーション — 引換券自体を刷り直す
- 挙動:「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トークン=「誰か」、アクセストークン=「何をしてよいか」、リフレッシュトークン=「また証明し直さなくていい」ための鍵。3枚の非対称な寿命設計は、STSの一時認証情報やメッセージング編の可視性タイムアウトと同じく、「寿命そのものを安全装置として設計する」という一貫した原理の表れである。