Amazon Cognito の Pre Sign-up トリガーでサインアップをメールドメインで制限してみる

記事タイトルとURLをコピーする

はじめに

こんにちは!

アプリケーションサービス本部ディベロップメントサービス1課の森山です。

Amazon Cognito で Auth0 などの外部 IdP と SSO 連携している場合、デフォルトでは外部 IdP で認証されたユーザーが誰でも Cognito にサインアップできてしまいます。

社内ツールや限定公開サービスなど、公開範囲を絞りたいケースでは、特定のメールドメインのユーザーだけにサインアップを制限したい場面があります。

今回は、Cognito のユーザープール Lambda トリガー(preSignUp)を使って、SSO は利用しつつ、サインアップできるユーザをメールアドレスのドメインで制御する方法を紹介します。

この記事で学べること

  • Pre Sign-up トリガーの仕組みと発火タイミング
  • 特定のメールドメインのみサインアップを許可する Lambda 関数の実装
  • CDK での Pre Sign-up トリガーの設定方法

前提知識・条件

  • Amazon Cognito と外部 IdP との連携方法の詳細等は割愛させていただきます

Pre Sign-up トリガーとは

Pre Sign-up トリガーは、Cognito にユーザーが作成される直前に発火する Lambda トリガーです。以下の 3 つのタイミングで呼び出されます。

triggerSource 発火タイミング
PreSignUp_SignUp 通常のメール/パスワードでのサインアップ
PreSignUp_ExternalProvider Auth0 などの外部プロバイダー経由のサインアップ
PreSignUp_AdminCreateUser 管理者によるユーザー作成

docs.aws.amazon.com

各種タイミングで呼び出す Lambda 関数内でエラーをスローすると、サインアップを拒否できます。

やってみた

では、動作確認してみます!

関数の準備

まず、以下の関数を準備します。

export const handler = async (event) => {
  const email = event.request.userAttributes?.email;
  const allowedDomains = ['xxx.com','bbb.co.jp'];
 
  if (email) {
    const domain = email.split('@')[1];
    if (!domain || !allowedDomains.includes(domain)) {
      throw new Error(`Sign-up is not allowed for email domain: ${domain || 'invalid'}`);
    }
  }
 
  return event;
};

サインアップしようとしているユーザーの email 属性のドメイン部分が allowedDomains に含まれていない場合、エラーをスローしてサインアップを拒否します。

なお、allowedDomains は今回サンプルとしてハードコードしていますが、実運用では Lambda の環境変数(process.env.ALLOWED_DOMAINS)で管理するのがおすすめです。

この関数はすべての triggerSource で発火するため、SSO 経由でも通常のサインアップでも同じドメイン制限がかかります。

SSO 経由の場合のみ制限したい場合は、event.triggerSource で分岐させることもできます。

if (event.triggerSource === 'PreSignUp_ExternalProvider') {
  // SSO 経由の時だけドメインチェック
}

Pre Sign-up トリガーの設定

作成した関数をトリガーに指定していきます。

マネジメントコンソールの場合、対象のユーザープールの 拡張機能 から Lambda トリガーを設定できます。

トリガータイプは サインアップ 内、サインアップ前トリガー を選択します。

CDK の場合、以下で実現できます。

    // Pre Sign-up Lambda関数の作成(メールドメイン制限)
    const preSignUpFunction = new lambda.Function(this, 'PreSignUpFunction', {
      runtime: lambda.Runtime.NODEJS_20_X,
      handler: 'index.handler',
      code: lambda.Code.fromAsset(path.join(__dirname, '../lambda/pre-signup')),
      timeout: cdk.Duration.seconds(5),
      description:
        '許可されたメールドメインのみサインアップを許可するPre Sign-up Trigger',
    });
 
    // Cognito User Poolの作成
    const userPool = new cognito.UserPool(this, 'UserPool', {
      userPoolName: 'my-user-pool',
      signInAliases: {
        email: true,
        username: true,
      },
      selfSignUpEnabled: true,
      autoVerify: {
        email: true,
      },
      accountRecovery: cognito.AccountRecovery.EMAIL_ONLY,
      standardAttributes: {
        email: {
          required: true,
        },
      },
      customAttributes: {
        role: new cognito.StringAttribute({ mutable: true }),
      },
      removalPolicy: cdk.RemovalPolicy.DESTROY,
      lambdaTriggers: {
        preSignUp: preSignUpFunction,
      },
    });

動作確認

最後に動作確認してみます。

許可されていないドメインのメールアドレスでサインアップを試みると、以下のようにエラーが返されサインアップが拒否されました。

思ったよりシンプルに実現でき、Lambdaトリガーの便利さに改めて気づきました。

まとめ

Cognito の Pre Sign-up トリガーを使うことで、サインアップ時にメールドメインを検証し、許可されたドメイン以外のユーザーを拒否できました。

外部 IdP と SSO 連携している環境で、意図しないユーザーの流入を防ぎたい場合に有効かと感じましたので紹介しました。

その他 Lambda トリガーは様々なタイミングでコールできるので、柔軟な認証フローの作成ができそうですね。

なお、Pre Sign-up トリガーはあくまでサインアップ時にのみ発火するため、すでに作成済みのユーザーのログインには影響しません。既存ユーザーを制限したい場合は別途対応が必要です。

森山 智史 (記事一覧)

アプリケーションサービス本部ディベロップメントサービス1課

2025年10月中途入社。

AWS Community Builders Serverless 2026