Your SaaS app signs up a new customer, and within that customer sit dozens of people who each want to connect their own mailbox. Now multiply that by a few thousand accounts across Gmail, Outlook, and a handful of enterprise tenants that demand admin sign-off before anyone can connect. Building that yourself means a separate OAuth project per provider, a token store you have to refresh on a timer, and a tenant boundary you enforce in every query.
This recipe shows how to model multi-tenant OAuth with one grant per connected account, keep tenants isolated in your own data, and handle enterprise admin consent without rebuilding the flow per customer.
How do I authenticate a multi-tenant SaaS app so each user connects their own account?
Section titled “How do I authenticate a multi-tenant SaaS app so each user connects their own account?”Send every user through the same hosted OAuth flow and store the grant ID it returns against that user’s tenant. Each completed flow at /v3/connect/auth produces exactly 1 grant representing 1 connected mailbox, so a tenant with 40 people who connect their inbox ends up with 40 grants, all reachable through the same API key.
The flow doesn’t change per tenant or per provider. One redirect URL serves your entire customer base, and the only variable is which of the 6 supported providers the person picks: Google, Microsoft, Yahoo, iCloud, IMAP, or Exchange. The request below starts a session at the authorization endpoint and carries a state value, which is how the callback gets tied back to the right user and tenant. Mint state as an unguessable, single-use token, never a raw user or tenant ID, so an attacker can’t forge a callback that links their mailbox to someone else’s account.
curl --request GET \ --url 'https://api.us.nylas.com/v3/connect/auth?client_id=<NYLAS_CLIENT_ID>&redirect_uri=https://myapp.com/callback&response_type=code&provider=google&state=<PER_USER_STATE>'The full code exchange at /v3/connect/token is covered in connect user accounts with OAuth.
How do SaaS companies typically handle OAuth token management across thousands of users?
Section titled “How do SaaS companies typically handle OAuth token management across thousands of users?”They stop managing provider tokens at all. With the Nylas hosted flow, the provider’s access and refresh tokens live on the grant, and the API refreshes the underlying token before it expires. Your database holds only a grant ID per account, so 5,000 connected mailboxes mean 5,000 non-secret identifiers instead of 5,000 refresh tokens you rotate yourself.
That split is the single biggest operational win at scale. There’s no cron job re-minting tokens, no encrypted token column, and no 401 storm when a batch of refresh tokens expires at once. A grant stays valid until the user or provider revokes it, and token refresh happens server-side without any code in your app. When you set access_type=online at authorization time the grant skips the refresh token and access ends with the session, but most server-side SaaS integrations want the default offline behavior. Keep the API key in a secrets manager, scope each grant to its tenant in your own table, and a leaked database row exposes an identifier, not working access to an inbox. The authentication best practices guide covers token hygiene in full.
How do I handle email authentication and OAuth for multiple enterprise customers?
Section titled “How do I handle email authentication and OAuth for multiple enterprise customers?”Use admin consent once per enterprise tenant, then connect that tenant’s people without per-user approval prompts. For Microsoft 365 customers, an administrator approves your application’s permissions in the Microsoft Entra admin center, which authorizes every account in that tenant in a single action instead of 200 individual consent screens.
Enterprise customers behave differently from self-serve signups in two ways. First, many block individual users from approving third-party apps, so application permissions sit unusable until an admin signs off. Second, they expect you to respect their tenant boundary. The admin consent model handles the first: the Microsoft admin approval guide walks through the Entra request flow, and Google Workspace offers a parallel domain-wide consent path. For the second, you enforce isolation in your own schema, since the API only ever sees individual grants and has no concept of a tenant. After consent clears, you can onboard a customer’s mailboxes in bulk rather than one interactive login at a time, as shown in bulk-authenticate user accounts.
How do I keep tenants isolated?
Section titled “How do I keep tenants isolated?”Tenant isolation lives entirely in your own database, because the API groups nothing: it sees grants, never tenants or users. Model a one-to-many chain, with 1 tenant pointing to many users and each user pointing to many grant rows. That table is the only place the tenant boundary exists.
Treat the tenant ID as a mandatory filter on every read. Before issuing any request, resolve the grant from your table scoped to the caller’s tenant, so a user in tenant A can never reach a grant that belongs to tenant B even if they guess its ID. The schema below keeps the riskiest data out of your store, holding the non-secret grant ID and your own metadata rather than provider tokens. Add a unique constraint on grant_id so the same mailbox isn’t linked twice, and index on tenant_id since nearly every query filters by it.
CREATE TABLE tenant_grants ( id BIGSERIAL PRIMARY KEY, tenant_id BIGINT NOT NULL REFERENCES tenants(id), user_id BIGINT NOT NULL REFERENCES users(id), grant_id TEXT NOT NULL UNIQUE, provider TEXT NOT NULL, email TEXT NOT NULL, created_at TIMESTAMPTZ NOT NULL DEFAULT now());CREATE INDEX idx_tenant_grants_tenant ON tenant_grants (tenant_id);How do I read mail for a tenant’s accounts?
Section titled “How do I read mail for a tenant’s accounts?”Every request targets one grant, so reading a tenant’s mail means looking up its grant IDs and issuing one call per grant against GET /v3/grants/{grant_id}/messages. The limit parameter accepts up to 200 results per page and defaults to 50, so keep it modest to stay under provider rate limits when you fan out across a tenant.
The call shape is identical across all 6 providers, so a Gmail grant and an Outlook grant run the same code with no branching. Resolve grants scoped to the tenant first, then map over them, tagging each result with its grant ID so the UI knows which account it came from.
curl --request GET \ --url 'https://api.us.nylas.com/v3/grants/<NYLAS_GRANT_ID>/messages?limit=20' \ --header 'Authorization: Bearer <NYLAS_API_KEY>'To merge several mailboxes per person into one view, see connect multiple accounts per user.
Self-managed OAuth vs Nylas multi-tenant OAuth
Section titled “Self-managed OAuth vs Nylas multi-tenant OAuth”Rolling your own multi-tenant OAuth means a separate integration per provider, each with its own consent model, ID formats, and token store. A unified layer collapses that into one flow and one schema across every provider. The table compares the work each approach takes for a SaaS app onboarding tenants at scale, where the per-provider tax compounds with every customer you add.
| Task | Self-managed OAuth | Nylas multi-tenant OAuth |
|---|---|---|
| Provider setup | One OAuth project per provider | 1 hosted flow for all 6 providers |
| Token storage | Encrypt and refresh tokens yourself | Store only the grant ID |
| Token refresh | A cron job re-minting tokens | Automatic, server-side |
| Enterprise consent | Wire admin consent per provider | Admin consent through one connector |
| Tenant isolation | Your schema | Your schema |
Be honest about the tradeoff: if your product targets exactly one provider and one tenant model, and you already run that provider’s OAuth, adding a unified layer buys little. The economics flip the moment you support a second provider or onboard enterprise customers who each want their own consent path.
What’s next
Section titled “What’s next”- Connect user accounts with OAuth for the single-account flow, scopes, and token refresh
- Connect multiple accounts per user to group several mailboxes under one person
- Bulk-authenticate user accounts to onboard a whole tenant after admin consent
- Authentication overview for the full grant model and every auth method