Trying Out Authentication Redundancy from Tokyo to Virginia Using Amazon Cognito Multi-Region Replication

Trying Out Authentication Redundancy from Tokyo to Virginia Using Amazon Cognito Multi-Region Replication

Using Amazon Cognito's multi-Region replication, GA in June 2026, I replicated a Tokyo user pool to Virginia. Covers CLI setup steps, authentication tests in both Regions, and write restrictions on the replica.
2026.06.04

This page has been translated by machine translation. View original

Introduction

Until now, achieving a multi-region setup with Amazon Cognito required custom implementation. Operationally heavy tasks were needed, such as exporting and importing user data, resetting passwords, and handling a different issuer for each region.

On June 3, 2026, the multi-region replication feature of Amazon Cognito became generally available.

Aspect Conventional (custom implementation) Multi-region replication
Data synchronization Self-built export + import Automatic replication
Passwords Depending on the method, resets or migration processing are required Authentication with the same password is possible on the replica side too
issuer Different for each region Unified with Updated Issuer
Client settings Recreated for each region Automatically replicated (* Endpoint changes are required when migrating to Updated Issuer)
Token validation Manage JWKS per region Can be validated with a common JWKS

Details are introduced in the official blog.

https://aws.amazon.com/jp/blogs/aws/improve-your-application-resilience-with-amazon-cognito-multi-region-replication/

In this article, I configure the Tokyo region (ap-northeast-1) as the primary and the Virginia region (us-east-1) as the replica, and verify everything from setup to authentication tests and checking the replica-side restrictions, CLI-based.

Test Environment

Item Value
Primary ap-northeast-1 (Tokyo)
Replica us-east-1 (Virginia)
Tier ESSENTIALS
AWS CLI v2.34.58

The commands in this article use the following variables.

PRIMARY_REGION=ap-northeast-1
REPLICA_REGION=us-east-1
USER_POOL_ID=ap-northeast-1_xxxxxxxxx
CLIENT_ID=xxxxxxxxxxxxxxxxxxxxxxxxxx
KMS_KEY_ID=mrk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Setup

To enable multi-region replication, you need to satisfy the following prerequisites in order.

Note that new APIs such as create-user-pool-replica are available in AWS CLI v2.34.58 and later. Older versions do not recognize the command, so please update beforehand.

  1. Create a KMS multi-region key
  2. Configure the key policy
  3. Create the user pool (specifying the CMK)
  4. Change IssuerConfiguration
  5. Create and activate the replica

Creating a KMS Multi-Region Key

Multi-region replication requires a KMS customer managed key (CMK). Instead of a regular KMS key, create a multi-region key and replicate it to the replica region as well.

# Create a multi-region key in the primary region
aws kms create-key \
  --multi-region \
  --description "Multi-region key for Cognito" \
  --region ${PRIMARY_REGION}
{
    "KeyMetadata": {
        "KeyId": "mrk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
        "MultiRegion": true,
        "MultiRegionConfiguration": {
            "MultiRegionKeyType": "PRIMARY"
        }
    }
}

Replicate the key to the replica region.

aws kms replicate-key \
  --key-id ${KMS_KEY_ID} \
  --replica-region ${REPLICA_REGION} \
  --region ${PRIMARY_REGION}

Configuring the Key Policy

To allow Cognito to use the key, grant permissions to both the cognito-idp.amazonaws.com and identitystore.amazonaws.com services in the key policy. identitystore.amazonaws.com is a service used internally during replication, and is configured following the policy example in the official documentation.

The setting is required on the keys in both regions (primary and replica).

Key policy example (Cognito-related part)
{
    "Sid": "Allow Cognito to use the key",
    "Effect": "Allow",
    "Principal": {
        "Service": [
            "cognito-idp.amazonaws.com",
            "identitystore.amazonaws.com"
        ]
    },
    "Action": [
        "kms:Encrypt",
        "kms:Decrypt",
        "kms:ReEncrypt*",
        "kms:GenerateDataKey*",
        "kms:DescribeKey",
        "kms:CreateGrant"
    ],
    "Resource": "*",
    "Condition": {
        "StringEquals": {
            "aws:SourceAccount": "000000000000"
        }
    }
}

