Migrate from Amazon Cognito to ZITADEL

Moving Cognito customer identity to self-hosted ZITADEL is a planned data, protocol and trigger rebuild, not a file copy. This page explains what moves cleanly, what needs rework and how to sequence the cutover.

On this page

Migrate from Amazon Cognito to ZITADEL: what moves and what does not

Teams that want customer login on infrastructure they control usually start with one question: how much of their Cognito user pool can move to self-hosted ZITADEL without forcing every customer through a new sign-in. The short answer is that user profiles and attributes move with a planned export and import, while password hashes are the hard part. Cognito does not hand over hashes in a standard export, so the migration plan has to decide, per user population, between a forced password reset and a sign-in-time migration. Platform engineering usually owns the ZITADEL deployment and database, security owns the password and MFA decisions, and application teams own the client changes. Most of the risk sits in those three areas, not in the data copy itself.

ZITADEL documents migration guides and a just-in-time migration approach, which lets a user's credentials move the first time they sign in through the new system. That pattern fits pools with many active users, but it needs the old pool to stay reachable until the last migrated user has signed in or a cutoff is reached. Mapping matters as much as moving. Each Cognito app client has to become an application inside a ZITADEL project, with its redirect URIs, token settings and roles rebuilt, and the sub values apps store must either be preserved or re-linked. Lambda triggers such as pre-authentication or post-confirmation logic have no direct equivalent and must be rewritten as ZITADEL Actions, so each trigger needs a documented owner and a test case.

Before committing, confirm three things with ZITADEL and your own environment: the export and import path for your pool size, the password handling you can accept for each user group, and the PostgreSQL version and high availability setup you will run, since ZITADEL supports PostgreSQL 14 through 18. Ask for a written scope that lists every app client, trigger and custom attribute, and agree a rollback plan before any user is moved. The migration guides are the natural starting point, and a scoped test in a non-production instance will show you more about your own risk than any general estimate. No duration should be planned from this page alone.

Which Cognito capabilities map to ZITADEL and where rework is needed

This table maps Cognito user pool concepts to their closest ZITADEL equivalents and marks each row as clean, needs rework or gap. Read the status column first, then the rework notes, since most migration effort sits in the rows marked needs rework. Hosted UI paths, token claims and Action syntax must be confirmed against ZITADEL's documentation for your version before you build against them.

Cognito capabilityZITADEL equivalentStatus and notes
User pools and usersInstance, organization and users inside a project's organizationNeeds rework. Cognito pools are flat, so decide how existing pools map onto ZITADEL organizations before importing users.
App clientsProjects grouping applications, roles and grantsNeeds rework. Each app client becomes an application in a project. Recreate client IDs, secrets and redirect URIs, since they will not carry over.
Hosted UI and loginZITADEL hosted loginNeeds rework. Hosted UI paths, custom domains and branding differ. Confirm the login URL structure and theming options in ZITADEL's documentation.
OIDC federationOIDC support and identity providersClean for most cases. Confirm each upstream provider's client settings and scopes in the target environment.
SAML federationSAML 2.0 identity providers and applicationsNeeds rework. Attribute mappings and metadata URLs must be rebuilt and tested against each relying party.
MFA and passkeysPasskeys with FIDO2 and WebAuthn, with password fallbackNeeds rework. Enrolled Cognito MFA factors do not transfer, so users re-enroll. Plan the user communication and the fallback path.
Custom attributesCustom user metadata and user schema, set per organizationNeeds rework. Map each custom attribute and confirm data types, since Cognito attribute names and types are fixed at pool creation.
GroupsRoles and grants on projectsNeeds rework. Cognito groups map to ZITADEL roles and grants, not one-to-one. Review group membership in each application.
Lambda triggersZITADEL ActionsGap. Each trigger's logic must be rewritten as an Action. Confirm supported hook points and runtime limits in ZITADEL's documentation.
The sub claimUser ID in the token subject claimGap. Subject values differ from Cognito's. Apps that store the sub claim need a mapping table or a sign-in-time migration to keep existing links.

