外部IdPの認証情報からAWS一時クレデンシャルを取得する方法を調べてみた(Cognito Identity Pool と IAM OIDC Federation)
はじめに
「開発者ごとに IAM ユーザを作りたくない」
例えば生成 AI サービス(Amazon Bedrock 等)を社内の開発者に使わせたい場面などで、ユーザの数だけ IAM ユーザを作るのは管理コストが高く現実的ではありません。こういった場面において、既存の IdP(Cognito User Pool、Entra ID、Okta 等)のトークンを AWS の一時クレデンシャルに変換する方法として、本記事では以下の 2 方式を取り上げます。
- Cognito Identity Pool: 認証と認可の「橋渡し役」
- IAM OIDC Federation: STS に直接委任する「シンプル」な方式
本記事では、この 2 方式の仕組み・違い・選び方を解説します。
認証と認可は別のもの
まず前提を整理します。
| 役割 | 担当 | やること |
|---|---|---|
| 認証(Authentication) | 外部 IdP | 「この人は誰か」を判定し、ID Token(JWT)を発行 |
| 認可(Authorization) | AWS IAM | 「この人に何を許可するか」を制御。一時クレデンシャルで表現 |
外部 IdP が発行した ID Token だけでは、AWS リソースにはアクセスできません。ID Token を AWS の一時クレデンシャル(AccessKeyId / SecretAccessKey / SessionToken)に変換するプロセスが必要です。
この変換を担うのが Identity Pool や IAM OIDC Federation です。
外部 IdP(認証)
│
│ ID Token (JWT)
↓
Identity Pool or IAM OIDC Federation ← 今回の主題
│
│ AWS 一時クレデンシャル
↓
AWS リソース(認可)
なぜ AWS は外部の ID Token を信頼することができるのか
「事前登録」と「JWT の署名検証」によって信頼します。
事前登録: 「この IdP を信頼する」と宣言する
管理者が AWS に対して「この IdP のトークンなら信頼してよい」と事前に登録します。登録なしに任意の IdP のトークンで AWS にアクセスすることは不可能です。
- Identity Pool: 認証プロバイダーとして IdP を追加
- IAM OIDC Federation: IAM OIDC Provider を作成し、IdP の issuer URL と audience を登録
JWT の署名検証: 偽造を防ぐ
ID Token は JWT(JSON Web Token)形式で、IdP の秘密鍵で署名されています。
AWS は以下を検証します。
- 署名の検証: IdP の公開鍵で JWT の署名を確認
- issuer (iss): 登録済みの IdP が発行したトークンか
- audience (aud): 正しいアプリ向けのトークンか
- 有効期限 (exp): 期限内か
IdPの秘密鍵を持たない限り有効な署名を生成することはできないので、トークンを偽造することもできません。
方式 1: Cognito Identity Pool
概要
Identity Pool は認証と認可の橋渡し役です。外部 IdP の認証結果を受け取り、事前設定されたルールに従って IAM ロールの一時クレデンシャルを発行します。
フロー
対応する IdP
| IdP タイプ | 設定方法 |
|---|---|
| Cognito User Pool | 認証プロバイダーとして直接指定 |
| SAML 対応 IdP(Entra ID, Okta 等) | SAML プロバイダーとして登録 |
| OIDC 対応 IdP(Auth0, Keycloak 等) | OIDC プロバイダーとして登録 |
| ソーシャル IdP(Google, Apple, Facebook, Amazon) | 組み込みサポート |
特徴
- API 呼び出しは2回行われる(GetId + GetCredentialsForIdentity)
- セッション時間は1時間固定で変更不可
- IAM OIDC Provider の手動登録が不要(Identity Pool が内部で処理)
- ロールマッピング機能がある(後述)
- CloudTrail でのユーザ特定が間接的(後述)
方式 2: IAM OIDC Federation
概要
Identity Pool を介さず、ID Token を直接 STS に渡して一時クレデンシャルを取得する方式です。事前に IAM OIDC Provider を登録しておく必要があります。
フロー
特徴
- API 呼び出しは1回(AssumeRoleWithWebIdentity)
- セッション時間は最大12時間(IAM ロールの MaxSessionDuration で管理者が設定)
- IAM OIDC Provider の事前登録が必要
- ロールマッピングは組み込みでは非対応(コード実装 + Trust Policy で実現可能)
- CloudTrail でのユーザ特定が直接的(後述)
Trust Policy の例
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::123456789012:oidc-provider/cognito-idp.ap-northeast-1.amazonaws.com/ap-northeast-1_xxxxx"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"cognito-idp.ap-northeast-1.amazonaws.com/ap-northeast-1_xxxxx:aud": "client-id-here"
}
}
}]
}
Principal.Federated で「どの IdP を信頼するか」、Condition で「トークンのどのクレームがどの値であれば許可するか」を指定します。
セッション時間の制御
| 設定者 | 設定項目 | 説明 |
|---|---|---|
| 管理者 | IAM ロールの MaxSessionDuration |
上限値を設定(1〜12 時間、デフォルト 1 時間) |
| 呼び出し元 | --duration-seconds パラメータ |
希望値をリクエスト(上限以内) |
ロールマッピング — ユーザの属性に応じた権限の切り替え
「管理者は全モデル使える、一般ユーザは Sonnet のみ」のように、ユーザの属性に応じて IAM ロール(権限)を切り替えたいケースがあります。
Identity Pool の場合
AWS 側の設定だけでロールを切り替えられます。コード変更は不要です。
Identity Pool のロールマッピング設定:
cognito:groups に "admin" を含む → BedrockFullAccessRole
cognito:groups に "member" を含む → BedrockSonnetOnlyRole
admin グループのユーザが ID Token を渡すと、Identity Pool がトークン内の cognito:groups を読み、自動的に BedrockFullAccessRole のクレデンシャルを発行します。
IAM OIDC Federation の場合
組み込みのロールマッピング機能はありません。呼び出し元にロジックを実装します。
呼び出し元のコード:
1. ID Token を取得
2. JWT をデコードして groups クレームを読む
3. "admin" → ロール A で AssumeRoleWithWebIdentity
"member" → ロール B で AssumeRoleWithWebIdentity
「呼び出し元を改竄して不正なロールを指定されるのでは?」と心配になるかもしれませんが、各 IAM ロールの Trust Policy に Condition を設定しておけば、STS がサーバ側でクレームを検証し条件に合わないリクエストを拒否します。ユーザー側にロール名を通知する必要がありますが、最終的な認可判断は AWS 側で行われるためセキュリティ水準は Identity Pool と同等です。
比較
| 観点 | Identity Pool | IAM OIDC Federation |
|---|---|---|
| ロール選択のロジック | AWS 側の設定のみ | AWS 側の設定 + 呼び出し元のコード実装 |
| 新しいグループ追加時 | AWS の設定変更のみ | AWS の設定変更 + 呼び出し元のコード変更 |
| セキュリティ | Identity Pool が判定 | Trust Policy でガード(同等) |
2方式の比較まとめ
| 項目 | Identity Pool | IAM OIDC Federation |
|---|---|---|
| 仕組み | ID Token → Identity Pool → 内部で STS → クレデンシャル | ID Token → STS → クレデンシャル |
| API 呼び出し | 2 回 | 1 回 |
| セッション時間 | 1 時間固定(変更不可) | 最大 12 時間(管理者設定) |
| CloudTrail でのユーザ特定 | 間接的 | 直接的 |
| ロールマッピング | 対応(AWS 側の設定のみ) | コード実装 + Trust Policy |
| 対応 IdP | Cognito, SAML, OIDC, ソーシャル | OIDC 準拠の IdP |
| 概念的な役割 | 認証と認可の橋渡し役 | STS に直接委任 |
どちらを選ぶか
| こんなときは | こちらを選ぶ |
|---|---|
| セッション時間を1時間以上にしたい | IAM OIDC Federation |
| CloudTrail で操作者を直接特定したい | IAM OIDC Federation |
| CloudTrail のログを少しでも減らしたい | IAM OIDC Federation |
| グループ/属性でロールを切り替えたい(コード変更なしで) | Identity Pool |
| SAML 対応 IdP を使いたい | Identity Pool |
| 最小構成で始めたい | IAM OIDC Federation |
CloudTrail でのユーザ特定 — 具体的にどう記録されるか
実際に Claude Code on Bedrock を実行した際の CloudTrail ログで比較します。
IAM OIDC Federation の場合
CloudTrail のイベント履歴を見ると、以下のイベントが記録されています。

