Overview
YorAuth splits OAuth provider integration across two services: yorauth-app manages configuration, credential storage, and connection records; yorauth-gate handles the browser-facing OAuth redirects and provider callbacks. This separation keeps OAuth credentials and raw tokens out of your application's request path.
Architecture
Your App / Hosted Login Page
|
| 1. User clicks "Sign in with Google"
v
yorauth-app
(creates OAuthState, redirects browser)
|
| 2. Browser follows redirect to gate
v
yorauth-gate ──────────────────────────► Google / GitHub / Microsoft
GET /oauth/{provider}?state=... (OAuth provider)
| |
| | 3. User authenticates
| | 4. Provider redirects back
v |
yorauth-gate ◄────────────────────────────────┘
GET /oauth/{provider}/callback?code=...&state=...
|
| 5. Gate validates state, exchanges code for tokens
| 6. Gate sends tokens to yorauth-app (internal API)
v
yorauth-app
(encrypts tokens, upserts OAuthConnection)
|
| 7. Returns connection_id to gate
v
yorauth-gate
(redirects browser back with connection_id)
|
v
Your App / Hosted Login Page
(receives connection_id, completes login)
Step-by-Step Flow
1. State Creation
Before the browser visits the gate, yorauth-app (or the hosted login page) creates an OAuthState record in the shared database. The state record includes:
state— a cryptographically random 64-character string used for CSRF protectionapplication_id— which application is initiating the flowprovider— the target OAuth provider (e.g.google)redirect_uri— where gate should redirect the browser after the callback completesexpires_at— 10 minutes from creation; gate rejects expired states
2. Gate Redirect
The browser is sent to https://gate.yorauth.com/oauth/{provider}?state={state}.
Gate validates the state exists in the database, is not expired, has not been used, and matches the requested provider. If the application has configured custom OAuth credentials, gate fetches them from yorauth-app's internal API (cached for 5 minutes). It then builds the provider redirect URL, injecting the state parameter, requested scopes, and any provider-specific options (such as access_type=offline for Google to obtain refresh tokens).
3. Provider Authentication
The user authenticates directly with the provider (Google, GitHub, etc.) and grants the requested scopes. The provider redirects back to gate's callback URL.
4. Callback and Token Exchange
Gate receives GET /oauth/{provider}/callback?code={code}&state={state}.
It performs the following checks:
- State exists in the database
- State has not already been used (single-use enforcement)
- State has not expired
- State matches the requested provider
The state is atomically marked as used before token exchange proceeds, preventing replay attacks. Gate exchanges the authorization code for tokens using the provider's token endpoint via Laravel Socialite.
5. Token Storage
Gate sends the raw tokens to yorauth-app via a signed internal API call. yorauth-app encrypts the access token and refresh token using Laravel's Crypt::encryptString() (AES-256-CBC) and upserts an OAuthConnection record. If a connection already exists for the same application, provider, and provider user ID, it is updated with fresh tokens; otherwise a new connection is created.
yorauth-app returns the connection_id (UUID) of the upserted connection.
6. Redirect to Your Application
Gate redirects the browser to the redirect_uri stored in the OAuthState, appending ?connection_id={uuid}. Your application can use this ID to complete the authentication flow (for example, resolving the user associated with the connection).
Security Properties
- CSRF protection — The
stateparameter is validated with exact match before any token exchange occurs. - Single-use states — Each state is atomically marked used before tokens are exchanged, preventing replay attacks.
- 10-minute expiry — States expire after 10 minutes, limiting the window for interception.
- Token encryption — Access tokens and refresh tokens are encrypted at rest using AES-256-CBC. Raw tokens are never stored in plaintext.
- Open redirect protection — Gate validates the
redirect_uriagainst an allowlist of schemes (HTTPS in production) before redirecting. - State consumed on provider error — If the provider returns an error (e.g. user denied access), the state is marked used to prevent it from being replayed.
Default Scopes
Each provider has default scopes that gate requests unless your configuration overrides them:
| Provider | Default Scopes |
|---|---|
openid, email, profile | |
| Microsoft | openid, email, profile, User.Read |
| GitHub | user:email, read:user |
email, public_profile | |
| Apple | name, email |
| Slack | identity.basic, identity.email, identity.avatar |
| Salesforce | openid, email, profile |
openid, email, profile | |
| Shopify | read_customers |
| Stripe | read_write |
You can override scopes per application when configuring a provider.
Configuration Modes
When configuring a provider for your application you choose one of two modes:
BYOA (Bring Your Own App) — You supply your own client_id and client_secret from the provider's developer console. Credentials are encrypted at rest. This mode gives you full control over branding, approved scopes, and usage limits.
YorAuth Managed — YorAuth provides a shared OAuth application for supported providers. No provider setup is required. Available on supported plans.
See Configuring Providers for the complete API reference.