API Gateway × Cognito × IAM認証 完全ガイド 2025年版
なぜ今でもこのパターンが有効なのか
AWS のAPI実装において、認証・認可の設計は最も重要な検討事項の一つです。2025年1月現在、AWSの公式ドキュメントでも明記されているように、Cognito User Poolで認証し、Identity PoolでSTS資格情報を取得してAPI GatewayをIAM認可で呼び出すパターンは、依然として推奨される実装方式として健在です。
このアプローチが長年支持される理由は、その「本質的な価値」にあります。単一の認証情報で複数のAWSサービス(S3、DynamoDB、API Gateway等)へアクセスできる統一性と、IAMロールによる細かい権限制御の組み合わせは、エンタープライズレベルのセキュリティ要件を満たすうえで極めて有効です。
2025年における選択肢の整理
REST API vs HTTP API - 適材適所の選択
現在のAPI Gateway実装では、大きく分けて2つの選択肢があります。それぞれの特徴を理解し、要件に応じて選択することが重要です。
REST API + IAM認証(本記事のメインパターン)
REST APIとIAM認証の組み合わせは、AWSリソース全体で統一されたセキュリティモデルを実現したい場合に最適です。特に、API Gatewayのリソースポリシーを活用できる点は大きなメリットです。特定のIPアドレスやVPCエンドポイントからのアクセスのみを許可するなど、多層防御を実現できます。
HTTP API + JWTオーソライザー
HTTP APIのJWTオーソライザーは、よりシンプルなAPIセキュリティを求める場合に適しています。Cognito User PoolのトークンやOIDCプロバイダーのJWTを直接検証でき、スコープベースのアクセス制御が簡潔に実装できます。新規プロダクトで純粋なAPIクライアント間通信を想定している場合、こちらを第一候補として検討する価値があります。
認証フローの最新アップデート
Cognitoのマネージドログインが整備され、従来のHosted UIから進化しました。特に注目すべきは、2024年に発表されたパスキーサポートです。FIDO2準拠のパスキーによるパスワードレス認証が可能になり、ユーザビリティとセキュリティの両立が実現できるようになりました。
ただし、パスキー機能の利用にはCognito Liteプラン以上が必要である点には注意が必要です。プロジェクトの予算とセキュリティ要件のバランスを考慮した選択が求められます。
実装アーキテクチャの詳細解説
全体的なワークフロー
Cognito User PoolとIdentity Poolを組み合わせたAWSサービスアクセスの全体像
実装するワークフローは以下の3ステップから構成されます。
- Cognito User Poolで認証トークン(IDトークン)を取得
- Cognito Identity PoolにIDトークンを渡し、STS一時認証情報を取得
- STS認証情報を使用してSigV4署名を生成し、API Gatewayへリクエスト
このフローの中核にあるのは「IAMロール」です。各ユーザーが適切な権限を持つIAMロールの認証情報を取得することで、きめ細かいアクセス制御を実現します。
IAMロールの設計と実装
IAMロールの設計は、このアーキテクチャの要となる部分です。2025年現在もAWSのベストプラクティスに従い、最小権限の原則を徹底することが重要です。
以下は管理者向けと従業員向けのIAMロール定義例です。
# 管理者向けロール
AuthenticatedAdminRole:
Type: AWS::IAM::Role
Properties:
RoleName: "example-cognito-apigateway-AuthenticatedAdminRole"
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Action: sts:AssumeRoleWithWebIdentity
Effect: Allow
Principal:
Federated: cognito-identity.amazonaws.com
Condition:
StringEquals:
cognito-identity.amazonaws.com:aud: !Ref CognitoIDPool
ForAnyValue:StringLike:
cognito-identity.amazonaws.com:amr: authenticated
Policies:
- PolicyName: "admin-api-access-policy"
PolicyDocument:
Version: "2012-10-17"
Statement:
- Sid: APIGatewayAdminAccess
Effect: Allow
Action:
- execute-api:Invoke
Resource:
- !Sub arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${ApiGatewayRestApi}/${Stage}/GET/admin/*
- !Sub arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${ApiGatewayRestApi}/${Stage}/POST/admin/*
- !Sub arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${ApiGatewayRestApi}/${Stage}/PUT/admin/*
- !Sub arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${ApiGatewayRestApi}/${Stage}/DELETE/admin/*
# 従業員向けロール
AuthenticatedStaffRole:
Type: AWS::IAM::Role
Properties:
RoleName: "example-cognito-apigateway-AuthenticatedStaffRole"
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Action: sts:AssumeRoleWithWebIdentity
Effect: Allow
Principal:
Federated: cognito-identity.amazonaws.com
Condition:
StringEquals:
cognito-identity.amazonaws.com:aud: !Ref CognitoIDPool
ForAnyValue:StringLike:
cognito-identity.amazonaws.com:amr: authenticated
Policies:
- PolicyName: "staff-api-access-policy"
PolicyDocument:
Version: "2012-10-17"
Statement:
- Sid: APIGatewayStaffAccess
Effect: Allow
Action:
- execute-api:Invoke
Resource:
- !Sub arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${ApiGatewayRestApi}/${Stage}/GET/staff/*
注目すべき点は、信頼ポリシー(AssumeRolePolicyDocument)の条件設定です。cognito-identity.amazonaws.com:aud
でIdentity Pool IDを指定し、cognito-identity.amazonaws.com:amr
で認証済みユーザーのみを許可しています。これはAWSの公式ドキュメントでも推奨される設定パターンです。
Cognito User Poolグループの活用
Cognito User Poolのグループ機能は、ユーザーとIAMロールのマッピングを実現する重要な要素です。各グループにIAMロールを紐付けることで、認証トークンにcognito:roles
とcognito:preferred_role
のクレームが含まれるようになります。
UserPoolAdministratorGroup:
Type: AWS::Cognito::UserPoolGroup
Properties:
Description: "管理者グループ"
GroupName: Admin
Precedence: 1
UserPoolId: !Ref CognitoUserPool
RoleArn: !GetAtt AuthenticatedAdminRole.Arn
UserPoolStaffGroup:
Type: AWS::Cognito::UserPoolGroup
Properties:
Description: "従業員グループ"
GroupName: Staff
Precedence: 2
UserPoolId: !Ref CognitoUserPool
RoleArn: !GetAtt AuthenticatedStaffRole.Arn
Precedenceの値は、ユーザーが複数のグループに所属している場合の優先順位を決定します。値が小さいほど優先度が高く、cognito:preferred_role
として選択されます。
Identity PoolのRoleMappings設定の重要性
Identity Poolの設定で最も重要なのは、RoleMappingsのType設定です。Type: Token
を指定することで、IDトークンに含まれるcognito:roles
とcognito:preferred_role
クレームを自動的に解釈し、適切なIAMロールを選択します。
IdentityPoolRoleAttachment:
Type: AWS::Cognito::IdentityPoolRoleAttachment
Properties:
IdentityPoolId: !Ref CognitoIDPool
Roles:
"authenticated": !GetAtt CognitoIdentityPoolAuthenticatedRole.Arn
RoleMappings:
CognitoUserPool:
AmbiguousRoleResolution: AuthenticatedRole
IdentityProvider: !Sub cognito-idp.${AWS::Region}.amazonaws.com/${CognitoUserPool}:${CognitoUserPoolClient}
Type: Token # ここが重要!
Type: Token
の設定により、完全にサーバーレスな環境でユーザーグループに基づいたIAMロールの自動割り当てが実現できます。これは、Lambda関数などでカスタムロジックを実装することなく、AWS管理のサービスのみで認可を実現できる優れたアプローチです。
API Gatewayのセキュリティ強化
リソースポリシーによる多層防御
REST APIの大きな利点の一つは、リソースポリシーを設定できることです。IAM認証と組み合わせることで、多層防御を実現できます。
ApiGatewayResourcePolicy:
Type: AWS::ApiGateway::RestApi
Properties:
Policy:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal: '*'
Action: 'execute-api:Invoke'
Resource: 'execute-api:/*'
Condition:
IpAddress:
aws:SourceIp:
- '10.0.0.0/8' # 社内ネットワーク
- '172.16.0.0/12' # VPC内部
- Effect: Deny
Principal: '*'
Action: 'execute-api:Invoke'
Resource: 'execute-api:/*'
Condition:
IpAddress:
aws:SourceIp:
- '192.168.1.100' # 特定のブロックIP
リソースポリシーは、IAM認証の前段階で適用されるため、不正なアクセスを早期に遮断できます。ただし、HTTP APIではリソースポリシーがサポートされていないため、この機能が必要な場合はREST APIを選択する必要があります。
TLS 1.3によるセキュリティ強化
2024年2月にAPI GatewayがTLS 1.3をサポートしたことで、より高速で安全な通信が可能になりました。既存のAPIでもTLS 1.3を有効にすることで、セキュリティとパフォーマンスの両面で改善が期待できます。
Lambda統合時の実装上の注意点
IAM認証時のコンテキスト情報
IAM認証を使用した場合、Lambda関数で取得できる情報には制限があります。公式ドキュメントによると、JWTトークンの内容は直接取得できませんが、$context.identity
変数を通じて以下の情報にアクセスできます。
interface APIGatewayRequestContext {
identity: {
cognitoIdentityPoolId: string;
accountId: string;
cognitoIdentityId: string;
caller: string;
sourceIp: string;
principalOrgId: string;
accessKey: string;
cognitoAuthenticationType: "authenticated";
cognitoAuthenticationProvider: string; // ここにUser PoolのsubIDが含まれる
userArn: string;
userAgent: string;
user: string;
};
}
特に重要なのはcognitoAuthenticationProvider
フィールドです。このフィールドにはcognito-idp.{region}.amazonaws.com/{userPoolId}:CognitoSignIn:{sub}
という形式で情報が格納され、ユーザーのsubIDを取得できます。
// Lambda関数でのユーザー特定例
export const handler = async (event: APIGatewayProxyEvent): Promise<APIGatewayProxyResult> => {
const authProvider = event.requestContext.identity?.cognitoAuthenticationProvider;
if (authProvider) {
// cognitoAuthenticationProviderからsubを抽出
const subMatch = authProvider.match(/:CognitoSignIn:(.+)$/);
const userSub = subMatch ? subMatch[1] : null;
if (userSub) {
// userSubを使用してユーザー固有の処理を実行
console.log(`User Sub: ${userSub}`);
}
}
return {
statusCode: 200,
body: JSON.stringify({ message: "Success" })
};
};
ユーザー属性が必要な場合の対処法
IAM認証では詳細なユーザー属性(メールアドレス、カスタム属性など)を取得できないため、これらの情報が必要な場合は以下の選択肢を検討する必要があります。
以下の方法でユーザー属性を取得できます。
- Lambda内でCognito User PoolのAdminGetUserAPIを呼び出す
- DynamoDBなどの外部データストアにユーザー情報をキャッシュする
- HTTP API + JWTオーソライザーに切り替える(JWTトークンから直接属性を取得可能)
実装時のベストプラクティス
最小権限の原則の徹底
IAMポリシーのResource指定では、ワイルドカードの使用を最小限に抑えることが重要です。以下は推奨される段階的なアプローチです。
# BAD: 過度に広範な権限
Resource:
- !Sub arn:aws:execute-api:*:*:*/*/*
# BETTER: API IDとステージを特定
Resource:
- !Sub arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${ApiGatewayRestApi}/${Stage}/*
# BEST: メソッドとパスも特定
Resource:
- !Sub arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${ApiGatewayRestApi}/${Stage}/GET/admin/users
- !Sub arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${ApiGatewayRestApi}/${Stage}/POST/admin/users
Identity Poolロールの適切な設定
Identity Pool用のロールには、必要最小限の権限のみを付与します。よくある誤りは、cognito-identity:*
のような広範な権限を付与してしまうことです。
# 推奨される最小権限の設定
CognitoIdentityPoolAuthenticatedRole:
Type: AWS::IAM::Role
Properties:
Policies:
- PolicyName: "minimal-cognito-access"
PolicyDocument:
Version: "2012-10-17"
Statement:
- Sid: MinimalCognitoAccess
Effect: Allow
Action:
- cognito-identity:GetCredentialsForIdentity
- cognito-identity:GetId
Resource: !Sub arn:aws:cognito-identity:${AWS::Region}:${AWS::AccountId}:identitypool/${CognitoIDPool}
エラーハンドリングとモニタリング
API Gatewayの認証エラーは、適切にログ記録し、モニタリングすることが重要です。CloudWatch Logsと連携し、認証失敗パターンを分析できるようにしましょう。
ApiGatewayLogGroup:
Type: AWS::Logs::LogGroup
Properties:
LogGroupName: !Sub /aws/apigateway/${ApiGatewayRestApi}
RetentionInDays: 30
ApiGatewayAccountConfig:
Type: AWS::ApiGateway::Account
Properties:
CloudWatchRoleArn: !GetAtt ApiGatewayCloudWatchRole.Arn
ApiGatewayDeployment:
Type: AWS::ApiGateway::Deployment
Properties:
RestApiId: !Ref ApiGatewayRestApi
StageName: !Ref Stage
StageDescription:
AccessLogSetting:
DestinationArn: !GetAtt ApiGatewayLogGroup.Arn
Format: '$context.requestId $context.identity.sourceIp $context.identity.userArn $context.requestTime $context.httpMethod $context.routeKey $context.status $context.error.message $context.error.messageString'
MethodSettings:
- ResourcePath: '/*'
HttpMethod: '*'
LoggingLevel: INFO
DataTraceEnabled: true
MetricsEnabled: true
2025年における選択判断フロー
プロジェクトに最適な認証方式を選択するため、以下の判断基準を参考にしてください。
REST API + IAM認証を選ぶべきケース
以下の要件がある場合は、REST API + IAM認証が適しています。
- AWS内の複数サービス(S3、DynamoDB等)で統一された認証を使いたい
- リソースポリシーによるIP制限やVPCエンドポイント制限が必要
- 既存のAWSインフラと密接に統合したい
- 細かいIAMロールベースの権限管理が必要
HTTP API + JWTオーソライザーを選ぶべきケース
以下の要件がある場合は、HTTP API + JWTオーソライザーが適しています。
- シンプルなスコープベースの認可で十分
- レイテンシを最小化したい(HTTP APIは一般的に高速)
- コスト最適化を重視(HTTP APIは料金が安い)
- 外部のOIDCプロバイダーと連携したい
ハイブリッドアプローチの検討
実際のプロジェクトでは、両方のアプローチを組み合わせることも有効です。例えば、パブリックAPIはHTTP API + JWTオーソライザーで実装し、管理APIはREST API + IAM認証で実装するという使い分けが考えられます。
トラブルシューティングガイド
よくある実装ミス
実装時によく遭遇する問題と、その解決方法をまとめました。
RoleMappingsのType設定ミス
Type: Token
をType: Rules
と間違えると、グループベースのロール自動割り当てが機能しません。必ずType: Token
を指定し、AmbiguousRoleResolution
も適切に設定してください。
信頼ポリシーの条件設定漏れ
IAMロールの信頼ポリシーで、Identity Pool IDの条件チェックを忘れると、セキュリティホールになる可能性があります。必ずcognito-identity.amazonaws.com:aud
でIdentity Pool IDを検証してください。
API実行権限のResource指定ミス
execute-api:Invoke
のResourceで、ステージやメソッドの指定を間違えると、403エラーが発生します。ARN形式を正確に記述することが重要です。
デバッグ手法
問題の切り分けには、以下のアプローチが有効です。
- CloudWatch Logsで認証フローの各段階をトレース
- AWS CLIでSTS AssumeRoleWithWebIdentityを直接実行して検証
- API GatewayのテストコンソールでIAM認証をシミュレート
まとめと今後の展望
2025年現在でも、Cognito User Pool、Identity Pool、IAM認証を組み合わせたAPI Gatewayの認証パターンは、その堅牢性と柔軟性から有効な選択肢です。特に、AWSエコシステム全体で統一されたセキュリティモデルを構築したい場合には、このアプローチが最適解となることが多いでしょう。
一方で、HTTP API + JWTオーソライザーという新しい選択肢も成熟し、よりシンプルなユースケースでは第一選択となる場合も増えています。プロジェクトの要件を正確に把握し、適切な技術選択を行うことが、成功への鍵となります。
今後は、パスキー認証やマネージドログインのさらなる進化により、よりユーザーフレンドリーかつセキュアな認証体験が実現されることが期待されます。技術の進化を見据えながら、現時点でのベストプラクティスを実装していくことが、持続可能なシステム構築につながるのではないでしょうか。