← AWSサービスの内部原理 コース
135. 誰かの認証からアプリの秘密まで — 1つのログインが動くための全部品の地図
1人のユーザーがログインボタンを押してからデータベースに辿り着くまで、その裏で何が起きているのかを1枚の地図として上流から下流へ図で追っていきます。
① サインイン — 誰かであることを証明し、3種類のトークンを受け取る
ユーザー
サインイン方式は2系統
Hosted UImanaged login
ユーザープールがトークン発行
SRP フローパスワードを直接送らずチャレンジ&レスポンスで証明
OAuth 2.0 認可コードIdPで認証→認可コード→トークンに交換
発行される3トークン(並列)
ユーザープール
トークン発行IDトークン「誰か」を表す・属性を含む・短命
アクセストークン「何ができるか」・スコープ/グループ含む・短命
リフレッシュトークン「再発行の権利」・長命
- ユーザープールは「アプリから見ると OIDC の IdP」(source 1)。
- サインインは大きく2系統。1つはSRP(Secure Remote Password)フロー——Cognitoの設定名では ALLOW_USER_SRP_AUTH(APIでは USER_SRP_AUTH)——で、パスワードそのものを送らずチャレンジ&レスポンスで証明する。もう1つはHosted UI(managed login)経由のOAuth 2.0ベースのサインインで、外部IdPや管理ページを介した認可コードのやり取りを伴う(source 1「Managed login」節)。
- IDトークンの claims にはユーザー属性・iss(発行者=ユーザープール)・aud(app client)が入る。アクセストークンの payload にはスコープ・グループ・iss・client_id が入る(source 3「Payload」節)。
- ID・アクセストークンは短命、リフレッシュトークンはそれらを取り直すための長命トークン、という役割分担。
サインインのゴールは「3枚の身分証」を手に入れること。IDトークンは"誰か"を、アクセストークンは"何をしてよいか"を、リフレッシュトークンは"それらを再発行する権利"を担う。1回のログインで役割の違う3枚が同時に出るのがユーザープールの出発点。
② 検証 — API Gatewayの前で、公開鍵がトークンの署名とclaimsを確かめる
アプリ
検証は上から順に
API Gatewayオーソライザー
次に署名検証
(1) kid を読むJWKS URI の公開鍵集合から一致する kid を探す
jwks.jsonはkidでキャッシュ・定期更新次にclaims照合
(2) 署名を検証RS256の公開鍵で照合・不一致は破棄
アクセス用とID用で別の鍵ペア全部通れば
exp期限切れでないか
iss自分のユーザープールか
aud/client_id自分のapp client宛てか
token_useaccess/idの用途どおりか
claimsを信頼
バックエンドへ- Cognitoの署名は alg = RS256(RSA + SHA-256)。kid は 2048-bit RSA 秘密署名鍵への短い参照(source 3「Header」節)。
- ユーザープールごとに RSA 鍵ペアを2組生成し、片方がアクセストークン、もう片方がIDトークンに署名する(source 3「Validate the JWT」節)。
- JWKS URI の形式:https://cognito-idp.{Region}.amazonaws.com/{userPoolId}/.well-known/jwks.json(source 3)。
- kid が違う正当な iss のトークンが来たら鍵ローテーションの可能性 → JWKSキャッシュを更新して再確認(source 3 Note)。
- claims照合:aud(IDトークン)/ client_id(アクセストークン)が app client 一致、iss がユーザープール一致、exp 未失効、token_use が用途どおり(source 3「Verify the claims」節)。
検証の核心は「秘密鍵で署名したものは、対応する公開鍵でしか検証が通らない」という非対称鍵の性質。kid で鍵を選び、署名で改ざんを弾き、claims で宛先と期限を確かめる。この一連が通って初めてトークンの中身を信じられる。
③ 両替 — AWSリソースに触りたいなら、トークンをSTSの一時認証情報に替える
ユーザープールのトークン
ユーザーの状態で2つの入口
IDプールfederated identities
ロールマッピング
認証済みauthenticated・サインイン済み
ゲストunauthenticated・本人確認前
STS呼び出し
ロールマッピング単一ロール、またはclaimsで出し分け
AssumeRoleWithWebIdentity
署名付きリクエストで
一時AWS認証情報期限付き・そのロールの権限だけ
S3 / DynamoDB など
- IDプールは「federated identities のディレクトリで、AWS認証情報と両替できる」。サインイン済みでも未識別(ゲスト)でも一時認証情報を発行する(source 2)。
- Cognitoは各IdPの claims を AssumeRoleWithWebIdentity リクエストにまとめて短期認証情報を得る(source 2)。
- ゲストには「狭いスコープの認証情報」を、サインインで権限を引き上げる。全認証ユーザーに単一ロール、または claims ごとにロールを選べる(source 2 features 節)。
- 住み分け:「ユーザープール=SSO対応アプリへのOIDC IdP」「IDプール=IAM認可が要るアプリへのAWSのIdP」(source 2)。
IDプールがやっているのは"両替所"の仕事。ユーザー用のトークンを、AWSが理解できる期限付きの一時認証情報に交換する。ゲストと認証済みで別ロール、claimsで出し分け——ここまでが「AWSリソースに何をしてよいか」を決める認可の層。
④ 秘密の取得 — バックエンドが動く瞬間、DBパスワードはコードの外から取り出される
Lambda / ECSタスクが起動
ローテーション用Lambdaが4ステップで版を入れ替え
Secrets ManagerParameter Store
コードには秘密を一切書かない次に
(1) createSecret新値をAWSPENDINGの新版として保存
次に
(2) setSecretDB側の資格情報をAWSPENDINGに合わせて変更
次に
(3) testSecretAWSPENDINGの値で接続試験
旧版には自動でAWSPREVIOUS
(4) finishSecretAWSCURRENTを旧版から新版へ移動・AWSPENDINGが外れる
旧版: AWSPREVIOUS直前の正常版として残る
新版: AWSCURRENTアプリが常に読む版
- Secrets Manager はローテーション中、staging label で版を識別する(source 4 冒頭)。
- 4ステップは createSecret / setSecret / testSecret / finishSecret。createSecret は新値を AWSPENDING として保存(idempotency のため)(source 4)。
- finishSecret は AWSCURRENT を旧版から新版へ「移動」し、同じAPI呼び出しで AWSPENDING を外す。Secrets Manager が旧版に自動で AWSPREVIOUS を付け、直前の正常版を保持(source 4「finishSecret」節)。
- アプリが常に読むのは AWSCURRENT。名札の付け替えが原子的だから、ローテーション中もアプリは無停止で最新版を掴める。
秘密は「コードに書かない・実行時に取り出す・定期的に入れ替える」。ローテーションの本質は版の中身を書き換えることではなく、AWSCURRENT という名札を新しい版へ付け替えること。アプリは名札の側だけを見るので、下で版が入れ替わっても気づかず動き続ける。
⑤ 種明かし — 1本のログインに、これまで見た原理が全部再登場していた
認証=誰かこの編の中心
ユーザープールのJWT①発行/②検証
公開鍵で署名検証非対称鍵の署名検証
認可=AWSへの権限
IDプール+STS③両替
期限付きリース時限リース
完全性=改ざんなし
JWT署名検証kid→署名(②)
非対称鍵の署名検証認証と同じ仕組みの別用途
機密性=盗み見なし
Secrets ManagerSecureStringのKMS暗号化(④)
KMS暗号化+ラベル付替えラベル=ポインタの付け替え
認証暗号編の主役AWSリソースへの認可(IAM/STSが中心)
この編の主役アプリのユーザー認証(ユーザープールのJWTが中心)
- 4分類の対応:ユーザープールのJWT=認証(誰か)、IDプール+STS=認可(AWSリソースへの権限)、JWT署名検証=完全性(改ざん検知)、Secrets Manager/SecureString の KMS暗号化=機密性(盗み見防止)。
- 再登場した3原理:②の非対称鍵の署名検証(公開鍵暗号)、③の時限リース(STS一時認証情報)、④のラベルという名のポインタの付け替え(AWSCURRENT/AWSPENDING/AWSPREVIOUS)。
- この3原理はコース全体で繰り返し登場したもの。JWT署名検証は認証暗号編の公開鍵暗号、STS一時認証情報は認証暗号編の時限リース、ラベルの付け替えは DynamoDB編・S3編で見た「版を動かさず参照だけ差し替える」追記ログ/バージョニングの発想と同じ。
- 住み分け:認証暗号編は「AWSリソースへの認可」が主役だったのに対し、この編は「アプリのユーザー認証」が主役。同じ4つの問いを、別の主役で解いている。
1本のログインの裏側は、非対称鍵の署名検証・時限リースの発行・ポインタ(ラベル)の付け替えという、これまでの編で見た原理の総動員だった。マネージドサービスは魔法ではなく、コンピュータの基礎の組み合わせでできている——それがこの編の、そしてコース全体の締めくくり。