I tried Amazon Cognito multi-region replication to test authentication redundancy from Tokyo to Virginia
This page has been translated by machine translation. View original
Introduction
Amazon Cognito previously required custom implementations to achieve multi-region configurations. This involved high operational overhead, including exporting and importing user data, resetting passwords, and handling different issuers per region.
On June 3, 2026, Amazon Cognito's multi-region replication feature became generally available.
| Aspect | Before (Custom Implementation) | Multi-Region Replication |
|---|---|---|
| Data sync | Custom export + import implementation | Automatic replication |
| Passwords | Reset or migration processing required depending on the approach | Authentication with the same password possible on the replica side |
| Issuer | Different per region | Unified with Updated Issuer |
| Client settings | Recreated per region | Automatically replicated (※ endpoint change required when migrating to Updated Issuer) |
| Token validation | JWKS managed per region | Verifiable with a common JWKS |
The official blog introduces the details.
This article verifies the setup, authentication testing, and replica-side constraint checks using CLI, with the Tokyo region (ap-northeast-1) as primary and the Virginia region (us-east-1) as replica.
Verification Environment
| Item | Value |
|---|---|
| Primary | ap-northeast-1 (Tokyo) |
| Replica | us-east-1 (Virginia) |
| Tier | ESSENTIALS |
| AWS CLI | v2.34.58 |
The following variables are used in the commands in this article.
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, the following prerequisites must be met in order.
Note that new APIs such as create-user-pool-replica are available in AWS CLI v2.34.58 and later. The commands will not be recognized in older versions, so please update beforehand.
- Create a KMS multi-region key
- Configure the key policy
- Create the user pool (specifying CMK)
- Change the IssuerConfiguration
- Create and activate the replica
Creating a KMS Multi-Region Key
A KMS customer managed key (CMK) is required for multi-region replication. Create a multi-region key rather than a regular KMS 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
Grant permissions for both cognito-idp.amazonaws.com and identitystore.amazonaws.com services in the key policy so that Cognito can use the key. identitystore.amazonaws.com is a service used internally during replication, and is configured according to the policy example in the official documentation.
Configuration is required for each key in both regions (primary and replica).
Key policy example (Cognito-related portion)
{
"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 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 the IssuerConfiguration
Before replication, switch the OIDC Issuer to the Updated format. The Updated Issuer format is https://issuer-cognito-idp.[region].amazonaws.com/[userPoolId]. In this configuration, even when authenticating from the replica region, the iss became the issuer of the primary ap-northeast-1. Therefore, regardless of whether authenticating from Tokyo or Virginia, tokens can be verified using 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 met, 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 CREATING → INACTIVE. Once it becomes INACTIVE, manually switch it to ACTIVE.
# Check status (wait for CREATING → INACTIVE, approximately 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"
}
]
}
# Activate the replica
aws cognito-idp update-user-pool-replica \
--user-pool-id ${USER_POOL_ID} \
--region-name ${REPLICA_REGION} \
--status ACTIVE \
--region ${PRIMARY_REGION}
Setup is now complete. Users and client settings created in the primary (Tokyo) are automatically synced to the replica (Virginia).
Authentication Testing
We verified whether users created in the primary (Tokyo) can also authenticate from the replica (Virginia).
Preparing the Test User
Create an app client and 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"
}
}
This ClientId will be used as CLIENT_ID going forward.
# 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 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. We confirmed the user was visible on the replica side with admin-get-user before proceeding to authentication testing.
Authentication in 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}
Succeeded.
Authentication in 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
We compared the key claims of tokens obtained from both regions.
ID Token:
| claim | Tokyo (Primary) | Virginia (Replica) |
|---|---|---|
| iss | https://issuer-cognito-idp.ap-northeast-1.amazonaws.com/ap-northeast-1_xxxxxxxxx |
Identical |
| sub | a7445a18-xxxx-xxxx-xxxx-xxxxxxxxxxxx |
Identical |
| aud | xxxxxxxxxxxxxxxxxxxxxxxxxx |
Identical |
Access Token:
| claim | Tokyo (Primary) | Virginia (Replica) |
|---|---|---|
| iss | https://issuer-cognito-idp.ap-northeast-1.amazonaws.com/ap-northeast-1_xxxxxxxxx |
Identical |
| sub | a7445a18-xxxx-xxxx-xxxx-xxxxxxxxxxxx |
Identical |
| client_id | xxxxxxxxxxxxxxxxxxxxxxxxxx |
Identical |
The iss, sub, and aud (client_id) match between both regions. While iat, exp, and jti differ depending on the authentication timing, the claims referenced during token validation are identical, so there is no need to branch token validation logic per region.
However, when switching to Updated Issuer on an existing pool, separate updates to the application's issuer / JWKS endpoint settings will be required.
Write Restrictions on the Replica
The user pool in the replica region is a read-only endpoint primarily intended for authentication and user data retrieval. We verified 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 |
| Retrieve user | AdminGetUser | ✅ Success |
All write operations attempted 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
Regardless of whether it is an Admin API or user-facing API, the error type is consistently OperationNotEnabledException with the message "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 manner.
Commands and outputs 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 '<valid access token obtained from replica>' \
--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
Retrieve user (success):
aws cognito-idp admin-get-user \
--user-pool-id ${USER_POOL_ID} \
--username testuser01 \
--region ${REPLICA_REGION}
# → User information returned successfully
As an application design approach, options include handling this error type and routing write operations to the primary region, or separating the authentication endpoint and write endpoint from the outset.
Checking the Replica Limit
We verified whether replicas in multiple regions can be added to a single user pool. We attempted to add a third region to a separate pool (with us-west-2 as 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. This means a maximum of 2-region configuration of primary + replica.
If you want to distribute authentication across 3 or more regions, a different design such as a multi-pool configuration will be required. Note that it is possible to share the same KMS multi-region key across multiple pools.
Cost Estimate
Multi-region replication incurs add-on charges in addition to Cognito's base charges. The following is an estimate based on published pricing as of June 2026.
Prerequisites:
- Cognito Essentials tier, 1 replica region
- KMS multi-region keys in 2 regions (primary + replica)
- Free Tier (10,000 MAU) applied to Cognito base charges
- No Free Tier for MRR (Multi-Region Replication) add-on
- KMS key monthly charges only (API request charges excluded)
- SMS, email delivery, and Advanced Security charges 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 applied) | ~$45 | ~$2 | ~$47 |
| 100,000 | ~$1,350 (after Free Tier deduction) | ~$450 | ~$2 | ~$1,802 |
Unit prices used: Cognito Essentials $0.015/MAU, MRR add-on $0.0045/MAU/replica region, KMS $1/key/region/month.
For pricing details, please refer to the Amazon Cognito pricing page and the AWS KMS pricing page.
Notes
- Switching to Updated Issuer is a breaking change for existing applications. The official blog explicitly states "requests to the old endpoints will no longer be routed correctly." Applications that validate the issuer as a fixed value will need to update their endpoint settings in advance.
- TOTP MFA is not supported on secondary replicas. Users with MFA configured can only authenticate on the primary.
- Password authentication failure counts are asynchronous across regions, so the lockout threshold for brute force protection is evaluated independently per region.
- Only pools on "next-generation infrastructure" are supported. Older existing pools will become available after migration is completed by AWS.
- To automate failover, a design for custom domains and DNS routing is required. In configurations that call the API directly, an implementation is needed on the application side to switch the target region.
Summary
With Amazon Cognito's multi-region replication, we confirmed that the user pool in the Tokyo region can be replicated to the Virginia region and authentication is possible from both regions. By using a KMS multi-region key and Updated Issuer, the same client ID and issuer / JWKS can be assumed, eliminating the need to separate token validation logic per region.
However, replicas are read-only, and user registration, password changes, attribute updates, and similar operations must be routed to the primary. Also, since the limit is one replica per pool, configurations with 3 or more regions will require consideration of a multi-pool configuration or similar approach.
For existing applications, note that switching to Updated Issuer is a breaking change. For new builds, addressing this before production use will make it easier to prepare for future multi-region expansion.