Save the complete key policy including the above policy as a JSON file and apply it to both regions. Keep the existing administrator permissions and add the above statement.

aws kms put-key-policy \
  --key-id ${KMS_KEY_ID} \
  --policy-name default \
  --policy file://key-policy.json \
  --region ${PRIMARY_REGION}

aws kms put-key-policy \
  --key-id ${KMS_KEY_ID} \
  --policy-name default \
  --policy file://key-policy.json \
  --region ${REPLICA_REGION}

Creating the User Pool

Create the UserPool by specifying the CMK with --key-configuration.

aws cognito-idp create-user-pool \
  --pool-name multi-region-test \
  --user-pool-tier ESSENTIALS \
  --key-configuration KeyType=CUSTOMER_MANAGED_KEY,KmsKeyArn=arn:aws:kms:${PRIMARY_REGION}:000000000000:key/${KMS_KEY_ID} \
  --region ${PRIMARY_REGION}
{
    "UserPool": {
        "Id": "ap-northeast-1_xxxxxxxxx",
        "Name": "multi-region-test"
    }
}

Changing IssuerConfiguration

Before replication, switch the OIDC Issuer to the Updated format. The Updated Issuer has the format https://issuer-cognito-idp.[region].amazonaws.com/[userPoolId]. In this configuration, even when authenticating in the replica region, iss was the issuer of the primary, ap-northeast-1. Therefore, whether you authenticate in Tokyo or Virginia, tokens can be validated assuming the same issuer / JWKS.

aws cognito-idp update-user-pool \
  --user-pool-id ${USER_POOL_ID} \
  --issuer-configuration Type=UPDATED \
  --key-configuration KeyType=CUSTOMER_MANAGED_KEY,KmsKeyArn=arn:aws:kms:${PRIMARY_REGION}:000000000000:key/${KMS_KEY_ID} \
  --region ${PRIMARY_REGION}

Creating the Replica

With the prerequisites satisfied, create the replica.

aws cognito-idp create-user-pool-replica \
  --user-pool-id ${USER_POOL_ID} \
  --region-name ${REPLICA_REGION} \
  --region ${PRIMARY_REGION}
{
    "UserPoolReplica": {
        "RegionName": "us-east-1",
        "Status": "CREATING",
        "Role": "SECONDARY"
    }
}

Activating the Replica

The replica first transitions from CREATING to INACTIVE. Once it becomes INACTIVE, manually switch it to ACTIVE.

# Check status (wait for CREATING → INACTIVE. About 2 minutes)
aws cognito-idp list-user-pool-replicas \
  --user-pool-id ${USER_POOL_ID} \
  --region ${PRIMARY_REGION}
{
    "UserPoolReplicas": [
        {
            "RegionName": "us-east-1",
            "Status": "INACTIVE",
            "Role": "SECONDARY"
        },
        {
            "RegionName": "ap-northeast-1",
            "Status": "ACTIVE",
            "Role": "PRIMARY"
        }
    ]
}
# Enable the replica
aws cognito-idp update-user-pool-replica \
  --user-pool-id ${USER_POOL_ID} \
  --region-name ${REPLICA_REGION} \
  --status ACTIVE \
  --region ${PRIMARY_REGION}

This completes the setup. Users and client settings created in the primary (Tokyo) are automatically synchronized to the replica (Virginia).

Authentication Test

I verified whether a user created in the primary (Tokyo) can also authenticate from the replica (Virginia).

Preparing the Test User

Create an app client and a test user in the primary region.

# Create app client
aws cognito-idp create-user-pool-client \
  --user-pool-id ${USER_POOL_ID} \
  --client-name test-client \
  --explicit-auth-flows ALLOW_USER_PASSWORD_AUTH ALLOW_REFRESH_TOKEN_AUTH \
  --region ${PRIMARY_REGION}
{
    "UserPoolClient": {
        "ClientId": "xxxxxxxxxxxxxxxxxxxxxxxxxx",
        "ClientName": "test-client"
    }
}

From here on, this ClientId is used as CLIENT_ID.

# Create test user
aws cognito-idp admin-create-user \
  --user-pool-id ${USER_POOL_ID} \
  --username testuser01 \
  --temporary-password 'TempPass1!' \
  --message-action SUPPRESS \
  --region ${PRIMARY_REGION}