Which user data can be exported from Cognito and what must be rebuilt

A Cognito move splits into two jobs: moving the user records and rebuilding everything that depends on the user pool. The export covers profiles and status, but not password hashes, so the sign-in path and the integrations need decisions before cutover.

Profiles and attributes export

The export gives you user records with standard and custom attributes, which become the basis for users and their metadata in ZITADEL. Check which custom attributes your apps read, because each one needs a matching field or metadata entry in the target organization. Map attribute names one by one before you run any import, and confirm with a test user that claims arrive with the values your applications expect.

Account status and MFA settings

Status fields such as enabled, confirmed and verified tell you which accounts should be imported and which should be left behind. MFA enrolment is a separate question, since factors often do not transfer with the profile. Decide per factor whether users re-enroll at first sign-in, and document the choice for your support team.

Password hashes and the sign-in path

Password hashes are not part of a standard Cognito export, so bulk import alone will not carry passwords across. You must choose between a forced password reset for every user and migrating users as they sign in, where your login flow verifies the old credential against Cognito before ZITADEL stores a new one. Plan the sign-in path before scheduling cutover, because it determines how long Cognito must stay reachable.

App client and redirect URI mapping

Each Cognito app client becomes a ZITADEL application inside a project, and each one needs its redirect URIs, logout URIs and allowed scopes copied exactly. A single character difference in a callback URL breaks login for that application. Build a table of every client, its owner and its callbacks, and test each one in a staging instance before DNS or configuration changes go live.

Token claims and the sub value

Applications usually key their records on the token subject, so the identifier issued for each user must either match the old value or be remapped in the database. Review the claims your apps read, such as email, groups and custom attributes, and rebuild their mapping in ZITADEL. Confirm with a sample login that the claims your code expects are present in the access and ID tokens.

Lambda triggers and downstream consumers

Cognito Lambda triggers for sign-up, pre-authentication, token generation and migration carry business logic that must be rebuilt as ZITADEL Actions, and each trigger needs a written behavior spec and test cases. Downstream consumers such as provisioning jobs, SCIM clients, data pipelines and audit tools also read from Cognito events or user lists, so list every consumer and decide whether it is re-pointed to ZITADEL's SCIM v2 interface or retired.

Bulk import or migrate users as they sign in

The core decision is whether to move every user in one batch and force a credential reset, or to leave users in Cognito for now and let ZITADEL validate their credentials against the old source at sign-in. Cognito's ListUsers API returns profiles, attributes and status, but it does not return password hashes, so a bulk import alone cannot carry passwords across. A batch move therefore usually ends with users setting a new password or passkey on first login, which requires a reset email or a communication plan. A just-in-time approach keeps passwords working during the transition, but it requires a working integration with Cognito for as long as migrated accounts remain unmoved, and it needs a clear end date.

Plan for the edge cases before choosing. Inactive or long-dormant accounts are better handled by an explicit decision: import them disabled, leave them in Cognito for archiving, or drop them after a documented retention check. MFA enrollment does not transfer in either approach, so decide whether users re-enroll TOTP or move to passkeys, which ZITADEL supports with password fallback. For user communication, prepare the sign-in message, the reset path and a support route before the cutover, and test the reset flow with a small pilot group first. Note that these choices also interact with the sub values your applications store, which are covered in the identity mapping section.

Before you commit to either path, confirm with ZITADEL which migration guide and approach it currently documents for a Cognito source. ZITADEL's migration guides cover Auth0, Keycloak, Firebase and another ZITADEL instance, and the team should verify whether a Cognito-specific guide or a generic just-in-time pattern applies to your version. Check the ZITADEL migration guides against your target release, and run a pilot import in a non-production instance to measure how many accounts actually need a reset.

How the migration sequence runs from inventory to decommission

