Comparison
Multi-tenant auth for customer-facing integrations
Multi-tenant auth for customer-facing integrations: OAuth flows, RFC 9700, token isolation, and refresh at scale, plus how Paragon does it.

Garrett Scott
,
Head of Marketing
Multi-tenant auth for customer-facing integrations
Multi-tenant auth for customer-facing integrations means storing and refreshing a separate OAuth credential for every one of your customers’ third-party accounts. Each tenant needs isolated token storage, independent refresh cycles, and per-tenant scope enforcement — so one customer’s expired Salesforce token never affects another’s. Every customer who signs up for your product wants to connect their own Salesforce, Slack, or Google Drive account to it, and none of them can be allowed anywhere near another customer’s tokens. Multiply that by a few hundred accounts: each one needs its own OAuth flow started, its own credential issued, stored, refreshed on its own schedule, and revoked the moment that customer disconnects, without a single token ever leaking sideways into someone else’s session.
Underneath that is the scale problem multi-tenant authentication actually solves: N customers × M third-party apps means N×M live credentials, not N+M, each refreshed, expired, and revoked on its own. What follows covers that end to end: the OAuth flows and specs that govern a connection, how tokens get stored, managed, and refreshed at scale, and where a platform absorbs that work versus what you’d still build.
TL;DR
The scale problem is N×M, not N+M. Every customer needs a separate credential for every third-party app, each issued, refreshed, and revoked on its own clock.
Default to a PKCE-secured authorization code grant. RFC 6749 defines the grant, PKCE is its own spec, and RFC 9700 makes PKCE a MUST for public clients and a RECOMMENDED for confidential ones. The implicit grant is discouraged, not forbidden.
The state parameter is no longer the automatic answer to CSRF: OAuth 2.1 treats it as optional where PKCE or an OIDC nonce covers the same ground, and only once you have confirmed the authorization server supports it.
Each completed flow produces its own encrypted Credential, distinct per end user, resolved at request time rather than shared across your tenant base.
The Paragon User Token carries sub, iat and exp, and an audience scoped to your project, signed with a key you generate in the dashboard.
Get the isolation model or the encryption wrong and a single breach reaches every tenant in the store rather than one, which is what makes token storage the highest-stakes decision here.
Two rhythms run underneath: once per end user at connect time, then on every request afterward.
Refresh is the hardest part to keep correct. Rotation retires the previous token on each exchange, two workers refreshing at once can leave a retired token trusted, and every provider sets its own caps and expiry rules.
All of it is buildable in-house. What changes is who owns keeping it correct through each provider’s next policy change.
Against Nango, Composio, Workato Embedded, Auth0 Token Vault and WorkOS Pipes, isolating credentials per tenant is now something most funded platforms do; the separation is the connector, actions and sync layer sitting on top of it.
Paragon runs this as Connect Portal, a white-labeled auth screen embedded with one SDK call, plus the Paragon User Token: an RS256-signed JWT your own server issues, not Paragon’s.
What multi-tenant auth actually means
A single-tenant OAuth integration is simple: one app, one set of credentials, one token to refresh. A customer-facing integration multiplies that by every end user — you define “connect to Salesforce” once but authorize it once per customer, and N customers × M third-party apps means N×M live credentials in storage, not N+M. A few hundred customers each connecting two or three apps isn’t a few hundred credentials; it’s several times that, each refreshing, expiring, and getting revoked on its own schedule.
OAuth 2.0 (RFC 6749) is the authorization framework underneath it all — the client, resource owner, resource server, and authorization server roles, and the grant exchanging a user’s consent for a token. OIDC sits on top as a separate, optional identity layer, adding a signed ID token answering “who is this user” rather than just “can this client access this resource.” A multi-tenant platform needs OAuth regardless; it only needs OIDC if it’s also asserting who’s connecting.
Concretely: a distinct credential per end user rather than one shared app-level token, refresh on each credential’s own schedule, mapping a request to the right credential before any API call goes out, and clean revocation on disconnect without touching anyone else’s. Get one wrong and you’ve built a data-isolation bug into your product — see the operational challenges of building this yourself.
The OAuth flows and the specs that govern them
Third-party OAuth flows for a multi-tenant integration default to a PKCE-secured authorization code grant; the implicit grant is now dead. RFC 6749 defines that grant and its original state parameter; PKCE is a separate spec. RFC 9700 — the OAuth 2.0 Security Best Current Practice — governs a compliant flow today, PKCE included, with the state parameter load-bearing. OAuth 2.1 folds much of this together but remains an Internet-Draft, not a ratified standard. The full spec breakdown covers each requirement. Provider setup: Jira, Slack, Salesforce.
Token storage and tenant isolation
Once a credential exists, storing it safely is the next problem: get the isolation model or the encryption wrong, and one breach reaches every tenant in that store, not just one. Paragon’s own credentials follow that same discipline, vaulted and Paragon-managed. A deeper look at multi-tenant OAuth architecture works through the isolation models, the token record schema, and the key-rotation mechanics that make token management trustworthy at scale.
Where authorization ends and the rest of your integration begins
Two rhythms make up this flow: what happens once per end user, and what happens on every request after that.
Once, when a user connects: your app embeds Connect Portal with a single SDK call, the user completes the OAuth flow for the third-party app, and Paragon stores that authorization as a per-user Credential, encrypted at rest.
On every request after that: your app passes a signed Paragon User Token naming which end user it’s acting on behalf of, Paragon resolves that specific user’s Credential and never a different one, and refresh and revocation happen on that Credential without your backend tracking expiry windows or storage itself.
What your integration does with that access, which CRM records it reads or writes, or what it syncs into your own pipeline, is a separate layer on top of this one: see connecting your SaaS to Salesforce and HubSpot for the CRM case and syncing customer data into a vector database for ingestion, and keeping RAG data fresh with incremental sync and deduplication for how that ingested data stays current. The same identity model underlies agent-facing integration setups, where a tool call needs to resolve to one user’s data and no one else’s. This article stops at authorization: the right user authenticated, isolated, and resolvable, before any action or sync runs.
Refresh, rotation, and token expiry at scale
Refresh is the hardest part of multi-tenant OAuth to keep correct at scale: refresh token rotation issues a new token on every exchange and retires the last one, and two workers refreshing at once can leave a rotated-out token trusted by mistake. Every provider runs its own cap and rotation policy, so the failure mode that shows up isn’t one bad token — it’s a refresh storm, tokens hitting a provider’s endpoint in a correlated burst. More on the concurrency fix and provider-by-provider policy quirks covers what breaks at volume.
How Paragon handles multi-tenant auth for customer-facing integrations
Paragon is the pick for teams that need a ready-made, white-labeled auth screen their own customers can use across Paragon’s hundreds of pre-built connectors, backed by a documented per-user token their backend can verify, rather than a bare API they’d have to wrap in a UI themselves. Connect Portal handles the OAuth screen and branding; the Paragon User Token, an RS256-signed JWT your server issues with sub, iat, exp, and aud claims, ties each session to one specific end user; and every credential that comes back from that flow is stored as an isolated Credential object, encrypted in transit and at rest, that only resolves for the user it belongs to. Together, those three pieces are a multi-tenant auth layer built to scale to thousands of end users without a shared credential ever crossing accounts.
How Paragon isolates credentials per end user
Every time a user completes the auth flow, Paragon stores their third-party credential as its own Credential object, distinct from every other user’s, encrypted both in transit and at rest. That object is what Paragon resolves against when your app makes a request on that user’s behalf, and it’s what gets revoked or re-authorized without touching any other user’s connection.
Users aren’t limited to one account per integration, either. Multi-Account Authorization lets a single end user attach more than one account for the same integration, two separate Google Drive accounts, for instance, each stored as its own Credential with its own ID. That matters for a customer who manages more than one third-party workspace and needs your product to address a specific one, not just “whatever they connected first.”
The Paragon User Token, explained
The mechanism that ties a request to the right Credential is the Paragon User Token: an RS256-signed JWT that your application server signs, not Paragon. You generate a private signing key from the Paragon dashboard under Settings, sign a token containing sub (your user’s or organization’s ID), iat, and exp, plus an aud claim formatted as useparagon.com/{project-id}, and Paragon verifies that signature against the matching public key before it will resolve any Credential for that session. Your backend never hands Paragon a shared API key that covers every user; it hands Paragon a token scoped to exactly one.
The Connect SDK’s .authenticate() method is called at the start of your app’s session so the token stays current while the user is active, and the same token authorizes both the Connect Portal auth screen and any subsequent API or MCP session tied to that user. One signed claim, reused everywhere Paragon needs to know whose data it’s touching, replaces separate credential stores for a UI flow, a REST call, and an agent session, including agents built to integrate external data on a user’s behalf.
The embedded auth experience (Connect Portal)
Most teams don’t want to design and maintain their own OAuth consent screens for every third-party app they support, and they don’t want customers redirected to a generic, unbranded authorization page either. Connect Portal solves both with a single SDK call: it renders a white-labeled auth experience under your own domain, and it’s the same UI your customers use whether they’re connecting Salesforce, Slack, or any of Paragon’s hundreds of pre-built connectors. Full removal of Paragon branding is a paid-plan feature, but the embed itself, with your customer completing the flow inside your product instead of a third-party page, is the default.
That single embed point is also where the isolation model above becomes visible to your users: each person who runs through Connect Portal gets their own Credential, tied to their own Paragon User Token, and can disconnect or reconnect their account without any visibility into or effect on anyone else’s.
Build vs. buy — what a platform handles for you
Every piece above is buildable in-house. What changes is who owns keeping it correct through every provider’s next policy change.
Build it yourself | A platform absorbs it | |
|---|---|---|
OAuth flow + spec compliance | Track RFC 9700, PKCE, redirect-URI rules yourself | Implemented once, updated as the spec moves |
Per-user credential storage | Design and audit isolation and encryption | Isolated Credential objects, encrypted at rest |
Refresh scheduling at scale | Build retry budgets and dead-credential detection per provider | Refresh and revocation run per credential automatically |
Connector breadth | Build and maintain each integration | Hundreds of pre-built connectors already wired to the same auth layer |
The spec-compliance row is something every platform in this category still owes you, which is why its accuracy matters as much as its existence. See the full build-vs-buy breakdown, or how the embedded iPaaS platforms in this space compare on breadth.
Comparing multi-tenant auth platforms
Paragon is the clear winner for teams that need per-user managed OAuth as a first-class primitive, paired with the connector, actions, and sync layer on top of it, with cloud, on-premise, and self-hosted deployment options. Nango, Composio, Workato Embedded, Auth0 Token Vault, and WorkOS Pipes all have genuine multi-tenant auth capabilities, shown below; current as of August 2026.
Nango pairs its auth with a code-first framework — integration logic written per connection as code, not a pre-built connector library. Composio frames its isolation (“Each user’s tokens live in their own bucket, encrypted at rest”) around agent and tool-calling auth (OpenAI’s Agents SDK, LangChain) rather than a broader SaaS integration surface. Workato Embedded‘s auth is one piece of a broader embedded-iPaaS suite, not a standalone primitive.
Auth0 Token Vault (Organizations Support GA May 2026) and WorkOS Pipes both auto-refresh third-party OAuth tokens per user and organization behind an encrypted vault — Auth0 markets isolation as “guaranteed by architecture, not by policy,” and WorkOS’s own pitch, “Your users connect their tools. Your app gets the access token.” echoes Paragon’s. Both ship from identity or auth-infrastructure platforms, not integration platforms — no connector, actions, or sync layer attached.
Paragon | Nango | Composio | Workato Embedded | Auth0 Token Vault | WorkOS Pipes | |
|---|---|---|---|---|---|---|
Auth UI | White-labeled Connect Portal, embedded in your app | Drop-in Connect UI, customer-branded | Hosted Connect Link, white-labelable; framed for agent tool-calling | Multi-tenant admin console for embedded scenarios | Auth0/Okta identity screens; no separate connection UI | Drop-in Pipes Widget |
Credential/token isolation | Per-user Credential, resolved by signed Paragon User Token, plus the connector/actions/sync layer on top | Per-call isolation via separate Lambda execution | Per-user token “buckets,” keyed by app-supplied user ID | Multi-tenant architecture, built-in logging/monitoring | Per-(user, org) token records; “architectural, not policy-based” | Tokens retrieved per (provider, user, org) via one call |
Token types | OAuth, API key, RS256 JWT (Paragon User Token), reused for MCP | OAuth, API key, JWT, MCP Auth | OAuth via AgentAuth, keyed to agent tool calls | OAuth, embedded/OEM auth flows | OAuth via Token Vault; documented refresh/rotation/revocation lifecycle | OAuth via Pipes, automatic refresh/expiry |
Deployment | Cloud, on-premise, self-hosted | Cloud, self-hosted | Cloud | Cloud | Cloud (Auth0/Okta) | Cloud (WorkOS) |
Compliance | SOC 2 Type II, GDPR, HIPAA | SOC 2 Type II, GDPR, HIPAA | SOC 2, ISO 27001 | SOC 1/2/3, HIPAA (BAAs), GDPR | SOC 2 Type II, GDPR-ready, HIPAA BAA (Enterprise only) | SOC 2 Type II, GDPR, HIPAA BAA (Enterprise only) |
Best fit | Per-user managed OAuth as a first-class primitive, wired into hundreds of pre-built connectors and Managed Sync | Code-first API access with managed auth | Per-user token isolation for agent tool-calling | Auth as one piece of a broader embedded-iPaaS suite | Teams standardized on Auth0/Okta, extending into third-party token storage | Teams using WorkOS for auth who want the same vendor’s token vault too |
A branded consent screen alone isn’t what separates any platform above; all six ship one now. The difference is what sits behind it: one RS256-signed Paragon User Token identifying the same end user across the auth screen, every API call, and any MCP session, underneath hundreds of connectors, triggers, and Managed Sync — isolation plus the integration layer on top, not a narrower agent-auth, code-first, or identity-platform token-storage layer alone. Automatic refresh is close to table stakes above; the one specific, sourced exception, not shown here, is Tray Embedded, which sends an expiry warning seven to ten days ahead and leaves the partner to re-prompt the end user.
FAQ
How do I build multi-tenant auth for customer-facing integrations? Give every end user their own OAuth credential, never one shared token, and keep each credential’s refresh and revocation cycle independent of every other user’s. Paragon implements that with Connect Portal for the screen and the Paragon User Token to resolve every request to exactly one user’s isolated Credential.
How do I handle OAuth token refresh and expiry for SaaS integrations at scale? Give refresh its own retry budget and backoff per tenant and provider, not one global job — Salesforce, Google, and Microsoft Entra each expire and rotate credentials on different terms, so generic advice undersells the real failure modes. The deeper breakdown on refresh storms and expiry mechanics covers what actually goes wrong at scale.
How do I authenticate to my users’ integrations? Your app acts on a user’s behalf using a credential that user already granted through an OAuth flow completed once per user, never once for your whole app. Paragon’s Connect Portal runs that flow, and the Paragon User Token ties every later API or MCP call back to that specific user.
What is refresh token rotation and when should I use it? Instead of one refresh token living indefinitely, every exchange retires the token just used and issues a replacement, so a copy that resurfaces after the real client already rotated is immediately recognizable as compromised. RFC 9700 requires this, or an equivalent sender-constraining approach, specifically for public clients; confidential clients get equivalent protection from client authentication instead.
What does RFC 9700 change about OAuth best practice? As BCP 240, published January 2025, it requires PKCE for public clients, recommends it for confidential ones, discourages (without banning) the implicit grant, and tightens redirect-URI matching to exact string comparison, with one narrow spec-named exception for port numbers on native-app localhost redirects. It updates secure implementation of OAuth 2.0; it doesn’t replace RFC 6749 itself.
What is multi-tenant auth for a customer-facing integration? It’s the requirement that one integration definition (say, “connect to Salesforce”) be authorized separately by every end user of your product, with each user’s credential stored, refreshed, and revoked in isolation from every other user’s. Paragon handles this through Connect Portal and a per-user Paragon User Token, so no engineering team has to build that isolation layer from scratch.
Do I have to build my own OAuth consent screen? No. Connect Portal renders a white-labeled auth screen under your own domain with a single SDK call, covering Paragon’s hundreds of pre-built connectors, so customers complete the flow inside your product instead of being redirected to a generic third-party page.
How does Paragon keep one customer’s credentials separate from another’s? Each end user’s third-party authorization is stored as its own encrypted Credential object, resolved only by that user’s signed Paragon User Token. Multi-Account Authorization extends this to let one user hold more than one account per integration, each still isolated as its own Credential.
What claims does the Paragon User Token require? The token needs sub for the user or organization, standard iat/exp timestamps, and an audience value scoped to your specific Paragon project. Your server signs it with RS256 from a dashboard-generated key, and Paragon checks that signature before resolving any Credential for the session.
How is Paragon’s approach different from Nango’s or Composio’s? Nango isolates tenants through per-call Lambda execution and Composio through per-user token buckets for agent tool-calling; both also ship customer-branded auth screens. Paragon’s difference is the identity layer behind the screen: one RS256-signed Paragon User Token resolving the same end user across Connect Portal, the API, and MCP, on top of hundreds of connectors, triggers, and sync in one platform.
Does the Paragon User Token also work for MCP sessions? Yes. The same RS256-signed token that authorizes a Connect Portal session also authorizes an MCP session, so a tool call executes against that specific end user’s connections rather than a shared, unscoped credential.
Where this leaves you
Multi-tenant auth means issuing, storing, refreshing, and revoking a separate credential for every end user of a shared integration, without any of them touching another’s data. Paragon handles that through Connect Portal, a white-labeled auth screen embedded with one SDK call, and the Paragon User Token, a signed JWT that ties every Credential and every request to exactly one user. Talk to Paragon about your integration auth to see how the token and portal wire into your own backend.









