Table of Contents

Auth0 to Azure AD B2C was not a decision I took lightly. This article explains the one feature that forced the switch, reduced identity costs, and unlocked enterprise-level customization.
I need to have a conversation with myself about the invoice that landed in my inbox last October. It was from Auth0, and it was for our SaaS platform’s identity provider renewal.
We had just hit a growth spurt. Our Monthly Active Users (MAU) had tripled. In the startup world, this is called “success.” But looking at the bill, it felt like a punishment.
Auth0 is an incredible product. It’s developer-friendly, the docs are beautiful, and it “just works.” I built our MVP with it in an afternoon. But as we scaled into the enterprise space, two walls closed in on me simultaneously:

  1. The Pricing Cliff: The cost per user was eating into our margins.
  2. The “Black Box” Logic: We needed deep customization for a client in the healthcare sector, and Auth0’s “Rules” and “Actions” (while powerful) were hitting their limits regarding protocol manipulation.

That’s when I looked at Azure Active Directory B2C (Business to Consumer).
I admit, I was hesitant. I had heard the horror stories about XML configuration files. But I decided to run a Proof of Concept. And in that process, I discovered the Identity Experience Framework (IEF).
Here is why I migrated, and why that specific feature changed everything.


The “Success Tax” of Managed Identity

Before I explain the solution, let me explain the trap.
When you start with a provider like Auth0 or Okta, you are paying for convenience. You don’t want to manage password hashes, MFA rotation, or OIDC compliance.

But as you grow, you start needing weird things.

  • “Can we store this specific legacy claim in the token?”
  • “Can we call a REST API before the password is validated to check for fraud?”
  • “Can we federally sign in with another Azure AD tenant but map their groups to our internal roles?”

In Auth0, I was writing increasingly complex JavaScript “Rules” to hack these flows together. It felt fragile. And every time I added a feature, the bill went up.

The Reality Check: I calculated that moving to Azure AD B2C would make our first 50,000 monthly active users… free. The cost difference wasn’t just 10% or 20%. It was an order of magnitude.

The Game-Changing Feature: Identity Experience Framework (IEF) & Custom Policies

The feature that convinced me to endure the migration wasn’t the price (though that helped). It was the Identity Experience Framework (IEF).
In most identity platforms, you configure settings. Toggle a switch for “MFA.” Toggle a switch for “Google Login.”
In Azure AD B2C with Custom Policies, you don’t just configure settings; you program the user journey.

Why “Custom Policies” Are a Superpower

IEF allows you to define the entire identity state machine using XML. Yes, XML is verbose. Yes, it has a steep learning curve. But it gives you god-mode access to the authentication flow.
Here is what I could suddenly do:

  1. Complex Rest API Integration: I could inject logic at any step. I created a journey that checks a user’s subscription status in our SQL database during the login and denies access if they have an unpaid invoice, showing them a custom payment screen—all within the auth flow.
  2. Migration without Password Resets: This was the killer. I could define a logic flow that checks legacy credentials and seamlessly migrates them to B2C without the user ever knowing.

The Code: A Glimpse of the Power

In Auth0, I was restricted to the user object they gave me. In B2C, I define the “Orchestration Steps.”
Here is a snippet of an XML policy that checks if a user needs to run a specific migration step:

<OrchestrationStep Order="3" Type="ClaimsExchange">
  <Preconditions>
    <Precondition Type="ClaimEquals" ExecuteActionsIf="true">
      <Value>isMigrated</Value>
      <Value>true</Value>
      <Action>SkipThisOrchestrationStep</Action>
    </Precondition>
  </Preconditions>
  <ClaimsExchanges>
    <ClaimsExchange Id="RestAPI-CheckLegacyDB" TechnicalProfileReferenceId="REST-CheckUserStatus" />
  </ClaimsExchanges>
</OrchestrationStep>

This XML snippet tells the identity engine: “If the user is already migrated, skip this. If not, call this REST API to check their status.”
It is explicit. It is version-controllable. It is powerful.


