← Back to Blog

B2B SaaS Multi-Tenancy & User Onboarding Patterns

Implementing organization provisioning, user administration, and secure invite validation flows

This document details organization provisioning and user onboarding structures within multi-tenant SaaS environments. Zero IDS allows isolation of customer domains, teams, and administrative roles natively.

A. Administrative Provisioning via Backend APIs

When a customer purchases a subscription in your B2B application, call the Zero IDS administrative endpoints from your backend to set up their tenant space:

1. Provision Customer Organization (Tenant)

Create a separate organization bound to the customer's domain name:

curl -X POST http://localhost:3000/api/organizations \
  -H "Content-Type: application/json" \
  -H "X-User-ID: your-super-admin-uuid" \
  -d '{
    "name": "Acme Corporation",
    "domain": "acme.com"
  }'

Response: Returns the organization record, including the auto-generated id (UUID) representing the Tenant.

2. Provision Organization Administrator

Create the customer's initial administrator, binding their profile to the newly created organization ID:

curl -X POST http://localhost:3000/api/users \
  -H "Content-Type: application/json" \
  -H "X-User-ID: your-super-admin-uuid" \
  -d '{
    "email": "admin@acme.com",
    "password": "secureTemporaryPassword123!",
    "firstName": "Alice",
    "lastName": "Admin",
    "organizationId": "acme-organization-uuid",
    "roleNames": ["ORG_ADMIN"]
  }'

The ORG_ADMIN role permits Alice to invite members, manage teams, configure 2FA enforcement, and review audit logs within the Acme Corp tenant space.

B. User Invitation and Onboarding Flows

Select either a Zero-managed or client-managed invitation flow based on your SaaS requirements:

Pattern 1: Zero-Managed Onboarding (Direct Email Invitations)

Your application calls the user creation endpoint on behalf of the organization administrator. Zero IDS automatically sends an onboarding confirmation email to the invited user:

curl -X POST http://localhost:3000/api/users \
  -H "Content-Type: application/json" \
  -H "X-User-ID: alice-org-admin-uuid" \
  -d '{
    "email": "bob@acme.com",
    "password": "temporaryPassword123!",
    "firstName": "Bob",
    "lastName": "Developer",
    "organizationId": "acme-organization-uuid",
    "roleNames": ["MEMBER"]
  }'

Pattern 2: App-Managed Onboarding (Custom Invitation Links)

Your application backend generates custom onboarding links (containing invitation tokens) and sends emails via its own delivery system.

When a user clicks the invitation link, your application validates the token and redirects the user to the OIDC authorization endpoint, passing a login_hint to populate the login form:

app.get('/accept-invite', (req, res) => {
    const { org_id, email, token } = req.query;

    // Validate the invitation token internally
    if (!isValidInviteToken(token, email)) {
        return res.status(400).send("Invalid or expired invitation token.");
    }

    // Persist organization context in cookie storage
    res.cookie('pending_invite_org', org_id, { httpOnly: true, secure: true });

    // Redirect to OIDC authorization endpoint with login_hint
    const zeroIdsAuthUrl = 'http://localhost:3000/oidc/auth' +
        '?client_id=your_saas_client_id' +
        '&redirect_uri=https://your-app.com/auth/callback' +
        '&response_type=code' +
        '&scope=openid profile email' +
        '&login_hint=' + encodeURIComponent(email);

    res.redirect(zeroIdsAuthUrl);
});

OIDC Series Guides