The sequence moves Cognito users and applications to ZITADEL in controlled stages, so each application is proven on the new system before its logins leave the old pool. Each step produces a written artifact that the next step depends on.

  1. Inventory user pools, app clients and triggers

    List every Cognito user pool, app client, custom attribute, group, hosted UI setting and Lambda trigger, and record which applications and downstream systems depend on each one. The owner of each application signs off on the list. The output is an inventory that names each app client, the sub values applications store, and the trigger logic that runs during sign-up, sign-in or token issuance. You know this step is done when every pool and trigger has an owner and no application is unaccounted for.

  2. Build the attribute and trigger maps

    Map each Cognito attribute to a ZITADEL user field or custom metadata, and decide how the sub claim, email verification and group membership will carry over. Rewrite each Lambda trigger as a ZITADEL Action or confirm that the behavior is no longer needed. The outputs are an attribute map and a trigger rebuild list, with a reviewer named for each entry. Confirm the Actions and claim behavior against the ZITADEL documentation for your version before you rely on them.

  3. Pilot one app client on a non-production instance

    Stand up a non-production ZITADEL instance on PostgreSQL, create a project and application that mirror one low-risk app client, and load a copy of its users through either a bulk import or a sign-in-time migration. Test sign-in, token claims, role checks, password reset and passkey enrollment with the application team. The pilot is complete when the app team signs off on the test results and any gaps are logged as defects with owners.

  4. Run both systems in parallel

    Keep the Cognito pool live for every application while the migrated application accepts logins from ZITADEL, and monitor sign-in success, token validation errors and support tickets from both sides. Keep user records synchronized where the chosen migration method requires it. The output is a parallel-run log with error rates and reconciled user counts. Confirm the exit criteria in writing before you move to cutover, because the parallel run is the point where drift between the two systems shows up.

  5. Cut over each application with a runbook

    Move applications one at a time, each with a written cutover runbook that lists the DNS or configuration change, the freeze window for new Cognito sign-ups, the rollback steps and the named people who approve the switch. Verify session behavior and API token acceptance after each move before starting the next application. The cutover is done for an application when its runbook is closed and its logins are served only by ZITADEL.

  6. Retire the pool with a retained audit export

    After every application has run on ZITADEL through an agreed observation period, export the Cognito user list, group memberships and configuration as an archive, and store it under your records retention policy. Then disable sign-in on the pool, confirm no application still calls its endpoints, and delete it. The output is a retained audit export plus a decommission record that lists the deleted resources and the approver. Ask your compliance lead which retention period applies before you delete anything.

How the migration changes with user count and starting setup

A single user pool serving one or two applications is the simplest starting point. The user store is small, the attribute set is usually standard, and the main decisions are which applications move first and how users switch over. Because there are few clients to remap, the cutover can often be staged one application at a time, with the pool kept live for the application that has not moved yet. The password approach is the main choice here: Cognito does not export password hashes, so you either force a reset or migrate users as they sign in.

  • Sequence: Export the profiles, create the ZITADEL organization and project, then move one application at a time.
  • Passwords: A sign-in-time migration usually suits a small pool, because each user moves once they return.
  • Rebuild effort: Mostly the app client to ZITADEL application mapping, plus the token and redirect URI checks for each app.
  • Triggers: Often few or none, so confirm early whether any Lambda trigger changes what users see at sign-in.
  • Ongoing: One ZITADEL instance is enough for this scope, and the self-hosting effort is mainly the PostgreSQL database and the upgrade routine.

Confirm the number of app clients, the trigger configuration and whether any user has MFA enrolled before you choose the password approach.

What drives cost and duration in a Cognito to ZITADEL move

The cost of a Cognito to ZITADEL move splits into one-time project work and recurring platform operation. Each card names who is paid for a component and what to ask for in a written quote, so the figures can be compared on equal terms. Cognito costs should be taken from the AWS price list for your own region and usage, not estimated here.

Discovery and scope definition

