How to Handle OAuth Across Many Integrations
March 9, 2026
The most effective way to handle OAuth across many integrations is to centralize authorization into a single system that manages provider configuration, token storage, refresh logic, scopes, and error handling across all integrations.
Once your product integrates with more than a few APIs, OAuth becomes infrastructure—not per-integration code.
Without this shift, teams quickly run into scaling issues: broken tokens, inconsistent scopes, race conditions, and brittle refresh logic.
Why OAuth becomes a bottleneck at scale
OAuth 2.0 is a standard, but in practice every provider implements it differently.
When integrating with platforms like Google, Slack, Salesforce, HubSpot, and Microsoft, you encounter:
- different OAuth flows (authorization_code, client_credentials, API keys)
- inconsistent scope naming (contacts.read vs read_contacts)
- different token formats and expiration rules
- refresh token rotation vs static refresh tokens
- redirect URI inconsistencies
- HTML vs JSON error responses
- varying rate limits and retry requirements
Each new integration introduces new edge cases.
At 5 integrations, this is manageable.
At 20+, it becomes a system reliability problem.
Core architecture for managing OAuth at scale
1. Centralized token store
All tokens should be stored in a single, secure system.
Each record should include:
- user_id or tenant_id
- provider
- access_token
- refresh_token
- expires_at
- scopes
Best practices:
- encrypt tokens at rest (AES-256)
- use envelope encryption with systems like AWS KMS or HashiCorp Vault
- always scope queries per tenant (never global access)
This becomes your single source of truth for all integrations.
2. Unified OAuth service layer
Instead of handling OAuth separately for every API, build a shared service that handles:
- authorization URL generation
- callback handling
- token exchange
- token refresh
- revocation handling
Typical interface:
- getAuthorizationUrl(provider, user)
- exchangeCode(provider, code)
- refreshToken(connectionId)
- getValidToken(connectionId)
This removes duplicated logic across integrations.
3. Standardized redirect handling
Use a single callback endpoint:
/auth/callback
Use the state parameter to encode:
- provider
- tenant_id
- nonce
This allows one endpoint to handle all integrations safely.
4. Proactive token refresh
Never wait for a 401.
Instead:
- refresh tokens before expiration (e.g. 5–10 minutes early)
- run background workers to manage refresh cycles
- track expiration centrally
This prevents production failures and improves reliability.
5. Concurrency-safe token refresh
One of the most common failure points is race conditions.
Without protection:
- multiple requests trigger refresh simultaneously
- refresh tokens get overwritten
- tokens become invalid
Solution: locking
Single instance:
- in-memory locks
Distributed systems:
- Redis-based locking (e.g. Redlock)
Example pattern:
- only one refresh runs per connection
- all other requests wait for completion
This avoids token corruption.
6. Scope normalization
Every provider defines scopes differently.
Examples:
- contacts.read
- read_contacts
- crm.objects.contacts.read
To manage this:
- define internal 'unified scopes'
- map provider scopes to internal ones
This simplifies permission management across integrations.
7. API request guardrails
Every API request should:
- validate token freshness
- retry on 401 with refresh
- respect provider rate limits
- handle provider-specific errors
This logic should live in your OAuth layer—not in product code.
Operational challenges teams underestimate
Most teams don't struggle with OAuth setup.
They struggle with operating OAuth at scale.
Common issues include:
Token drift
Tokens expire at different times across integrations.
Revocations
Users disconnect apps externally, breaking integrations silently.
Refresh failures
Invalid_grant errors force re-authentication.
Rate limits
Some providers throttle token refresh aggressively.
Observability gaps
Teams don't know when connections are broken.
Without centralized handling, these issues multiply quickly.
Build vs buy: OAuth infrastructure
At small scale, teams build OAuth internally.
At scale, many adopt tools like:
These tools help with:
- OAuth flows
- token storage
- refresh logic
- provider configuration
However, they still introduce tradeoffs:
- additional infrastructure layer
- data handling considerations
- limitations across integration depth
- need to coordinate with your API layer
How Unified handles OAuth across 415+ integrations
At Unified, OAuth is treated as part of the integration infrastructure—not a separate system.
Instead of managing OAuth alongside integrations, we unify it into the same layer.
This includes:
Unified OAuth abstraction
- supports all major OAuth flows
- normalizes provider differences
- handles API keys and token-based auth
Single redirect model
- one standardized callback endpoint
- no per-provider configuration complexity
Unified scope system
- abstract scopes like crm_contact_read
- mapped to provider-specific permissions
Automatic token lifecycle management
- encrypted storage
- automatic refresh
- provider-specific handling
- failure detection and connection health tracking
Standardized error handling
- consistent 401 / 403 / 400 responses
- no provider-specific parsing
Connection-based security
- each integration tied to a scoped connection
- permissions enforced at the connection level
Why this matters for SaaS products
OAuth complexity directly impacts:
- time to launch integrations
- reliability in production
- customer onboarding experience
- support burden
- security and compliance
When OAuth is fragmented:
- integrations break silently
- engineers spend time debugging auth issues
- customers must reconnect frequently
When OAuth is centralized:
- integrations behave consistently
- failures are predictable and visible
- onboarding becomes faster
- systems scale cleanly
Key takeaways
If you're building SaaS integrations:
- treat OAuth as infrastructure, not feature code
- centralize token storage and lifecycle management
- normalize scopes and redirect flows
- implement concurrency-safe refresh logic
- build observability into connection health
And most importantly:
The complexity is not in the OAuth handshake.
It's in managing OAuth reliably across dozens or hundreds of integrations.