IAM OIDC Federation の CloudTrail
| # | イベント名 | ユーザー名 | イベントソース |
|---|---|---|---|
| 1 | InitiateAuth | - | cognito-idp.amazonaws.com |
| 2 | AssumeRoleWithWebIdentity | (Cognito sub) | sts.amazonaws.com |
| 3 | ListInferenceProfiles | user@example.com | bedrock.amazonaws.com |
| 4 | InvokeModelWithResponseStream | user@example.com | bedrock.amazonaws.com |
Bedrock の操作(3, 4)のユーザー名に RoleSessionName で指定したメールアドレスがそのまま記録されています。ログを見るだけで誰の操作かすぐにわかります。
InvokeModelWithResponseStream のログの userIdentity を抜粋すると:
{
"userIdentity": {
"type": "AssumedRole",
"principalId": "AROAXXXXXXXXXXXXXXXXX:user@example.com",
"arn": "arn:aws:sts::123456789012:assumed-role/BedrockClaudeCodeOidcRole/user@example.com",
"sessionContext": {
"sessionIssuer": {
"userName": "BedrockClaudeCodeOidcRole"
},
"webIdFederationData": {
"federatedProvider": "cognito-idp.ap-northeast-1.amazonaws.com/ap-northeast-1_xxxxx"
}
}
}
}
principalId の : 以降が RoleSessionName(メールアドレス)、webIdFederationData.federatedProvider にどの IdP 経由かも記録されます。
Identity Pool の場合