Discovery covers the user pool inventory, app clients, custom attributes, Lambda triggers and the apps that depend on the sub claim. This is the largest single driver of duration because every trigger and client mapping found here shapes later work. Ask the vendor to name the deliverable, the number of apps in scope and who confirms the inventory in writing before build starts.

ZITADEL deployment and database

Self-hosted ZITADEL runs on PostgreSQL, with versions 14 through 18 supported according to the ZITADEL documentation. Costs include the database service, backups, the Linux, Docker Compose or Kubernetes platform, and the team that patches both. Confirm which PostgreSQL version and hosting model the quote assumes, and whether the database is managed by your cloud provider or by the implementation partner.

High availability design

ZITADEL recommends a Kubernetes cluster with the official Helm chart for high availability. Multiple nodes, load balancing, certificate management and a tested failover path add infrastructure and engineering time that a single-node pilot does not need. Ask whether the quote includes a highly available topology, who owns the cluster after handover and how failover is tested.

Trigger rebuilds as Actions

Cognito Lambda triggers for sign-up, pre-token generation and custom messages must be rewritten as ZITADEL Actions and retested against real flows. Effort depends on how much business logic lives in each trigger and on any calls to external systems. Ask the vendor to list each trigger, its replacement and the test cases it will pass before cutover.

User migration method

Bulk import and sign-in-time migration carry different costs. Bulk import requires an export that Cognito does not fully provide, including password hashes, so users may need password resets. Sign-in-time migration needs a custom integration that runs while the old pool remains live. Ask which method is priced, how password handling is covered and who writes and runs the migration code.

Testing, cutover and operations

Testing covers functional login flows, token claims, MFA and load, and cutover needs a rehearsal and a rollback plan. After go-live, patching, upgrades, backups and monitoring recur. Retainers for upgrades and support are optional and priced separately from the project. Ask for a fixed scope for testing and cutover, a stated support model after handover and the recurring cost of operations owned by your team.

Questions buyers ask before moving Cognito to ZITADEL

How much effort does a Cognito to ZITADEL move take?

The effort depends mostly on how many user pools, app clients and Lambda triggers you run, and on whether users must sign in again. No fixed effort figure is supplied for this move, so ask for one based on your own inventory. The main drivers are the number of applications that need new client configuration, the complexity of custom attributes and trigger logic, and how much cutover testing your compliance and release processes require. Ask any provider to give you a written breakdown by workstream: export, import or sign-in migration, client mapping, trigger rebuild, testing and cutover. Ask for that breakdown to be tied to a written scope before work starts.

How long does it take to move from Cognito to ZITADEL?

The duration is set by your application inventory, your change windows and the migration approach you pick, not by the platform itself. Bulk import can be scheduled as one event, while migrating users as they sign in runs for as long as your old pool stays active, which can extend the overall project. No duration is supplied for this move, so confirm the timeline in the written scope. Ask how the plan handles a parallel running period, rollback to Cognito, and the date after which the old pool is retired.

Can an internal team move Cognito to ZITADEL on its own?

Yes, a team with strong identity and cloud skills can do it, but the work spans several disciplines. Your engineers need to operate PostgreSQL 14 or later, a Docker Compose or Kubernetes deployment, OIDC configuration, and the ZITADEL concepts of instances, organizations and projects. Your security team also has to review token settings, MFA and the rebuilt trigger logic. Ask yourself whether you have capacity for this alongside normal releases. A fixed-scope engagement with DeployOpen covers planning, implementation, hardening, backup and documentation, and you can keep operations in-house afterward. Confirm the handover scope in writing.

Can Cognito password hashes move to ZITADEL?

Cognito does not export password hashes, so you cannot carry existing passwords across in a standard export. Your practical options are a just-in-time migration, where ZITADEL's migration approach validates a user's sign-in against the old pool and then stores the user in ZITADEL, or a forced password reset for users who have not signed in. ZITADEL documents migration guides that use just-in-time approaches. Confirm with the vendor and your own testing exactly which Cognito data each path can bring over, and plan for users who never return.