# Confirm the password
aws cognito-idp admin-set-user-password \
  --user-pool-id ${USER_POOL_ID} \
  --username testuser01 \
  --password 'TestPass123!' \
  --permanent \
  --region ${PRIMARY_REGION}

Even after setting the replica to ACTIVE, it may take several tens of seconds for users and clients to be reflected. I confirmed with admin-get-user that the user was visible on the replica side before proceeding to the authentication test.

Authentication on the Primary (Tokyo)

aws cognito-idp initiate-auth \
  --auth-flow USER_PASSWORD_AUTH \
  --client-id ${CLIENT_ID} \
  --auth-parameters USERNAME=testuser01,PASSWORD='TestPass123!' \
  --region ${PRIMARY_REGION}

It succeeded.

Authentication on the Replica (Virginia)

aws cognito-idp initiate-auth \
  --auth-flow USER_PASSWORD_AUTH \
  --client-id ${CLIENT_ID} \
  --auth-parameters USERNAME=testuser01,PASSWORD='TestPass123!' \
  --region ${REPLICA_REGION}

This also succeeded.

Token Comparison

I compared the main claims of the tokens obtained in both regions.

ID token:

claim Tokyo (Primary) Virginia (Replica)
iss https://issuer-cognito-idp.ap-northeast-1.amazonaws.com/ap-northeast-1_xxxxxxxxx Same
sub a7445a18-xxxx-xxxx-xxxx-xxxxxxxxxxxx Same
aud xxxxxxxxxxxxxxxxxxxxxxxxxx Same

Access token:

claim Tokyo (Primary) Virginia (Replica)
iss https://issuer-cognito-idp.ap-northeast-1.amazonaws.com/ap-northeast-1_xxxxxxxxx Same
sub a7445a18-xxxx-xxxx-xxxx-xxxxxxxxxxxx Same
client_id xxxxxxxxxxxxxxxxxxxxxxxxxx Same

iss, sub, and aud (client_id) match in both regions. iat, exp, and jti differ depending on the authentication timing, but since the claims referenced in token validation are identical, there is no need to branch the token validation logic per region.

However, when switching an existing pool to Updated Issuer, the issuer / JWKS endpoint settings on the application side must be updated separately.

Replica Write Restrictions

The user pool in the replica region is a read-only endpoint primarily intended for authentication and user data lookup. I checked how write operations are rejected.

Verification Results

Operation API Result
Create user AdminCreateUser ❌ Rejected
Self sign-up SignUp ❌ Rejected
Set password (Admin) AdminSetUserPassword ❌ Rejected
Change password (User) ChangePassword ❌ Rejected
Password reset ForgotPassword ❌ Rejected
Update attributes AdminUpdateUserAttributes ❌ Rejected
Get user AdminGetUser ✅ Succeeded

All the write operations I tried were rejected with the same error.

An error occurred (OperationNotEnabledException) when calling the AdminCreateUser operation:
This operation is not enabled in this region for this User Pool

Whether it is an Admin API or a user-facing API, the error type is consistently OperationNotEnabledException, and the message is "This operation is not enabled in this region for this User Pool". ChangePassword using a valid access token issued by the replica was also rejected in the same way.

Commands and output for each operation

Create user:

aws cognito-idp admin-create-user \
  --user-pool-id ${USER_POOL_ID} \
  --username testuser02 \
  --temporary-password 'TempPass1!' \
  --message-action SUPPRESS \
  --region ${REPLICA_REGION}
# → OperationNotEnabledException

Self sign-up:

aws cognito-idp sign-up \
  --client-id ${CLIENT_ID} \
  --username testuser03 \
  --password 'TestPass123!' \
  --region ${REPLICA_REGION}
# → OperationNotEnabledException

Set password:

aws cognito-idp admin-set-user-password \
  --user-pool-id ${USER_POOL_ID} \
  --username testuser01 \
  --password 'NewPass456!' \
  --permanent \
  --region ${REPLICA_REGION}
# → OperationNotEnabledException

Change password (user operation):

aws cognito-idp change-password \
  --previous-password 'TestPass123!' \
  --proposed-password 'NewPass789!' \
  --access-token '<レプリカで取得した有効なアクセストークン>' \
  --region ${REPLICA_REGION}
# → OperationNotEnabledException

Password reset:

aws cognito-idp forgot-password \
  --client-id ${CLIENT_ID} \
  --username testuser01 \
  --region ${REPLICA_REGION}
# → OperationNotEnabledException

Update attributes:

aws cognito-idp admin-update-user-attributes \
  --user-pool-id ${USER_POOL_ID} \
  --username testuser01 \
  --user-attributes Name=email,Value=test@example.com \
  --region ${REPLICA_REGION}
# → OperationNotEnabledException

Get user (success):

aws cognito-idp admin-get-user \
  --user-pool-id ${USER_POOL_ID} \
  --username testuser01 \
  --region ${REPLICA_REGION}
# → User information is returned successfully

As an application design, possible approaches are to handle this error type and route write operations to the primary region, or to separate the authentication endpoint and the write endpoint from the start.

Checking the Replica Limit

I verified whether replicas in multiple regions can be added to a single user pool. I attempt to add a third region to another pool (with us-west-2 as the primary) that already has a replica in Virginia (us-east-1).

aws cognito-idp create-user-pool-replica \
  --user-pool-id us-west-2_xxxxxxxxx \
  --region-name ap-northeast-1 \
  --region us-west-2
An error occurred (LimitExceededException) when calling the CreateUserPoolReplica operation:
User pool has reached the maximum allowed number of replicas

It was rejected with LimitExceededException. The limit is one replica per pool. In other words, a two-region configuration of primary + replica is the maximum.

If you want to distribute authentication across three or more regions, a different design, such as a separate-pool configuration, is required. Note that the same KMS multi-region key can be shared across multiple pools.

Cost Estimate

Multi-region replication incurs add-on charges in addition to the base Cognito charges. Below is an estimate based on the published pricing as of June 2026.

Assumptions:

  • Cognito Essentials tier, one replica region
  • KMS multi-region keys for 2 regions (primary + replica)
  • Free Tier (10,000 MAU) applied to the base Cognito charges
  • There is no Free Tier for the MRR (Multi-Region Replication) add-on
  • KMS includes only the monthly key fee (API request charges excluded)
  • SMS, email sending, and Advanced Security charges are not included
MAU Cognito base MRR add-on KMS (2 regions) Monthly estimate
1,000 $0 (Free Tier) ~$5 ~$2 ~$7
10,000 $0 (after Free Tier) ~$45 ~$2 ~$47
100,000 ~$1,350 (after Free Tier deduction) ~$450 ~$2 ~$1,802

Unit prices used for calculation: Cognito Essentials $0.015/MAU, MRR add-on $0.0045/MAU/replica region, KMS $1/key/region/month.

For pricing details, see the Amazon Cognito pricing page and the AWS KMS pricing page.

Notes

  • Switching to Updated Issuer is a breaking change for existing apps. The official blog explicitly states "requests to the old endpoints will no longer be routed correctly". Applications that validate the issuer against a fixed value need their endpoints updated beforehand
  • TOTP MFA is not supported on the secondary replica. Users with MFA configured can authenticate only on the primary
  • Password authentication failure counts are asynchronous between regions, so lockout thresholds for brute-force protection are evaluated independently in each region
  • Only pools on the "next-generation infrastructure" are supported. Older existing pools will become available after AWS completes their migration
  • To automate failover, you need to design custom domains and DNS routing. In configurations that call the API directly, you need to implement switching of the target region on the application side

Summary

With Amazon Cognito multi-region replication, I confirmed that a user pool in the Tokyo region can be replicated to the Virginia region and that authentication works in both regions. By using a KMS multi-region key and Updated Issuer, you can assume the same client ID and issuer / JWKS, and there is no need to split token validation logic per region.

However, the replica is read-only, so user registration, password changes, attribute updates, and the like must be routed to the primary. Also, since only one replica is allowed per pool, a separate-pool configuration or similar needs to be considered for three or more regions.

For existing apps, be aware that switching to Updated Issuer is a breaking change; for new builds, addressing it before production use will make it easier to prepare for future multi-region expansion.

Share this article

AWSのお困り事はクラスメソッドへ