How do I set up Auth0 Organizations for a multi-tenant B2B SaaS (members, roles, invites, per-org login)?
Authentication & Identity APIs

How do I set up Auth0 Organizations for a multi-tenant B2B SaaS (members, roles, invites, per-org login)?

10 min read

Most B2B SaaS teams reach the same inflection point: you’ve outgrown “one tenant, one customer,” and now every enterprise prospect asks for SSO, per-customer admin, and clean separation of data and users. Auth0 Organizations is designed exactly for this multi-tenant pattern—modeling each customer as an organization, with members, roles, invites, and dedicated login experiences.

Below is a practical, implementation-first guide to setting up Auth0 Organizations for a multi-tenant B2B SaaS, based on how I’ve done it in production (including the gotchas around roles and per-org login).


What “multi-tenant with Organizations” actually means

In this model:

  • Each business customer = one Auth0 Organization
  • Your SaaS app = one Auth0 application (SPA / Regular Web App)
  • Users = Members of one or more Organizations
  • Authorization = Combination of:
    • Organization membership
    • Organization-level roles (e.g., org:admin, org:billing)
    • App-level roles/permissions, if you use RBAC
  • Login = Either:
    • User chooses an organization at login
    • Or user is sent to a per-org login link / home realm discovery flow

This lets you:

  • Separate customers (up to 2 million organizations in a single Auth0 tenant).
  • Turn on SSO and SCIM per customer.
  • Expose self-service admin and invites without exposing your whole Auth0 tenant.

Prerequisites & high-level setup

Before wiring in members, roles, and invites, make sure you have the basics in place.

1. Create or identify your Auth0 application

For a typical B2B SaaS, you’ll have:

  • A Single-Page Application (SPA) or Regular Web Application registered in Auth0:
    • Dashboard path:
      Applications > Applications > [Your App]
  • Redirect URIs and logout URLs configured for your frontend.

You’ll use this same application for all organizations.

2. Enable Organizations in your tenant

  1. In the Dashboard:
    Organizations > Settings
  2. Enable Organizations.
  3. Decide:
    • Can users be members of multiple organizations?
    • Can users create organizations themselves?
      (Usually “no” for B2B SaaS; you control org creation from back-office or billing.)

3. Associate your app with Organizations

  1. Go to:
    Applications > Applications > [Your App] > Organizations
  2. Enable:
    • “Enable Organizations”
    • Optional: “Allow users to select organizations” (if you want org picker at login).

This tells Auth0 that logins for this app can be scoped to a specific org.


Step 1: Model your customers as Organizations

Each of your B2B customers should get an Auth0 Organization.

Create an Organization per customer

Dashboard:

  1. Organizations > Create Organization
  2. Set:
    • Name (ID): machine-friendly, e.g. acme-corp
    • Display Name: what users see, e.g. Acme Corp
  3. Assign your app under Associated Applications.

API example (for automation):

curl --request POST \
  --url https://YOUR_TENANT_DOMAIN/api/v2/organizations \
  --header 'authorization: Bearer YOUR_MGMT_API_TOKEN' \
  --header 'content-type: application/json' \
  --data '{
    "name": "acme-corp",
    "display_name": "Acme Corp",
    "branding": {
      "logo_url": "https://example.com/acme-logo.png",
      "colors": {
        "primary": "#0047AB"
      }
    }
  }'

I strongly recommend you:

  • Store the organization_id returned by Auth0 in your own “customers” table.
  • Use a one-to-one mapping between SaaS tenant and Organization for clean audit trails.

Step 2: Configure per-organization login (per-org login links)

Your B2B customers expect users to land in their tenant, not guess a shared login.

Option A: Dedicated org login URLs

Auth0 provides a per-org login URL:

https://YOUR_TENANT_DOMAIN/authorize?
  client_id=YOUR_CLIENT_ID&
  organization=ORG_ID_OR_NAME&
  redirect_uri=YOUR_CALLBACK_URL&
  response_type=code&
  scope=openid%20profile%20email

For example:

https://YOUR_TENANT_DOMAIN/authorize?
  client_id=abcd1234&
  organization=acme-corp&
  redirect_uri=https://app.your-saas.com/callback&
  response_type=code&
  scope=openid%20profile%20email

Implementation patterns:

  • Put this behind a “Login” button on each customer’s subdomain, e.g. https://acme.your-saas.com/login.
  • Or email this URL to org members as the canonical login link.

Option B: Organization picker at login

