Dev Study
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本のログインの裏側は、非対称鍵の署名検証・時限リースの発行・ポインタ(ラベル)の付け替えという、これまでの編で見た原理の総動員だった。マネージドサービスは魔法ではなく、コンピュータの基礎の組み合わせでできている——それがこの編の、そしてコース全体の締めくくり。

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