Identity Pool の CloudTrail
| # | イベント名 | ユーザー名 | イベントソース |
|---|---|---|---|
| 1 | InitiateAuth | - | cognito-idp.amazonaws.com |
| 2 | AssumeRoleWithWebIdentity | (IdentityId) | sts.amazonaws.com |
| 3 | ListInferenceProfiles | CognitoIdentityCredentials | bedrock.amazonaws.com |
| 4 | InvokeModelWithResponseStream | CognitoIdentityCredentials | bedrock.amazonaws.com |
Bedrock の操作(3, 4)のユーザー名が一律 CognitoIdentityCredentials です。ログだけでは誰の操作か特定できません。
InvokeModelWithResponseStream のログの userIdentity を抜粋すると:
{
"userIdentity": {
"type": "AssumedRole",
"principalId": "AROAXXXXXXXXXXXXXXXXX:CognitoIdentityCredentials",
"arn": "arn:aws:sts::123456789012:assumed-role/BedrockClaudeCodeCognitoRole/CognitoIdentityCredentials",
"sessionContext": {
"sessionIssuer": {
"userName": "BedrockClaudeCodeCognitoRole"
},
"webIdFederationData": {
"federatedProvider": "cognito-identity.amazonaws.com",
"attributes": {
"cognito-identity.amazonaws.com:amr": "[\"authenticated\",\"cognito-idp.ap-northeast-1.amazonaws.com/ap-northeast-1_xxxxx\",...]",
"cognito-identity.amazonaws.com:sub": "ap-northeast-1:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}
}
}
}
}
cognito-identity.amazonaws.com:sub に IdentityId が含まれますが、これだけではユーザのメールアドレス等はわかりません。
Identity Pool でユーザを特定する方法
Identity Pool 経由でも、以下の手順でユーザを突合できます。
- 上記ログの
cognito-identity.amazonaws.com:subから IdentityId を取得する aws cognito-identity describe-identityで IdentityId から紐付く IdP のユーザ情報(Cognito のsub等)を逆引きする
aws cognito-identity describe-identity \
--identity-id "ap-northeast-1:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" \
--region ap-northeast-1
セッション期限切れはユーザ体験に影響は(ほぼ)ない
「セッション時間が1時間で期限切れ」について説明します。
セッション期限切れが起こると、リフレッシュトークンを利用してID Tokenを更新する必要があります。認証ヘルパー側でリフレッシュを実装していればエンドユーザが意識する必要はありません。ただし、リフレッシュのタイミングで数秒の待ち時間が発生します。
AWS 一時クレデンシャルが期限切れ
→ アプリケーションが検知
→ IdP のリフレッシュトークンで新しい ID Token を取得(ブラウザは開かない)
→ Identity Pool / STS で新しい一時クレデンシャルを取得
→ ユーザから見ると途切れなく動作し続ける
ブラウザ再認証が必要なのはリフレッシュトークンの期限切れ時のみ(Cognito のデフォルトは 30日)です。
セッション時間の長短で変わるのは以下です。
- リフレッシュの頻度(1時間ごと vs 12時間ごと)
- IdP / STS の API 呼び出し回数(ただし STS・Identity Pool・Cognito User Pool のリフレッシュ API はいずれも無料。呼び出し回数が増えても費用には影響しない)
- CloudTrail のログ量(リフレッシュのたびに AssumeRoleWithWebIdentity 等のログが記録される)
IdP が Cognito User Pool の場合と外部 IdP の場合の違い
Cognito User Pool を IdP として使うと、AWS サービスとの統合がより深くなります。
以下に、AWS サービス上でできることをまとめます。
| 機能 | Cognito User Pool | 外部 OIDC IdP |
|---|---|---|
Token 型ロールマッピング(cognito:groups による自動選択) |
対応 | 非対応(Rules ベースのみ) |
| Pre Token Generation Lambda(クレームの動的カスタマイズ) | 対応 | 不可(IdP 側で設定) |
| AWS WAF 直接統合 | 対応 | 不可(*) |
| AdminUserGlobalSignOut(強制ログアウト) | 対応 | 不可(*) |
| 適応認証・漏洩パスワード検出(Plus プラン) | 対応 | 不可(*) |
(*): IdP 側の同等機能で対応可能な場合あり
料金の違い
| 構成 | 料金 |
|---|---|
| Cognito User Pool(ローカルユーザー) | 無料枠 10,000 MAU/月 |
| Cognito User Pool(SAML/OIDC フェデレーション) | 無料枠 50 MAU/月 |
| Identity Pool に外部 IdP を直接接続 | Identity Pool 自体は無料 |
既存の IdP(Entra ID, Okta 等)がありユーザ管理がそちらで完結しているなら、Cognito User Pool を経由する必要はありません。Identity Pool に直接つなぐ構成が料金面でも有利です。
Active Directory(オンプレミス AD)の場合
Active Directory 自体は OIDC/SAML を話さないため、直接接続できません。間に中継層を挟む必要があります。
| 中継層 | プロトコル | Identity Pool | IAM OIDC Federation |
|---|---|---|---|
| AD FS | SAML | 対応 | AssumeRoleWithSAML(別 API) |
| AD FS(新しいバージョン) | OIDC | 対応 | 対応 |
| Entra ID(Azure AD Connect で同期) | OIDC / SAML | 対応 | 対応 |
例えばオンプレ AD を Entra ID に同期している企業であれば、Entra ID を外部 IdP として本記事のパターンがそのまま使えます。
オンプレミス AD
↓ Azure AD Connect で同期
Entra ID (OIDC/SAML)
↓
Identity Pool or IAM OIDC Federation
↓
AWS 一時クレデンシャル
まとめ
今回調査した、外部 IdP の認証を AWS の認可に変換する方式は以下の2つ。
- Identity Pool: 認証と認可の橋渡し役。ロールマッピングを AWS 側の設定だけで実現できる。セッション時間は 1 時間固定。
- IAM OIDC Federation: STS に直接委任するシンプルな方式。セッション最大 12 時間、CloudTrail でのユーザ特定に強い。
どちらを選んでも、外部 IdP のユーザに IAM ユーザを作ることなく AWS リソースへのアクセスを許可できます。







