Start by mapping the Auth0 features you actually depend on, not the marketing category. Hosted login, custom domains, database connections, social login, enterprise SAML, MFA, machine-to-machine clients, Organizations, Rules, Actions, and Management API workflows all translate differently in open source systems. The big choice is whether you want an identity server that stays close to OAuth 2.0 and OIDC primitives, or a higher-level user management product with admin screens and policy workflows. Also decide who owns uptime for login, because identity outages take down every app at once.
Expect gaps around polish, defaults, and edge-case integrations. Auth0 hides a lot of operational detail: key rotation, email templates, brute-force protection, anomaly handling, tenant isolation, hosted login UX, and provider-specific social login quirks. Open source replacements can be strong, but you usually assemble more of the surrounding system yourself. Rules and Actions are another friction point because they often contain business logic that grew organically. Treat them as application code that needs design review, tests, and a new deployment path, not as snippets to copy over blindly.
Migration usually starts with a parallel realm or tenant in the new system, then one application moves first using OIDC discovery, issuer, client ID, client secret, callback URLs, scopes, and JWKS changes. User export from Auth0 can preserve profile fields and metadata, but password migration depends on the connection type, hash availability, and whether you choose forced reset or just-in-time migration. MFA enrollments, sessions, refresh tokens, logs, and custom rule side effects rarely move cleanly. Keep Auth0 running during cutover, verify token claims app by app, and plan a rollback path before changing production callbacks.