Multi-Tenant Architecture for B2B SaaS

Most auth providers treat users as isolated individuals, forcing you to build organization logic from scratch. The Bridge is built for B2B: workspaces, per-workspace roles, and workspace switching are part of the platform itself.

GDPR compliant ISO 27001 Security audited Enterprise-grade & compliant by default

What multi-tenant gets you

  • One auth platform, many apps Every internal or product app plugs into the same Bridge with its own app ID. No more separate logins per tool.
  • One login, many workspaces A person signs in once and unlocks every workspace they belong to, with a role and teams per workspace.
  • Workspace switching built in Switching is a state of the auth flow itself, so permissions and data scope change together.

One platform, many apps

Most companies do not have one application. They have a product, an admin panel, a couple of internal tools, and each one usually grows its own login. The Bridge inverts that: apps are a first-class object on the platform. Each app registers with its own app ID and gets the full login stack, from social login and SSO federation (SAML and OIDC) to MFA and passkeys, configured per app from one Control Center. Adding auth to the next internal tool means registering the next app, not building another login.

The model: apps, workspaces, memberships

Three objects carry the whole architecture:

  • An app is one of your applications on The Bridge.
  • A workspace (tenant) is a customer organization inside an app.
  • A membership connects a user to a workspace, and it is the membership that carries the role, team assignments, and enabled flag.

The consequence of putting the role on the membership instead of the user: the same person can be an admin in one workspace and a viewer in another, behind a single set of credentials. There is no duplicate account per organization, and there is no global role leaking across customers.

Switching workspaces is part of signing in

When a user with access to several workspaces signs in, workspace selection is a state of the login flow itself, not a screen you build. The frontend SDKs expose the whole thing: an auth:workspace-changed event fires on a switch, useTenantUsers() lists the workspaces available during selection, and hasMultiTenantAccess on the profile tells you whether to show a switcher at all. Because the switch happens inside the auth machinery, the session token is reissued for the new workspace: permissions and data scope flip together, atomically.

Your data, scoped by the token

The Bridge holds identity and workspace context. Your rows stay in your database, and the token tells you which workspace they belong to. Concretely: say your app stores projects, and Acme and Initech are both customers. Every project row carries the workspace it belongs to, and when someone at Acme creates a project, your endpoint reads the workspace from their verified token, never from the request body. A user cannot ask their way into another company's data, because the tenant ID is not something the client gets to say.

What that looks like depends on your backend framework. In NestJS, the SDK delivers the verified user through a decorator:

ts
// Fetching the signed-in user is as easy as one decorator
@Controller('projects')
export class ProjectsController {
  @Post()
  async create(
    @Body() data: CreateProjectDto,
    @CurrentUser() user: BridgeUser,
  ) {
    // tenantId comes from the verified JWT, not from the request body
    return this.projectsService.create(data, user.tenantId, user.id);
  }
}

In Express, the middleware puts the same verified user straight on the request:

ts
// Fetching the signed-in user is as easy as reading req.bridgeUser
router.post('/projects', async (req, res) => {
  const user = req.bridgeUser!;
  // tenantId comes from the verified JWT, not from the request body
  const project = await projects.create(req.body, user.tenantId, user.id);
  res.status(201).json(project);
});

How strictly you separate data stays your call. The documented strategies range from a tenantId column, which fits most apps, to a schema per tenant, to a fully separate database per tenant for maximum isolation. The full pattern, per framework and with provisioning included, is in the multi-tenancy docs.

Workspaces provision themselves

A new customer signup should not involve a human. The Bridge sends webhooks when tenants and users are created (TENANT_CREATED, TENANT_USER_CREATED, and their update and delete siblings), so your backend can set up default data the moment a workspace appears. The documented pattern pairs webhooks with a just-in-time fallback: if a request arrives for a workspace you have not seen, create it on the spot. Between the two, provisioning has no gap.

The workspace is also the commercial unit

Subscription, entitlements, and branding hang off the same workspace object that auth manages. Server-side, one call gives you all of it: bridge.fromJwt(jwt) returns the current workspace's plan, an entitlements.can() check for feature gating, and its branding, cached and deduped per request. On the frontend, the TeamManagementPanel component gives every workspace its own user management inside your app: invites, roles, password resets, workspace settings.

This is the part that outlasts your current roadmap: an app built on this model is already shaped like a sellable product. Turning an internal tool into a commercial one means attaching a plan to the workspace, not rebuilding identity and billing.

Build on the model instead of building the model. Create your first app and workspace in the Control Center, and your next tool starts with auth, teams, and billing already structured. Get started with The Bridge.
Ready to

build your B2B app?

Get started in minutes. No credit card required.

Get Started
Keep building

Explore every identity guide

Every auth question you were saving for later, answered in its own guide. Pick one and go build.