Contents
1️⃣ Cognito の基本概念と認証‑認可の分担
1.1 用語解説
| 用語 | 意味 |
|---|---|
| ユーザープール | ユーザー情報(メール・パスワード等)を管理し、サインアップ/サインインや MFA を提供する認証基盤。成功すると JWT (ID トークン/アクセストークン) が発行される。 |
| ID プール(アイデンティティプール) | ユーザープールから取得した JWT を受け取り、AWS の一時的クレデンシャルを生成する認可基盤。IAM ロールへマッピングしてリソースアクセスを制御できる。 |
| IAM ロール | AWS リソースへの権限集合。Cognito が発行したクレデンシャルはこのロールに紐付くことで実際の操作が可能になる。 |
| トークンからロール選択 (Token from role selection) | JWT に埋め込まれた情報(例: cognito:groups) を基に、どの IAM ロールを取得すべきか自動的に決定する方式。 |
1.2 認証・認可フロー(Mermaid 図)
|
1 2 3 4 5 6 7 8 9 10 11 |
flowchart TD A[ユーザー] -->|サインアップ/サインイン| B[User Pool] B -->|JWT 発行| C[クライアント (SPA / Mobile)] C -->|JWT を ID プールへ送信| D[Identity Pool] D -->|トークン検証 & ロールマッピング| E[IAM Role] E -->|AssumeRoleWithWebIdentity| F[一時的 AWS クレデンシャル] F -->|S3 / DynamoDB などの API 呼び出し| G[AWS リソース] classDef aws fill:#F0F8FF,stroke:#333; class D,E,F,G aws; |
- 認証:ユーザープールが行う(ステップ A→B)。
- 認可:ID プールが JWT を元に IAM ロールを決定し、一時的クレデンシャルを発行(ステップ D→F)。
公式ドキュメントは AWS の開発者ガイド「Amazon Cognito Identity Pools – 開始ガイド」をご参照ください。
2️⃣ IAM カスタムロールの作成と信頼ポリシー設定
2.1 ロール作成手順(コンソール編)
- IAM コンソール → ロール → ロールを作成 を選択。
- 信頼されたエンティティとして 「Cognito」 > 「Cognito ID プール」 を指定し、対象の ID プール ID を入力。
- 必要最小限の権限(例:
AmazonS3ReadOnlyAccess)をポリシーでアタッチ。 - ロール名は
cognito-{appName}-{rolePurpose}という規則に従うと管理しやすい(例:cognito-inventory-readonly)。
2.2 信頼ポリシーの正しい記述例
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Federated": "cognito-identity.amazonaws.com" }, "Action": "sts:AssumeRoleWithWebIdentity", "Condition": { "StringEquals": { "cognito-identity.amazonaws.com:aud": "<IDENTITY_POOL_ID>" }, "ForAnyValue:StringLike": { "cognito-identity.amazonaws.com:amr": "authenticated" } } } ] } |
aud:対象の ID プール ID(必ず実際の文字列に置き換える)。amr:authenticatedにすると、認証済みユーザーだけがロール取得できる。
※上記は公式サンプルと同一です。(IAM ロールの信頼ポリシー – AWS Docs)
3️⃣ ユーザープールグループ ↔ IAM ロール の紐付け
3.1 グループ作成とロール割り当て(コンソール)
| 手順 | 内容 |
|---|---|
| ① | Cognito → ユーザープール → グループ で admin・editor 等のグループを作成。 |
| ② | 各グループ編集画面の 「IAM ロール」 欄に、先ほど作成したカスタムロール ARN を入力(例: arn:aws:iam::123456789012:role/cognito-inventory-admin)。 |
| ③ | ID プール → 認証されたロール → Role mapping で 「Token from role selection」 を選択し、「Choose role from token」 に設定。 |
3.2 背景と効果
- ユーザープール側でグループにロール ARN を埋め込むだけで、ID プールは JWT の
cognito:groupsクレームを参照し自動的に対応ロールを選択します。 - アプリ側のコードは 「Cognito がロールマッピングをやってくれる」 という前提で実装できるため、認可ロジックが宣言的かつ保守性が向上します。
同様の手順は Zenn 記事「Cognito の ID プールでロールベースアクセス制御を行う」でも紹介されています(外部リンクは公式情報に準拠しています)。
4️⃣ Role Mapping の API/SDK による動的設定
4.1 SetIdentityPoolRoles API の正しいリクエスト構造
AWS CLI・SDK が期待する JSON は RoleMappings キーが「プロバイダー名 → マッピング情報」のマップ形式です。以下は公式ドキュメントに沿ったサンプルです。
|
1 2 3 4 |
aws cognito-identity set-identity-pool-roles \ --identity-pool-id <IDENTITY_POOL_ID> \ --role-mappings file://mapping.json |
mapping.json の例(Token based mapping)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
{ "RoleMappings": { "cognito-idp.<region>.amazonaws.com/<USER_POOL_ID>": { "Type": "Token", "AmbiguousRoleResolution": "Deny", "RulesConfiguration": { "Rules": [ { "Claim": "cognito:groups", "MatchType": "Contains", "Value": "admin", "RoleArn": "arn:aws:iam::123456789012:role/cognito-inventory-admin" }, { "Claim": "cognito:groups", "MatchType": "Contains", "Value": "editor", "RoleArn": "arn:aws:iam::123456789012:role/cognito-inventory-editor" } ] } } } } |
cognito-idp.<region>.amazonaws.com/<USER_POOL_ID>が対象のユーザープールを指すキーです。AmbiguousRoleResolutionにDenyを設定すると、どのルールにもマッチしなかった場合はロール取得が拒否されます(安全策)。
詳細は公式リファレンス SetIdentityPoolRoles – AWS CLI Command Reference を参照してください。
4.2 SDK 実装例(JavaScript / Amplify)
|
1 2 3 4 5 6 7 8 9 10 |
import { Auth } from 'aws-amplify'; // サインイン後に自動的にロールマッピングが適用されたクレデンシャルを取得 export async function fetchCredentials() { await Auth.currentAuthenticatedUser(); // 必要ならサインイン待ち const cred = await Auth.currentCredentials(); console.log('AWS AccessKeyId:', cred.accessKeyId); return cred; } |
- Amplify は内部で
cognito-identityのGetId・GetCredentialsForIdentityを呼び出し、取得したクレデンシャルは自動的にキャッシュします。
4.3 SDK 実装例(Python / boto3)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
import boto3 from botocore.exceptions import ClientError cognito_id = boto3.client('cognito-identity', region_name='ap-northeast-1') def set_role_mapping(identity_pool_id): try: response = cognito_id.set_identity_pool_roles( IdentityPoolId=identity_pool_id, RoleMappings={ f'cognito-idp.{cognito_id.meta.region_name}.amazonaws.com/<USER_POOL_ID>': { 'Type': 'Token', 'AmbiguousRoleResolution': 'Deny', 'RulesConfiguration': { 'Rules': [ { 'Claim': 'cognito:groups', 'MatchType': 'Contains', 'Value': 'admin', 'RoleArn': 'arn:aws:iam::123456789012:role/cognito-inventory-admin' }, { 'Claim': 'cognito:groups', 'MatchType': 'Contains', 'Value': 'editor', 'RoleArn': 'arn:aws:iam::123456789012:role/cognito-inventory-editor' } ] } } } ) print('Role mapping updated:', response) except ClientError as e: print('Failed to set role mapping:', e) # 呼び出し例 set_role_mapping('<IDENTITY_POOL_ID>') |
- ポイント:
RoleMappingsのキーは必ずcognito-idp.<region>.amazonaws.com/<USER_POOL_ID>形式で指定する必要があります。
4.4 インフラコードへの組み込み例(AWS CDK)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
import * as cognito from 'aws-cdk-lib/aws-cognito'; import * as iam from 'aws-cdk-lib/aws-iam'; import { Stack, StackProps } from 'aws-cdk-lib'; export class CognitoStack extends Stack { constructor(scope: Construct, id: string, props?: StackProps) { super(scope, id, props); const userPool = new cognito.UserPool(this, 'UserPool', {/* … */}); const identityPool = new cognito.CfnIdentityPool(this, 'IdentityPool', { allowUnauthenticatedIdentities: false, cognitoIdentityProviders: [{ clientId: userPool.userPoolClient.clientId, providerName: userPool.userPoolProviderName, }], }); const adminRole = new iam.Role(this, 'AdminRole', { assumedBy: new iam.FederatedPrincipal( 'cognito-identity.amazonaws.com', { "StringEquals": { "cognito-identity.amazonaws.com:aud": identityPool.ref } }, 'sts:AssumeRoleWithWebIdentity' ), }); adminRole.addManagedPolicy(iam.ManagedPolicy.fromAwsManagedPolicyName('AmazonS3FullAccess')); // Role mapping (CDK では CfnIdentityPool の roleMappings プロパティを使用) const roleMapping = new cognito.CfnIdentityPool.RoleMappingProperty({ type: 'Token', ambiguousRoleResolution: 'Deny', rulesConfiguration: { rules: [ { claim: 'cognito:groups', matchType: 'Contains', value: 'admin', roleArn: adminRole.roleArn, }, ], }, }); const cfnIdentityPool = identityPool.node.defaultChild as cognito.CfnIdentityPool; cfnIdentityPool.addPropertyOverride('RoleMappings', { [`cognito-idp.${this.region}.amazonaws.com/${userPool.userPoolId}`]: roleMapping, }); } } |
- CDK を利用すれば コードベースでロールマッピングを管理 でき、CI/CD パイプラインに組み込むのが容易です。
5️⃣ カスタムロール適用のテスト・エラーハンドリング・ベストプラクティス
5.1 テストフロー(実際に一時的クレデンシャルを取得)
- サインアップ → サインイン をアプリ側で完了させる。
- Amplify の
Auth.currentCredentials()または boto3 のget_id+get_credentials_for_identityで 一時的クレデンシャル を取得。 - 取得した AccessKeyId/SecretAccessKey で AWS CLI(例:
aws s3 ls --profile temporary) を実行し、期待通りのリソースにアクセスできるか確認する。
公式サンプルアプリは Cognito Identity Pools – Getting Started Application にあります。
5.2 よくあるエラーと対策
| エラー | 原因 | 推奨対処 |
|---|---|---|
InvalidIdentityPoolConfigurationException |
Role Mapping が未設定、または信頼ポリシーに cognito-identity.amazonaws.com が欠如 |
コンソール/CLI で Token from role selection を有効化し、信頼ポリシーを再確認 |
AccessDenied(S3 等) |
ロールに必要な権限が不足している | IAM ポリシーに対象アクション (s3:GetObject, dynamodb:Query など) を追加。最小権限の原則で見直し |
JWT に cognito:groups が無い |
ユーザープール側でグループ割り当てが漏れている | 管理コンソールまたは自動化スクリプトで対象ユーザーを正しいグループに所属させる |
5.3 運用上のベストプラクティス
- 最小権限
-
ロールごとに必要最低限のポリシーだけを付与し、
IAM Access Analyzerで過剰権限が無いか定期的に検査。 -
命名規則の徹底
-
cognito-{appName}-{rolePurpose}(例:cognito-inventory-admin)とすれば、ロール一覧から目的を瞬時に把握できる。 -
監査ログの活用
-
CloudTrail の
AssumeRoleWithWebIdentityイベントを有効化し、誰がどのロールを取得したか を可視化。異常取得は EventBridge でアラート化すると即応可能。 -
インフラコードで一元管理
-
CDK・Terraform・CloudFormation のいずれかで ユーザープール、ID プール、IAM ロール、Role Mapping を同時にデプロイし、環境差分がコードレビューで把握できるようにする。
-
テスト自動化
- CI パイプラインに
aws sts get-caller-identityなどの簡易コマンドを組み込み、デプロイ後にロール取得と権限検証をスクリプトで実行する。
📚 まとめ(全体像)
- 認証はユーザープール、認可は ID プール が基本構造。
- IAM カスタムロール は最小権限で作成し、
cognito-identity.amazonaws.comを信頼ポリシーに必ず入れる。 - ユーザープールグループ ↔ IAM ロール の 1 対 1 紐付けで、トークンベースのロール選択が自動化できる。
- SetIdentityPoolRoles API と SDK(Amplify / boto3)を活用すれば、環境ごとや条件分岐に応じたロールマッピングをコード化・自動化可能。
- テスト・監査・最小権限の徹底 が運用上の成功要因。CloudTrail と IAM Access Analyzer を併用し、定期的なレビューと CI での検証を組み込むことが推奨される。
これらの手順とベストプラクティスを踏まえて実装すれば、Cognito の認証・認可機構を安全かつスケーラブルに活用できるでしょう。