If you enable “Allow users to select organizations” on the app, Auth0 can:

  • Show an org picker after the user authenticates.
  • Or require the user to type/choose the org.

This is useful if users belong to multiple customers (e.g., agencies, consultants).


Step 3: Define organizational roles (per-org admin, member, etc.)

Auth0 Organizations lets you define organization roles that are separate from global app roles.

Typical B2B roles:

  • org_admin – manage members, invites, SSO, billing, settings
  • org_member – regular user of the product
  • org_billing – manage billing but not users (optional)
  • org_readonly – view-only (optional)

Create organization roles

  1. Dashboard:
    Organizations > Roles > Create Role
  2. Role type: “Organization” (not “Application”).
  3. Name and Description, e.g.:
    • Name: org_admin
    • Description: Organization administrator with full access to settings and members

You can still use application-level roles and permissions for in-app feature gating, but org roles are ideal for:

  • Access to your in-app org admin console.
  • Express configuration flows (e.g., Self-Service SSO).
  • SCIM / provisioning admin rights.

Step 4: Manage members (add, remove, map to tenants)

Members are how you attach users to a specific customer tenant.

Adding members to an organization

From the Dashboard:

  1. Organizations > [Acme Corp] > Members
  2. Click Invite or Add Members.
  3. Add email addresses and assign roles (e.g., org_admin, org_member).

Alternatively, via Management API (after signup or from your back-office):

curl --request POST \
  --url https://YOUR_TENANT_DOMAIN/api/v2/organizations/ORG_ID/members \
  --header 'authorization: Bearer YOUR_MGMT_API_TOKEN' \
  --header 'content-type: application/json' \
  --data '{
    "members": ["user_id_1", "user_id_2"],
    "roles": ["org_member"]
  }'

Recommended pattern:

  • On customer creation in your SaaS, create Organization.
  • On first user invite, create user (if needed), then add as member with org_admin.
  • Store org_id and user_id relationships in your DB for fast access.

Removing members

When you remove users from an org:

  • Their membership is revoked, but their Auth0 user profile still exists.
  • Your app should treat “not a member of this org” as no access to that tenant, even if the user still exists globally.

Step 5: Implement invites with per-org context

Auth0 Organizations supports invite flows that include org context.

High-level flow:

  1. Org admin initiates invite in your app (enters email + role).
  2. Your backend calls Auth0 to create an organization invitation.
  3. Auth0 generates an invite URL that includes organization and invitation parameters.
  4. You send that URL via your email system (or use Auth0’s email provider/templates).
  5. User clicks the invite, signs up/logs in, and is automatically joined to that org with the assigned role.

API example (simplified):

POST https://YOUR_TENANT_DOMAIN/api/v2/organizations/ORG_ID/invitations
Authorization: Bearer YOUR_MGMT_API_TOKEN
Content-Type: application/json

{
  "inviter": { "user_id": "inviting_user_id" },
  "invitee": { "email": "new.user@example.com" },
  "client_id": "YOUR_CLIENT_ID",
  "roles": ["org_member"],
  "app_metadata": {
    "invited_by_org": "acme-corp"
  }
}

When the invite is accepted, your app can:

  • Read organization in the ID token / user context.
  • Apply your own onboarding (e.g., set default workspace, plans).

Tip: Use an Auth0 Action on post-login to handle “invited user first login” and route them appropriately in your app.


Step 6: Read org and roles in your app (authorization decisions)

Once Organizations is wired, you need to actually use that context in your SaaS.

What’s in the tokens?

When a user logs in with an organization, Auth0 can include:

  • org_id and org_name in the ID token and access token (if you enable it).
  • Organization roles in the token, or via the /userinfo endpoint.

Configure token contents:

  1. Dashboard:
    Organizations > Settings > Token Contents
  2. Enable:
    • “Add organization ID to tokens”
    • “Add organization name to tokens”
    • Optionally “Add organization roles to tokens”

Or use a post-login Action to add a custom claim:

exports.onExecutePostLogin = async (event, api) => {
  if (event.organization) {
    api.idToken.setCustomClaim(
      "https://your-saas.com/org",
      {
        id: event.organization.id,
        name: event.organization.display_name,
        roles: event.authorization?.roles || []
      }
    );
  }
};

Then, in your app:

  • Use this claim to:
    • Route to /{orgSlug} or {orgId} in your frontend.
    • Enable/disable admin panels based on roles.includes("org_admin").
    • Enforce that orgId in URL or API path matches token’s org claim.

