1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Amazon Cognito × AWS PrivateLink を実戦投入するための設計方法

Last updated at Posted at 2025-11-22

はじめに

ようやくです。待望の機能がリリースされました!

Amazon Cognito User Pools が AWS PrivateLinkでのプライベート接続をサポート。
これまで、VPC 内のリソースから Cognito を利用した認証を行う場合、パブリックインターネット経由のアクセスが前提でしたが、今回のアップデートにより、VPC からの Cognito 認証・管理をインターネットを経由せずに実現できるようになりました、というアナウンスがありました。

実際の画面ではエンドポイントの作成時に、Interface型のCognitoサービスが選択できるようになっています。
image.png

何がかわったか?

これで、インターネットアクセスは不要になる!?と思ったのですが、あらためてちゃんと見ていきましょう。

Cognito User Pools のエンドポイントへ Interface VPC Endpoint(AWS PrivateLink)で接続できるようになりました。これにより、バックエンドからの管理操作やローカルユーザーのサインイン処理をパブリックインターネットを経由せずに実行可能です。ただし、ホステッド UI(ブラウザでの OAuth 認可コードフロー)やクライアント資格情報フロー、外部 IdP を使ったフェデレーションは PrivateLink 経由ではサポートされないため、ブラウザ側の通常ログインフローは従来どおりパブリック経路が必要です

AWS公式 What's New の内容を要約すると、ざっくり以下のようになります。
VPC内のECS/EKS/Lambda/EC2などのバックエンドからCognitoの管理や一部認証処理をインターネットを経由せずに実現できる、と。

一方で、次のようなブラウザ中心の認証フローは PrivateLink 経由にならないと書いてありました。

  • Hosted UI を使った OAuth 2.0 Authorization Code フロー
  • OAuth の Client Credentials フロー(トークンエンドポイント)
  • 外部 IdP(Azure AD / Okta など)との SAML / OIDC フェデレーション

ここを誤解すると「全部閉域にできるはず」と期待して設計してしまいそうです。

具体的なシナリオ①

やりたいこと

  • 社内業務システム(ブラウザでアクセス)
  • アクセス経路は閉域網( VPN / Direct Connect 経由)のみ
  • ポリシーとして「ブラウザからインターネットに出さない」
  • 認証は Cognito Hosted UI(+ Azure AD などの外部 IdP)で統合管理したい

実際に起きること

  • Hosted UI の /oauth2/authorize / /oauth2/token にブラウザから到達する必要がある
  • これらは PrivateLink の対象外 であり、最終的にはパブリックな Cognito のエンドポイントに到達する必要がある

結果

  • 社内ブラウザがインターネットに出られない環境(もしくは閉域網のみの要件)では、Hosted UI にそもそもアクセスできない
  • プロキシやファイアウォールでドメイン単位の例外許可が必要になり、「完全閉域」という要件は満たせなくなる

具体的なシナリオ②

やりたいこと

  • ブラウザ → 業務アプリ
  • 業務アプリ → Cognito Hosted UI
  • Cognito → Azure AD / Okta 等の外部 IdP(SAML / OIDC)
  • IdP 認証後、再び Cognito から アプリにトークンを返す

実際に起きること

  • Cognito Hosted UI も Azure AD / Okta もインターネット上のサービス
  • PrivateLink は「VPC → Cognito API」の閉域化であり、以下の通信はインターネット経由となる
    • ブラウザ → Cognito Hosted UI
    • Cognito Hosted UI → 外部 IdP

結果

  • 「フェデレーションを含め、認証関連トラフィックをすべて閉域に」という要件には合わない
  • ネットワーク/セキュリティ側と「どのドメインをどこまで許可するか」の調整や設計が必要となる

ではどう設計すべきかなのでしょう?

バックエンドだけ閉域化

  • バックエンド(ECS/EKS/Lambda/EC2)は Interface VPC Endpoint 経由で Cognito API を叩く。これは今回の新機能で対応が可能です
    • ユーザー管理、トークン検証、管理者操作など
  • ブラウザからの認証フロー(Hosted UI / フェデレーション)は従来どおりインターネット経由として、以下の対策を行いながら対応する
    • Cognito Custom Domain
    • AWS WAF
    • CloudFront 経由
    • IP 制限や各種シグナルを用いた防御 など

これは「バックエンドの閉域化」と「ブラウザ/外部 IdP のパブリック前提」を切り分けた設計となります。

認証方式そのものを変える

  • 要件として「どうしても閉域完結が必要」で、ブラウザのインターネット接続も認められない場合は以下の方法が考えられます
    • Hosted UI や標準 OAuth フローを前提にするのをやめる
    • Cognito Admin API(AdminInitiateAuth など)を用いた 自前のログイン API を構成する

ただし、これはアプリケーション側の実装・責務が重くなり、保守性とリスクを増やすため、要件とコストを慎重に比較する必要があるといえます。

実装編

CloudFormation による Interface VPC Endpoint 作成をやってみましょう。

前提となる既存リソース

  • VPC
  • マルチ AZ のサブネット
  • エンドポイント用のセキュリティグループ(HTTPS を許可)

CloudFormationサンプルテンプレート

AWSTemplateFormatVersion: '2010-09-09'
Description: >
  Create an Interface VPC Endpoint (AWS PrivateLink) for Amazon Cognito User Pools (cognito-idp).

Parameters:
  VpcId:
    Type: AWS::EC2::VPC::Id
    Description: VPC ID where the interface endpoint will be created.

  SubnetIds:
    Type: List<AWS::EC2::Subnet::Id>
    Description: Subnets (in different AZs) for the interface endpoint ENIs.

  SecurityGroupIds:
    Type: List<AWS::EC2::SecurityGroup::Id>
    Description: Security Group(s) to attach to the endpoint ENIs.

Resources:
  CognitoVpcEndpoint:
    Type: AWS::EC2::VPCEndpoint
    Properties:
      VpcId: !Ref VpcId
      ServiceName: !Sub "com.amazonaws.${AWS::Region}.cognito-idp"
      VpcEndpointType: Interface
      SubnetIds: !Ref SubnetIds
      SecurityGroupIds: !Ref SecurityGroupIds
      PrivateDnsEnabled: true
      PolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: "Allow"
            Principal: "*"
            Action:
              - "cognito-idp:AdminCreateUser"
              - "cognito-idp:AdminGetUser"
              - "cognito-idp:AdminInitiateAuth"
              - "cognito-idp:AdminRespondToAuthChallenge"
              - "cognito-idp:ListUserPools"
              - "cognito-idp:DescribeUserPool"
              - "cognito-idp:ListUsers"
            Resource: "*"

Outputs:
  VpcEndpointId:
    Description: VPC Endpoint ID for Cognito (PrivateLink)
    Value: !Ref CognitoVpcEndpoint

  VpcEndpointDnsEntries:
    Description: DNS entries for the endpoint
    Value: !Join [", ", !GetAtt CognitoVpcEndpoint.DnsEntries]

サンプルテンプレートの解説

  • Parameters:セクション
    スタック作成時に外から与える値の定義です。
    • VpcId
      エンドポイントを作成する対象VPCを指定します
    • SubnetIds
      1つ以上のサブネットIDを指定します
      複数 AZ にまたがるサブネットを指定することで、可用性を確保できます
    • SecurityGroupIds
      エンドポイントENIにアタッチするセキュリティグループのIDを指定します
  • Resources:セクション
    生成するリソースのプロパティです。
    • Properties
      • VpcId: !Ref VpcId
      • ServiceName: !Sub "com.amazonaws.${AWS::Region}.cognito-idp"
      • VpcEndpointType: Interface
      • SubnetIds: !Ref SubnetIds
      • SecurityGroupIds: !Ref SecurityGroupIds
      • PrivateDnsEnabled: true
    • PolicyDocument
      VPC エンドポイントポリシー(このエンドポイント経由で、どの API を誰に許可するか)を定義します。
      • Principal: "*"
        だれでも(任意の IAM プリンシパル)このエンドポイント経由でアクセス可能
        通常はアカウントやロールに絞り込む必要あり
      • Action
        このエンドポイントを経由して許可されている Cognito API アクションの一覧
      • Resource: "*"
        すべての Cognito リソース(全ユーザープール)が対象
        実運用では特定のユーザープール ARN に絞る必要あり
  • Outputs:セクション
    スタック作成後にコンソールや describe-stacks で参照できる出力です。
    • VpcEndpointId
      作成した VPC Endpoint の ID
    • VpcEndpointDnsEntries
      !GetAtt CognitoVpcEndpoint.DnsEntriesでエンドポイントに紐づく DNS 名(リージョナルエイリアスや ENI の FQDN 等)のリストが取得

コスト

インターフェイスエンドポイントの料金は、時間課金+データ処理課金となります。
東京リージョンの場合、
時間課金 $0.014/h
処理課金 1PBまで$0.01/GB

単価は 2025年11月時点のものです。最新情報は公式料金ページを確認してください。

まとめ

Cognito User Pools の PrivateLink 対応は、「バックエンドからの Cognito API 呼び出しを閉域化する」 ためには非常に有効といえます。

ただ一方で、Hosted UI をはじめてとして、外部 IdP(SAML / OIDC)とのフェデレーションは PrivateLink の対象外であり、認証フロー全体の完全閉域化の手段とはならないことがわかりました。

したがって設計上は、バックエンドの管理処理・トークン検証を PrivateLink で実現してセキュリティとネットワーク制御を強化しつつ、ブラウザ側や外部 IdP との経路はパブリック前提で WAF 等で防御という役割を考慮した設計が重要となります。

同じように「一部だけ PrivateLink で閉じられる」サービスは他にもあるので、「どのトラフィックが閉じられて、どこがパブリック前提なのか」 を意識して設計しておくとよいかと思います。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?