[AWS]Amazon Cognito ユーザープールへのアダプティブ認証設定方法


* Cognito ユーザープールにおけるアダプティブ認証とその設定方法についてまとめる。
## 1. アダプティブ認証とは
* ユーザーのサインイン試行ごとにリスク評価を行い、異常な試行に対して追加の認証（MFA の要求）やアクセスのブロックなどの自動応答を実施する機能。
```mermaid
sequenceDiagram
    autonumber
    participant U as ユーザー
    participant UI as フロントエンド（Hosted UI／カスタムUI）
    participant C as Cognito
    participant RA as リスク評価エンジン

    U->>UI: ユーザー名／パスワードを入力
    UI->>C: InitiateAuth API呼び出し<br/>(ContextData付)
    C->>RA: IP、デバイス、ロケーション等でリスク評価
    RA-->>C: リスクレベル (Low / Medium / High)
    C-->>UI: 認証チャレンジとリスクレベル情報返却
    alt リスクがLowの場合
        UI->>U: そのままサインイン成功（通常のセッション開始）
    else リスクがMediumの場合
        UI->>U: オプションMFAのプロンプト表示<br/>(MFA設定済みなら)
        U->>UI: MFAコード入力（任意）
        UI->>C: RespondToAuthChallenge API呼び出し (MFAコード付)
        C-->>UI: 認証成功／アクセストークン発行
    else リスクがHighの場合
        UI->>U: 強制的にMFAチャレンジ表示またはサインインブロック
        U->>UI: MFAコード入力
        UI->>C: RespondToAuthChallenge API呼び出し (MFAコード付)
        C-->>UI: 認証成功／アクセストークン発行
    end

```
## 2. アダプティブ認証の目的・主要概念

- **アダプティブ認証の目的**  
    アダプティブ認証は、ユーザーのサインインリクエストのコンテキスト（例：IP アドレス、デバイス、ロケーションなど）をもとにリスクを評価し、リスクが高い場合には MFA の追加要求やサインインのブロックといった対応を自動化する。
    
- **リスク評価の基準**  
    リスクは一般に「低」「中」「高」の3段階に分類され、以下のような要因が影響します。
    - 過去のサインインパターン（デバイスやロケーションの一致性）
    - アクセス元 IP アドレスの変化
    - ユーザーエージェントやブラウザの情報
    - その他のセッションコンテキスト情報
- **各リスクレベルに対するアクション**  
    各リスクレベルに対して以下のような自動応答を設定可能。
    - **低リスク**：通常のサインインを許可
    - **中リスク**：MFA のオプション要求（MFA が設定済みの場合はチャレンジを実施）
    - **高リスク**：MFA を必須にするか、場合によってはサインインをブロック

## 3. 設定方法

### 3.1 コンソールによる設定

1. **ユーザープールの作成または選択**  
    AWS Cognito コンソールにサインインし、対象のユーザープールを選択、または新規作成する。
    
2. **高度なセキュリティ機能の有効化**  
    ユーザープールの詳細画面で、Advanced securityタブを選択し、アダプティブ認証を有効にする。  
    ※この設定により、ユーザープール内で各サインイン試行に対してリスク評価が自動的に実施される。
    
3. **リスク評価と自動応答の設定**  
    以下の各項目を設定する。
    - **アクションの選択**
        - 低リスクの場合：許可（追加認証なし）または MFA オプションの提示
        - 中リスクの場合：MFA のオプションを要求
        - 高リスクの場合：MFA を必須にする、またはサインインをブロック
    - **通知設定**  
        ユーザーに対して、不審なサインイン試行があった場合にメール通知を送る設定を行う。通知には SES の設定が必要となる（事前に E メールアドレスの検証および SES のサンドボックス外への移行を実施）。
4. **設定の保存とテスト**  
    すべての設定内容を確認後、設定を保存し、テストユーザーでサインイン試行を実施し、リスク評価と自動応答が意図したとおりに動作するか検証する。
    
### 3.2 AWS CDK による設定

AWS CDK を利用する場合、ユーザープール作成時のオプションとしてアドバンスドセキュリティ機能を設定できる。

```typescript
new cognito.UserPool(this, "MyUserPool", {
  // ...その他の設定
  advancedSecurityMode: cognito.AdvancedSecurityMode.ENFORCED, // または AUDIT
});
```

- **AUDIT モード**  
    脅威の検出のみ行い、アラートを生成するが自動応答は行わない。
- **ENFORCED モード**  
    脅威が検出された場合、設定された自動応答（MFA 要求やサインインブロック）を実施する。

※なお、CDK での高度なセキュリティの細かい設定（リスクレベル毎のアクションのカスタマイズ）は、`CfnUserPoolRiskConfigurationAttachment` を利用して個別に設定する必要がある。

## 4. 設定時の注意事項

- **リスク評価の初期学習期間**  
    アダプティブ認証の精度は、ユーザーの正常なサインインパターンの学習後に向上する。初期は「監査のみ」モードで動作させ、十分なデータが蓄積された後に「ENFORCED」モードに切り替える運用が推奨される。
    
- **通知設定**  
    ユーザーへの通知を行う場合、SES の設定（E メールの検証、サンドボックス解除）が必要。通知の文面やフィードバックリンクのカスタマイズも事前に設定する必要がある。
    