Step 7: Wire multi-tenant access in your backend APIs

For a B2B SaaS, your backend should treat org_id as a mandatory dimension:

  • Every resource has an org_id column/key.
  • Every API request is evaluated against the authenticated org_id.

Typical backend checks:

  1. Extract organization context from the access token:

    • In Node/Express:

      const orgClaim = req.auth?.payload["https://your-saas.com/org"];
      if (!orgClaim) throw new Error("Organization context required");
      
  2. Validate data access:

    • When querying DB:
      SELECT * FROM projects
      WHERE id = $1 AND org_id = $2
      
    • With $2 = orgClaim.id.
  3. Gate admin operations by org roles:

    • Only org_admin can:
      • Manage members
      • Configure SSO/SCIM
      • Change billing / plan

This is where Organizations shines: you never have to guess org from email or domain; it’s explicit in the token.


Step 8: Turn on enterprise SSO and SCIM per organization (optional but powerful)

When you’re ready to land bigger customers, Organizations gives you:

Per-org enterprise SSO

For each customer:

  1. Organizations > [Acme Corp] > Connections
  2. Add e.g. Okta Workforce, Azure AD, SAML, etc.
  3. Configure their IdP (metadata, client IDs, etc.).
  4. Associate that connection only to the Acme Organization, not globally.

This enables:

  • Customer-specific SSO with home realm discovery.
  • Different IdPs for different customers.
  • No cross-tenant user leakage.

Self-service SSO configuration

With Self-Service Enterprise Configuration and org roles:

  • Grant org_admin access to an in-app SSO setup console.
  • Let them configure their own SAML/OIDC connection.
  • Under the hood, you use the Management API to create/update the enterprise connection and attach it to that Organization.

This is the pattern behind Auth0’s SaaStart reference application.

SCIM provisioning (joiner/mover/leaver)

If you enable Inbound SCIM per organization:

  • Customer IT can automate:
    • Create user → add as org member.
    • Department changes → update roles or groups.
    • Termination → deprovision user from the org.
  • You map externalId from their IdP to your user/tenant IDs (watch this mapping closely; mismatches cause “orphaned” accounts or duplicate users).

Step 9: Admin consoles and delegated control

With org roles and per-org login, you can safely expose:

  • Org-level admin console inside your SaaS:

    • Members list.
    • Role assignment.
    • SSO and SCIM configuration.
    • Audit views (backed by Auth0 logs streamed to Datadog/Splunk/AWS/Azure).
  • Delegated admin:

    • No need to give customers access to your Auth0 dashboard.
    • Everything happens via your app, backed by Auth0 Management API and org roles.

Auth0 handles:

  • Authentication flows (OIDC/SAML/OAuth).
  • Security protections (bcrypt hashing/salting, breached password detection, brute-force detection, rate limiting, DoS mitigation).
  • Availability (99.99% uptime, 10B+ authentications/mo, 3B+ attacks blocked/mo).

You keep:

  • Tenant model and UX.
  • Business logic and enforcement of org-level authorization.

Putting it all together: End-to-end flow

Here’s what a typical B2B tenant lifecycle looks like with Organizations:

  1. Customer created in your billing/CRM → Your backend:

    • Calls Auth0 to create Organization.
    • Stores org_id in your customers table.
  2. First admin invited:

    • Org admin (or your internal ops) triggers an invite.
    • Backend creates organization invitation with org_admin role.
    • Email contains per-org invite URL.
  3. Admin accepts invite:

    • User signs up/logs in via Auth0.
    • Organization membership + role created automatically.
    • Your app reads org claim, routes to /orgs/acme/admin.
  4. Admin invites more members:

    • In-app UI calls backend → Auth0 Organization invitations.
    • Members are added as org_member or other roles.
  5. Enterprise SSO/SCIM (later stage):

    • Admin configures SSO in your in-app console.
    • You use Auth0 Management API to create per-org connections.
    • SCIM provisioning is set up for automated user lifecycle.
  6. Ongoing login:

    • Users hit https://acme.your-saas.com/login.
    • You redirect to per-org /authorize?organization=acme-corp.
    • Auth0 issues tokens with org claim + org roles.
    • Backend enforces org_id at every data access.

Next Step

If you’re ready to move your B2B SaaS to a clean, scalable multi-tenant model with Organizations—without living “deep in SAML configs and OIDC flows”—it’s usually fastest to walk through your tenant model and org lifecycle with an expert.

Get Started