How do you keep the sub claim the same after migration?

The sub claim is the stable identifier your applications store and match on, so changing it can break account links and authorization data. Whether ZITADEL can keep your existing Cognito values depends on how users are created during import or sign-in migration, and this must be tested rather than assumed. Ask for a written test plan that compares the sub value for sample users in both systems, checks any stored references in your databases, and confirms how tokens from ZITADEL map to your application's user records before cutover.

What does the AGPL license mean for a SaaS deployment?

ZITADEL's core is licensed under AGPL-3.0, and that license applies to modified versions of the core software. Since v3.0, ZITADEL's core, Console and hosted login moved from Apache 2.0 to AGPL-3.0, while APIs, SDKs, proto definitions, examples, documentation, Helm charts and Terraform configurations remain Apache 2.0. If you run a modified core and make it available to users over a network, the AGPL obligations can apply. Have your legal counsel review your exact use, including any changes to the login pages, and confirm the boundaries with the vendor before you build on it.

What must our team supply before a migration starts?

A complete inventory is the most important input. Provide the list of user pools, app clients, callback URLs and scopes, custom attributes, groups, MFA settings, and every Lambda trigger with its logic. Also provide your target hosting details, PostgreSQL version, backup and retention requirements, network and DNS plans, and the compliance evidence your assessors expect. Name the people who approve cutover and rollback. Ask any provider to confirm, in the written scope, which items they will verify and which remain your responsibility.

Who runs ZITADEL after the migration is finished?

Your organization runs ZITADEL in your own infrastructure, so it owns upgrades, patching, backups, monitoring and incident response. ZITADEL's latest release is v4.19.5, released on 15 October 2026, so plan a regular upgrade cycle. Ask for a written operations model that covers who receives release notes, how upgrades are tested, how database backups are verified, and what support is available. Ongoing support, upgrades and continuous testing are available from DeployOpen as retainers, priced from the written scope.

How DeployOpen scopes and runs a Cognito to ZITADEL migration

DeployOpen plans and implements the move from Amazon Cognito to self-hosted ZITADEL inside your own infrastructure, from the first inventory of user pools and app clients to cutover and handover. Engagements are fixed-scope, with scope, deliverables and timelines agreed in writing before work starts.

How we scope

  • Inventory every Cognito user pool, app client, identity provider and Lambda trigger that touches sign-up or sign-in.
  • Confirm which user attributes must move, and which Cognito ListUsers data can be exported for each pool.
  • Agree in writing whether users move by bulk import, sign-in-time migration, or a forced password reset, given that Cognito exports no password hashes.

How we build

  • Stand up self-hosted ZITADEL on PostgreSQL in your own cloud account or data center, with the deployment model you confirm.
  • Map each app client to ZITADEL projects, applications, roles and grants, and preserve the subject identifiers your apps depend on.
  • Rebuild Lambda trigger logic as ZITADEL Actions and test each flow against staging copies of your user data before any cutover.

How we hand over

  • Document the instance layout, organization and project model, identity provider configuration and the migration runbook.
  • Provide test evidence for sign-in, password reset, MFA and passkey flows, plus the rollback steps agreed in the scope.
  • Train your platform and identity operators on routine administration, backup and upgrade procedures for the ZITADEL deployment.

How we support

  • Run post-cutover monitoring and hardening checks against the configuration agreed in the written scope.
  • Plan ZITADEL version upgrades and document the changes they require for your applications and Actions.
  • Offer ongoing support, upgrades and continuous testing as a retainer, priced from a written quote rather than a fixed list.

Talk to our team.

Tell us what you're working on, whether it's a deployment, an audit, a security test or a cyber range. You'll speak with an engineer who can help you scope it.

  • 30-minute call: free, with no obligation.
  • NDA on request: we can sign before you share details.
  • Clear next steps: a scope and plan after the call.