- **偽陽性の対策**  
    過剰なリスク評価により正常なサインインがブロックされる可能性があるため、各リスクレベルの閾値は慎重に設定し、必要に応じてユーザーからのフィードバック機能を活用して精度向上を図る。
    
- **ログの活用**  
    アダプティブ認証によって生成される CloudWatch Metrics やユーザーイベント履歴を活用して、不正アクセスの兆候を迅速に検知し、必要な対策を講じる。
    
## 5. カスタムUI実装との連携

```mermaid
sequenceDiagram
    autonumber
    participant U as ユーザー
    participant UI as カスタムUI
    participant Context as コンテキストデータ収集モジュール
    participant C as Cognito API
    participant MFA as 認証アプリ（TOTP／SMS）

    %% ① ログイン入力とコンテキスト収集
    U->>UI: ログインフォームにユーザー名／パスワード入力
    UI->>Context: IP, デバイスフィンガープリント等を収集
    Context-->>UI: EncodedContextData生成完了
    UI->>C: InitiateAuth API呼び出し<br/>(認証情報＋EncodedContextData)

    %% ② Cognitoによるリスク評価
    C->>UI: リスク評価結果とチャレンジ情報返却<br/>(Low/Medium/High)

    %% ③ リスクレベルに応じた分岐
    alt リスクがLowの場合
        UI->>U: サインイン成功、通常のセッション開始
    else リスクがMediumの場合
        UI->>U: 「MFA設定済みの場合のみ」MFAチャレンジ（オプション）を表示
        U->>UI: （任意）MFAコード入力
        UI->>C: RespondToAuthChallenge API呼び出し (MFAコード付)
        C-->>UI: 認証成功／アクセストークン発行
    else リスクがHighの場合
        UI->>U: 強制MFAチャレンジ表示
        alt ユーザーがMFA未登録の場合 (TOTP例)
            UI->>C: AssociateSoftwareToken API呼び出し<br/>(TOTP登録用シークレット取得)
            C-->>UI: シークレットキー返却
            UI->>U: QRコード生成し表示（TOTP登録用）
            U->>MFA: 認証アプリでQRコードをスキャンしOTP生成
            U->>UI: OTP入力（TOTP登録画面）
            UI->>C: VerifySoftwareToken API呼び出し<br/>(OTP検証)
            C-->>UI: TOTP登録完了
            UI->>C: SetUserMfaPreference API呼び出し<br/>(TOTPをMFA優先に設定)
        end
        U->>UI: MFAコード入力（既登録または登録後）
        UI->>C: RespondToAuthChallenge API呼び出し (MFAコード付)
        C-->>UI: 認証成功／アクセストークン発行
    end

    %% ④ セッション管理とフィードバック
    UI->>U: 認証完了、ユーザー情報表示／セッション管理開始

```
Hosted UI では自動でアダプティブ認証の評価が行われるが、独自にUIを実装する場合、以下の要素との連携が求められる。

- **UIコンポーネント**  
    通常のログイン画面に加えて、リスク評価に応じた MFA チャレンジやエラーメッセージを表示する画面の実装が必要となる。
    
- **API連携**  
    サインイン時に **InitiateAuth** や **RespondToAuthChallenge** の API 呼び出しに、`ContextData` または `UserContextData` パラメータとして、コンテキストデータ収集モジュールから取得したユーザーの IP アドレスやデバイス情報などのコンテキスト情報を追加する。これにより、Cognito が正確にリスク評価を実施できる。
    
	**コンテキストデータ収集モジュール例**
    	1. **JavaScript 用モジュール amazon-cognito-advanced-security-data.min.js**  
        Amazon Cognito 用に提供されているこのスクリプトは、ブラウザ上でユーザーのデバイス情報や IP アドレスなどを収集し、EncodedData として生成する。
        2. **iOS 用モジュール AWSCognitoIdentityProviderASF**  
            AWS Mobile SDK for iOS に含まれるモジュールで、ユーザーのコンテキストデータ（デバイスIDやその他の情報）を収集し、エンコードして Cognito への認証リクエストに付与できる。
    	3. **Android 用モジュール aws-android-sdk-cognitoidentityprovider-asf**  
        AWS Android SDK に含まれるモジュールで、ユーザーのデバイス情報やその他のセッション情報を収集し、エンコードして Cognito への API リクエストに渡すために利用する。
    
- **セッション管理・エラーハンドリング**  
    アダプティブ認証で生成されたリスク評価結果に応じたエラー処理や再認証フローを実装する必要がある。
    
## 6. 参考文献

- **Amazon Cognito ユーザープールの高度なセキュリティ機能**
	- https://docs.aws.amazon.com/ja_jp/cognito/latest/developerguide/cognito-user-pool-settings-advanced-security.html
- **AWS CDK の Cognito Advanced Security 設定例**  
	- https://github.com/Imamachi-n/aws-cdk-samples
* **アプリケーションにおける脅威保護のためのデータ収集**
	* https://docs.aws.amazon.com/ja_jp/cognito/latest/developerguide/user-pool-settings-viewing-advanced-security-app.html