My Migration Journey

Moving 100,000 users is terrifying. If you mess up, no one can log in. Your business stops. Here is the strategy I used to move from Auth0 to Azure AD B2C without a single password reset email.

Phase 1: Just-In-Time (JIT) Migration

This is the standard pattern, but B2C makes it natively possible via Custom Policies.

I set up a “Migration User Journey.”

  1. User enters credentials in the B2C login box.
  2. B2C checks its own database. (User not found).
  3. B2C calls a REST API (Azure Function) behind the scenes.
  4. The Azure Function tries to log in to Auth0 with those credentials via the Resource Owner Password Grant.
  5. If Auth0 says “Success,” B2C creates the user in its directory and sets the password to what they just typed.
  6. User is logged in.

To the user, nothing changed. To us, they just moved databases.

Phase 2: Mapping Claims & Tokens

Auth0 and Azure AD emit tokens differently.

  • Auth0 might call it https://schemas.myapp.com/role.
  • Azure AD likes extension_Role.

I used the OutputClaimsTransformation feature in B2C to rename claims on the fly. This meant I didn’t have to rewrite my backend API code. I just told B2C to “speak the language” of my existing app.

Phase 3: The Parallel Run

For two weeks, we supported both login methods.

  • New users went straight to B2C.
  • Existing users went through the JIT flow.
  • We used a Traffic Manager to slowly ramp up traffic to the B2C endpoints.

Real Results: The “Enterprise” Grade

After the dust settled and the XML scars healed, the results spoke for themselves.

MetricAuth0 EraAzure AD B2C Era
Pricing ModelTiered MAU CliffsFirst 50k MAU Free
CustomizationJS Rules (Limited)IEF XML (Unlimited)
SecurityStandardMicrosoft SOC2 / HIPAA
B2B IntegrationPaid Add-onNative Entra ID Integration

1. Predictable Pricing

We went from a bill that fluctuated wildly to a bill that was largely… zero. The “Premium P1” features cost money, but the core authentication for our customer base fell entirely within the free tier.

2. Single Identity Ecosystem

Our internal staff uses Azure AD (Entra ID) for Office 365. Our customers use Azure AD B2C.
The integration is seamless. We can now easily invite a customer (B2C) to collaborate on a SharePoint document (B2B) because the underlying plumbing is the same Microsoft identity platform.

3. Compliance Confidence

When a new enterprise client asked, “Are you SOC2 compliant?” I didn’t have to explain our custom Auth0 rules. I just pointed to the Microsoft Trust Center. Azure AD B2C inherits the massive compliance framework of Azure. That conversation became 10x shorter.


Is Azure AD B2C Perfect?

No. Let me be brutally honest.

The Learning Curve is Vertical.
Auth0 is a gentle slope. Azure AD B2C Custom Policies is a cliff. You will spend days debugging cryptic XML error messages like “A claim of type ‘userId’ was not found.” You need to understand OpenID Connect protocols deeply.

The Documentation is “Dense.”
Microsoft’s documentation is comprehensive, but finding the exact example for a specific custom policy scenario can be like finding a needle in a haystack.

The Portal UI.
The Azure portal experience for B2C can feel disjointed compared to the slick Auth0 dashboard.


Final Thoughts

I’m talking to myself here, and to any CTO or Architect staring at an identity provider bill that rivals their cloud compute costs.
Auth0 is fantastic for getting started. It is the best developer experience in the market, hands down.
But Azure AD B2C is the best enterprise experience in the market.
The move wasn’t easy. I traded the simplicity of JavaScript for the complexity of XML. But in return, I got a platform that I own, that scales without bankruptcy, and that allows me to build absolutely any authentication flow my clients can dream up.
The grass isn’t just greener. It’s virtually free for the first 50,000 users. And in the SaaS game, that is an advantage you can’t ignore.

Categorized in: