Laravel 12 WorkOS Integration Guide 2025: Complete Setup Tutorial for Enterprise Authentication

Building a B2B SaaS application in 2025? Then you've probably heard enterprise customers asking for features like "Can you support our company's Single Sign-On?" or "We need to sync users from our Active Directory." These enterprise requirements can take months to build from scratchโ€”but what if I told you there's a better way?

Enter WorkOS: a developer-friendly platform that brings enterprise-grade authentication to Laravel 12 applications in minutes, not months. In this comprehensive guide, we'll walk through everything you need to know about integrating WorkOS with Laravel 12, from basic setup to advanced features like SSO, Directory Sync, and role-based access control.

Whether you're starting a new Laravel project or adding enterprise features to an existing application, this tutorial will show you exactly how to implement WorkOS AuthKit, configure SSO providers, set up SCIM provisioning, and deploy production-ready authentication that will impress your enterprise customers. Let's dive in!

๐ŸŽฏ What You'll Learn: Complete WorkOS integration with Laravel 12, AuthKit setup, SSO configuration, Directory Sync, SCIM provisioning, roles & permissions, Magic Auth, Passkeys, and production deployment best practices.


What is WorkOS? Understanding the Platform

Before we jump into code, let's understand what makes WorkOS special. WorkOS is a modern API platform designed specifically for developers building B2B SaaS applications who need enterprise-ready features without the complexity.

Think of WorkOS as your "enterprise features as a service" platform. Instead of spending 3-6 months building SAML SSO, SCIM provisioning, audit logs, and admin portals from scratch, you integrate WorkOS and get all these features through simple API calls. It's like having an enterprise authentication team working for you!

Core Features of WorkOS

  • AuthKit (User Management): Complete authentication system with social login, Magic Auth, Passkeys, and MFA
  • Single Sign-On (SSO): Support for SAML and OIDC protocols with all major identity providers (Okta, Azure AD, Google Workspace, etc.)
  • Directory Sync: Automatic user provisioning using SCIM from corporate directories
  • Admin Portal: Self-service interface for your customers to configure SSO and manage their organization
  • Audit Logs: Compliance-ready logging for security and regulatory requirements
  • Organizations: Multi-tenant architecture with built-in organization management

Why Choose WorkOS for Laravel Applications?

If you're building a Laravel app that sells to businesses (B2B), WorkOS solves several critical challenges:

  • Speed to Market: Launch enterprise features in hours instead of months
  • Free for Growth: Up to 1 million monthly active users completely free
  • Laravel Native: Official Laravel 12 starter kits with WorkOS pre-configured
  • Developer Experience: Clean APIs, excellent documentation, and Laravel SDK
  • Enterprise Sales: Close deals faster when you can say "Yes" to SSO requirements
  • Security & Compliance: SOC 2 Type II certified infrastructure
  • Focus on Your Product: Stop building authentication plumbing, build your core features

๐Ÿ’ก Real Talk: Building SAML SSO from scratch typically takes 2-3 months of development time. With WorkOS, you can have it running in an afternoon. That's 2-3 months you can spend building features that differentiate your product!


WorkOS AuthKit: Your Complete Authentication Solution

WorkOS AuthKit is a complete authentication platform that handles everything from user registration to enterprise SSO. It's the fastest way to add production-ready authentication to your Laravel 12 application.

Authentication Methods Supported

AuthKit supports multiple authentication methods that you can enable or disable based on your needs:

  • Email + Password: Traditional authentication (can be disabled for better security)
  • Social Login: Google, GitHub, Microsoft, Apple authentication
  • Magic Auth: Passwordless authentication via email magic links
  • Passkeys (WebAuthn): Modern biometric authentication for ultimate security
  • Enterprise SSO: SAML and OIDC for corporate identity providers
  • Multi-Factor Authentication: TOTP-based MFA for enhanced security

Key AuthKit Features

  • Pre-Built UI: Beautiful, customizable authentication screens that match your brand
  • Session Management: Secure session handling with configurable timeouts
  • User Profiles: Normalized user data across all authentication methods
  • Organizations: Multi-tenant support with role-based access control
  • Email Verification: Built-in email verification workflows
  • Account Recovery: Secure password reset and account recovery flows
  • Customizable Branding: Match WorkOS UI to your application's design

โš ๏ธ Security Tip: WorkOS recommends disabling traditional email/password authentication and using modern methods like Magic Auth or Passkeys. These methods are more secure, have better user experience, and eliminate password-related security risks!


Prerequisites: What You Need Before Starting

Before we begin integrating WorkOS with Laravel 12, make sure you have the following requirements in place:

System Requirements

  • PHP: Version 8.2, 8.3, or 8.4 (Laravel 12 requirement)
  • Composer: Latest version (2.7+) for dependency management
  • Laravel 12: Fresh installation or existing project
  • Database: MySQL 8.0+, PostgreSQL 12+, or SQLite
  • Node.js: Version 18+ (for frontend asset compilation)

Required Accounts

  • WorkOS Account: Sign up for free at dashboard.workos.com
  • Development Environment: Local development server or cloud platform

Check Your Setup

# Verify PHP version
php -v
# Should show PHP 8.2.0 or higher

# Check Composer
composer --version
# Should show Composer 2.7+ 

# Verify Node.js
node --version
# Should show v18.0.0 or higher

Step 1: Create Your WorkOS Account

Let's start by setting up your WorkOS account. This is quick and completely free for up to 1 million monthly active users.

Sign Up for WorkOS

  1. Visit WorkOS Dashboard
  2. Sign up with your email or use GitHub/Google authentication
  3. Verify your email address
  4. Create your first WorkOS environment (you'll get both staging and production)

Get Your API Credentials

After signing up, you'll need to grab your API keys from the WorkOS Dashboard:

  1. Navigate to the API Keys section in your dashboard
  2. Copy your Client ID
  3. Copy your API Key (keep this secret!)
  4. Note: Start with staging keys for development, switch to production keys when deploying

๐Ÿ” Security Warning: Never commit your WorkOS API keys to version control! Always use environment variables and keep your .env file out of Git. Your API keys provide full access to your WorkOS account.


Step 2: Install Laravel 12 with WorkOS Starter Kit

Laravel 12 makes WorkOS integration incredibly easy with official starter kit support. You can get a fully configured authentication system in minutes!

Method 1: Fresh Laravel 12 Project with WorkOS (Recommended)

If you're starting a new project, this is the fastest path:

# Create a new Laravel 12 project
laravel new my-workos-app

# Follow the interactive prompts:
# 1. Name your application
# 2. Choose "React" or "Vue" starter kit
# 3. Select "WorkOS" as authentication provider
# 4. Choose testing framework (Pest recommended)

# Navigate to your project
cd my-workos-app

Method 2: Add WorkOS to Existing Laravel 12 Project

Already have a Laravel 12 app? No problem! Install Laravel Breeze with WorkOS support:

# Install Laravel Breeze
composer require laravel/breeze --dev

# Run Breeze installation with WorkOS
php artisan breeze:install

# Select your stack:
# - Choose "React" or "Vue"
# - Select "WorkOS" for authentication
# - Choose your preferred testing framework

# Install dependencies
npm install

# Build assets
npm run dev

Method 3: Manual WorkOS SDK Installation

For maximum control or to integrate WorkOS into a custom authentication setup:

# Install WorkOS PHP SDK
composer require workos/workos-php

# The SDK is now available in your Laravel application

Step 3: Configure WorkOS in Laravel

Now let's connect your Laravel application to WorkOS by configuring your environment variables.

Update Your .env File

Open your .env file and add your WorkOS credentials:

# WorkOS Configuration
WORKOS_CLIENT_ID=your-client-id-here
WORKOS_API_KEY=your-api-key-here
WORKOS_REDIRECT_URL="http://localhost:8000/authenticate"

# Application URL (important for redirects)
APP_URL=http://localhost:8000

# Session Configuration (match WorkOS timeout)
SESSION_LIFETIME=120  # 120 minutes = 2 hours

Replace your-client-id-here and your-api-key-here with the actual values from your WorkOS Dashboard.

Understanding the Configuration

  • WORKOS_CLIENT_ID: Public identifier for your WorkOS application
  • WORKOS_API_KEY: Secret key for server-side API calls (keep this private!)
  • WORKOS_REDIRECT_URL: Where users return after authentication
  • SESSION_LIFETIME: Should match WorkOS inactivity timeout (default 120 minutes)

Step 4: Configure Redirect URIs in WorkOS Dashboard

WorkOS needs to know where to send users after they authenticate. Let's configure the redirect URIs in the WorkOS Dashboard.

Configure Redirects

  1. Log in to your WorkOS Dashboard
  2. Navigate to the Redirects section
  3. Add the following URLs for local development:
# Sign-in callback (where users return after login)
http://localhost:8000/authenticate

# Homepage URL (where users land after successful auth)
http://localhost:8000/

# Logout redirect URL (where users go after logout)
http://localhost:8000/

For Production Deployment

When deploying to production, add your production URLs as well:

# Production callback
https://yourdomain.com/authenticate

# Production homepage
https://yourdomain.com/

# Production logout redirect
https://yourdomain.com/

๐Ÿ’ก Pro Tip: WorkOS supports wildcard redirect URIs! You can use patterns like https://*.yourdomain.com/authenticate to handle multiple subdomains. This is perfect for multi-tenant applications!


Step 5: Choose Your Authentication Methods

One of the best features of WorkOS is flexibility in authentication methods. Let's configure which methods your users can use to sign in.

Configure Authentication in Dashboard

  1. In your WorkOS Dashboard, go to Authentication section
  2. You'll see all available authentication methods
  3. Toggle the methods you want to enable for your application

Available Authentication Methods

1. Email + Password (Traditional)

Standard username/password authentication. While familiar, it's less secure than modern alternatives. Consider disabling it in favor of passwordless options.

To disable Email + Password:
1. Navigate to Authentication > Configure Email + Password
2. Toggle the switch to OFF
3. Save changes

2. Social Login (OAuth Providers)

Allow users to sign in with existing accounts:

  • Google: Perfect for B2B apps, most businesses use Google Workspace
  • GitHub: Great for developer-focused applications
  • Microsoft: Essential for enterprises using Office 365/Azure AD
  • Apple: Required for iOS apps, great for privacy-conscious users

To enable social login, you'll need to create OAuth apps with each provider and add the credentials to WorkOS.

3. Magic Auth (Passwordless Email Links)

The modern, secure way to authenticate. Users receive a magic link via emailโ€”click it, and they're logged in. No passwords to remember or manage!

Benefits of Magic Auth:
โœ“ No password to forget
โœ“ No password database to secure
โœ“ Better user experience
โœ“ Reduced support tickets
โœ“ Improved security (no password reuse)

4. Passkeys (WebAuthn)

The future of authentication! Passkeys use biometric authentication (Face ID, Touch ID, Windows Hello) or hardware security keys. They're phishing-resistant and incredibly user-friendly.

5. Enterprise SSO (SAML/OIDC)

For enterprise customers who need to use their corporate identity provider. We'll cover this in detail in the SSO section below.

Recommended Configuration for 2025

Modern, Secure Setup:
โœ“ Magic Auth (passwordless email) - Primary method
โœ“ Passkeys (WebAuthn) - For returning users
โœ“ Social Login (Google, GitHub) - User choice
โœ“ Enterprise SSO - For business customers
โœ— Email + Password - DISABLED (security risk)

Step 6: Synchronize Session Timeouts

To ensure consistent user experience, your Laravel session timeout should match your WorkOS inactivity timeout. This prevents confusing scenarios where users are logged out of one system but not the other.

Configure WorkOS Session Timeout

  1. In WorkOS Dashboard, navigate to Sessions
  2. Click "Configure session lifetime"
  3. Set Inactivity timeout to 120 minutes (2 hours)
  4. This matches Laravel's default session lifetime

Verify Laravel Session Configuration

Check your .env file:

# Session lifetime in minutes (default is 120)
SESSION_LIFETIME=120

# Session driver (default is file, use redis or database for production)
SESSION_DRIVER=file

# Session cookie name
SESSION_COOKIE=${APP_NAME}_session

Production Session Recommendations

For production applications, consider these session configurations:

# Use Redis for session storage (faster, scalable)
SESSION_DRIVER=redis
REDIS_CLIENT=predis
REDIS_HOST=127.0.0.1
REDIS_PORT=6379

# Or use database sessions
SESSION_DRIVER=database

# Then run: php artisan session:table
# Then run: php artisan migrate

Step 7: Test Your Authentication Flow

Now comes the exciting partโ€”let's test that everything works! WorkOS provides a test organization in your staging environment so you can try the authentication flow end-to-end.

Start Your Laravel Development Server

# Start Laravel development server
php artisan serve

# In another terminal, start the Vite dev server
npm run dev

# Your app is now running at http://localhost:8000

Test the Login Flow

  1. Open your browser and navigate to http://localhost:8000
  2. Click on "Login" or "Register"
  3. You'll be redirected to WorkOS's hosted authentication page
  4. Try signing in with the test organization provided by WorkOS
  5. After successful authentication, you'll be redirected back to your Laravel app

Using WorkOS Test Organization

WorkOS provides a "Test Organization" in staging that uses a mock identity provider:

  1. Go to your WorkOS Dashboard
  2. Navigate to Test SSO page
  3. You'll see test credentials and can simulate various login scenarios
  4. Use these to test SSO without setting up a real identity provider

What to Test

  • โœ“ User registration with different authentication methods
  • โœ“ Login and logout flows
  • โœ“ Session persistence (close browser, reopen - should stay logged in)
  • โœ“ Session timeout (wait 2 hours, should be logged out)
  • โœ“ Invalid credentials handling
  • โœ“ Redirect URI handling

๐ŸŽ‰ Success! If you can log in and see your user profile, congratulations! You've successfully integrated WorkOS with Laravel 12. You now have enterprise-ready authentication running in your application!


Implementing Enterprise SSO in Laravel

Single Sign-On (SSO) is the #1 feature enterprise customers request. It allows their employees to use their corporate credentials (like Okta, Azure AD, Google Workspace) to access your application. Let's implement it!

Understanding SSO in WorkOS

WorkOS makes SSO incredibly simple by handling all the complex SAML and OIDC protocol details. You don't need to understand the XML schemas or cryptographic signaturesโ€”WorkOS does that for you.

Two Ways to Implement SSO

Option A: Using AuthKit (Recommended)

If you're using WorkOS AuthKit (which we set up earlier), SSO is already available! Enterprise customers can enable SSO from their organization settings, and it just works. No additional code needed!

Option B: Standalone SSO API

For custom authentication flows or if you're integrating SSO into an existing auth system, use the standalone API:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use WorkOS\WorkOS;

class SSOController extends Controller
{
    private $workos;

    public function __construct()
    {
        $this->workos = new WorkOS(env('WORKOS_API_KEY'));
    }

    /**
     * Initiate SSO authentication
     */
    public function initiate(Request $request)
    {
        $organizationId = $request->input('organization');
        
        // Generate authorization URL
        $authorizationUrl = $this->workos->sso->getAuthorizationUrl([
            'organization' => $organizationId,
            'clientId' => env('WORKOS_CLIENT_ID'),
            'redirectUri' => env('WORKOS_REDIRECT_URL'),
            'state' => csrf_token(), // Use for security
        ]);

        // Redirect user to WorkOS for authentication
        return redirect($authorizationUrl);
    }

    /**
     * Handle SSO callback
     */
    public function callback(Request $request)
    {
        $code = $request->input('code');
        
        // Exchange code for user profile
        $profile = $this->workos->sso->getProfile([
            'code' => $code,
            'clientId' => env('WORKOS_CLIENT_ID'),
        ]);

        // IMPORTANT: Always validate the organization
        $organizationId = $profile->organizationId;
        
        // Find or create user in your database
        $user = User::firstOrCreate(
            ['email' => $profile->email],
            [
                'name' => $profile->firstName . ' ' . $profile->lastName,
                'workos_id' => $profile->id,
                'organization_id' => $organizationId,
            ]
        );

        // Log the user in
        auth()->login($user);

        return redirect('/dashboard');
    }
}

Register SSO Routes

<?php

use App\Http\Controllers\SSOController;
use Illuminate\Support\Facades\Route;

// Initiate SSO
Route::get('/sso/initiate', [SSOController::class, 'initiate'])
    ->name('sso.initiate');

// SSO callback
Route::get('/sso/callback', [SSOController::class, 'callback'])
    ->name('sso.callback');

Setting Up SSO for a Customer

When an enterprise customer wants to enable SSO:

  1. Create an Organization in WorkOS: Each customer gets their own organization
  2. Configure their Identity Provider: They provide their SAML metadata or OIDC settings
  3. Test the Connection: Use WorkOS test SSO feature to verify
  4. Go Live: Enable SSO for their organization

WorkOS even provides an Admin Portal that your customers can use to configure SSO themselves, reducing your support burden!

Supported Identity Providers

  • Okta
  • Azure AD / Microsoft Entra ID
  • Google Workspace
  • OneLogin
  • Auth0
  • Ping Identity
  • JumpCloud
  • Any SAML 2.0 or OIDC compliant provider

Directory Sync and SCIM Provisioning

Directory Sync automatically keeps your application's user list in sync with your customer's corporate directory. When an employee is hired, fired, or changes roles, those changes are automatically reflected in your app. This is powered by the SCIM (System for Cross-domain Identity Management) protocol.

Why Directory Sync Matters

Imagine this scenario: A customer has 500 employees. One employee leaves the company. Without Directory Sync, they need to manually remove that user from your application (and 50 other SaaS tools). With Directory Sync, it happens automatically when they're removed from Active Directory or Okta.

What Gets Synced

  • Users: Employee information (name, email, job title, etc.)
  • Groups: Department or team memberships
  • User Status: Active, suspended, or deactivated
  • Profile Updates: Name changes, email updates, etc.

Setting Up Directory Sync

WorkOS handles the complex SCIM implementation. You just need to handle the webhook events:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use App\Models\User;

class WorkOSWebhookController extends Controller
{
    /**
     * Handle WorkOS webhooks
     */
    public function handle(Request $request)
    {
        // Verify webhook signature (important for security!)
        $signature = $request->header('WorkOS-Signature');
        // Verify signature matches (implement signature verification)

        $event = $request->input('event');
        $data = $request->input('data');

        // Handle different event types
        switch ($event) {
            case 'dsync.user.created':
                $this->handleUserCreated($data);
                break;

            case 'dsync.user.updated':
                $this->handleUserUpdated($data);
                break;

            case 'dsync.user.deleted':
                $this->handleUserDeleted($data);
                break;

            case 'dsync.group.created':
                $this->handleGroupCreated($data);
                break;

            case 'dsync.group.user_added':
                $this->handleUserAddedToGroup($data);
                break;

            case 'dsync.group.user_removed':
                $this->handleUserRemovedFromGroup($data);
                break;
        }

        return response()->json(['status' => 'success']);
    }

    private function handleUserCreated($data)
    {
        User::create([
            'email' => $data['email'],
            'name' => $data['first_name'] . ' ' . $data['last_name'],
            'workos_user_id' => $data['id'],
            'directory_id' => $data['directory_id'],
            'state' => $data['state'], // active, inactive, suspended
        ]);

        Log::info('User created via Directory Sync', ['email' => $data['email']]);
    }

    private function handleUserUpdated($data)
    {
        $user = User::where('workos_user_id', $data['id'])->first();
        
        if ($user) {
            $user->update([
                'name' => $data['first_name'] . ' ' . $data['last_name'],
                'email' => $data['email'],
                'state' => $data['state'],
            ]);

            Log::info('User updated via Directory Sync', ['email' => $data['email']]);
        }
    }

    private function handleUserDeleted($data)
    {
        $user = User::where('workos_user_id', $data['id'])->first();
        
        if ($user) {
            // Soft delete or deactivate the user
            $user->update(['state' => 'inactive']);
            // Or: $user->delete();

            Log::info('User deleted via Directory Sync', ['email' => $user->email]);
        }
    }

    private function handleGroupCreated($data)
    {
        // Create team/department in your system
        Log::info('Group created via Directory Sync', ['name' => $data['name']]);
    }

    private function handleUserAddedToGroup($data)
    {
        // Add user to team/department
        Log::info('User added to group via Directory Sync');
    }

    private function handleUserRemovedFromGroup($data)
    {
        // Remove user from team/department
        Log::info('User removed from group via Directory Sync');
    }
}

Register Webhook Route

<?php

use App\Http\Controllers\WorkOSWebhookController;
use Illuminate\Support\Facades\Route;

// Exclude from CSRF protection in app/Http/Middleware/VerifyCsrfToken.php
Route::post('/webhooks/workos', [WorkOSWebhookController::class, 'handle'])
    ->name('workos.webhook');

Configure Webhook in WorkOS

  1. Go to WorkOS Dashboard โ†’ Webhooks
  2. Add your webhook URL: https://yourdomain.com/webhooks/workos
  3. Select the events you want to receive
  4. Save and test the webhook

๐Ÿ’ก Enterprise Win: Directory Sync is a huge selling point for enterprise customers! Being able to say "Yes, we support automatic user provisioning via SCIM" can make or break a deal with large organizations.


Implementing Roles and Permissions

WorkOS AuthKit includes built-in support for roles and permissions, making it easy to implement role-based access control (RBAC) in your Laravel application. As of 2025, AuthKit even supports multiple roles per user!

Define Roles in WorkOS Dashboard

  1. Navigate to Roles in WorkOS Dashboard
  2. Create roles like: Admin, Manager, Member, Viewer
  3. Define permissions for each role
  4. Assign roles to users in their organization

Using Roles in Laravel

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class DashboardController extends Controller
{
    public function index(Request $request)
    {
        $user = $request->user();
        
        // Get user's roles from WorkOS
        $roles = $user->workos_roles; // Assumes you store this
        
        // Check if user has specific role
        if (in_array('admin', $roles)) {
            // Admin-only functionality
            return view('dashboard.admin');
        }
        
        if (in_array('manager', $roles)) {
            // Manager functionality
            return view('dashboard.manager');
        }
        
        // Default member view
        return view('dashboard.member');
    }
}

Create a Role Middleware

# Generate middleware
php artisan make:middleware CheckRole
<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;

class CheckRole
{
    public function handle(Request $request, Closure $next, string $role)
    {
        $user = $request->user();
        
        if (!$user) {
            return redirect('/login');
        }
        
        // Check if user has required role
        $roles = $user->workos_roles ?? [];
        
        if (!in_array($role, $roles)) {
            abort(403, 'Unauthorized action.');
        }
        
        return $next($request);
    }
}

Use Role Middleware in Routes

<?php

use Illuminate\Support\Facades\Route;

// Admin-only routes
Route::middleware(['auth', 'role:admin'])->group(function () {
    Route::get('/admin/users', [AdminController::class, 'users']);
    Route::get('/admin/settings', [AdminController::class, 'settings']);
});

// Manager routes
Route::middleware(['auth', 'role:manager'])->group(function () {
    Route::get('/reports', [ReportController::class, 'index']);
});

// Multiple roles
Route::middleware(['auth'])->group(function () {
    Route::get('/dashboard', function () {
        return view('dashboard');
    });
});

Blade Template Role Checks

<!-- resources/views/dashboard.blade.php -->

<div class="dashboard">
    <h1>Dashboard</h1>

    @if(in_array('admin', auth()->user()->workos_roles ?? []))
        <div class="admin-panel">
            <h2>Admin Controls</h2>
            <a href="/admin/users">Manage Users</a>
            <a href="/admin/settings">System Settings</a>
        </div>
    @endif

    @if(in_array('manager', auth()->user()->workos_roles ?? []) || in_array('admin', auth()->user()->workos_roles ?? []))
        <div class="manager-panel">
            <h2>Reports</h2>
            <a href="/reports">View Reports</a>
        </div>
    @endif

    <div class="user-content">
        <!-- Content for all authenticated users -->
    </div>
</div>

Deploying to Production

Ready to take your Laravel + WorkOS application live? Here's how to deploy to production safely and securely.

Pre-Deployment Checklist

  • โœ“ Switch from staging to production WorkOS API keys
  • โœ“ Add production redirect URIs in WorkOS Dashboard
  • โœ“ Configure production session storage (Redis recommended)
  • โœ“ Set up HTTPS/SSL certificates
  • โœ“ Configure production database
  • โœ“ Test all authentication flows
  • โœ“ Set up monitoring and error tracking

Production Environment Variables

# Production .env file

APP_NAME="Your App Name"
APP_ENV=production
APP_DEBUG=false
APP_URL=https://yourdomain.com

# WorkOS PRODUCTION Keys
WORKOS_CLIENT_ID=your-production-client-id
WORKOS_API_KEY=your-production-api-key
WORKOS_REDIRECT_URL="https://yourdomain.com/authenticate"

# Database
DB_CONNECTION=mysql
DB_HOST=your-production-db-host
DB_DATABASE=your_database
DB_USERNAME=your_username
DB_PASSWORD=strong_password_here

# Session (Use Redis for production)
SESSION_DRIVER=redis
SESSION_LIFETIME=120

# Cache
CACHE_DRIVER=redis

# Queue (for background jobs)
QUEUE_CONNECTION=redis

# Redis Configuration
REDIS_HOST=your-redis-host
REDIS_PASSWORD=null
REDIS_PORT=6379

Laravel Cloud Deployment

If you're using Laravel Cloud (recommended for Laravel 12), the process is streamlined:

  1. Connect your GitHub/GitLab repository
  2. Laravel Cloud detects WorkOS automatically
  3. Add your production WorkOS keys as environment variables
  4. Create production database
  5. Update WorkOS redirect URIs with your Laravel Cloud domain
  6. Deploy!

Traditional Server Deployment

# On your production server

# Pull latest code
git pull origin main

# Install dependencies
composer install --optimize-autoloader --no-dev
npm ci --production

# Build assets
npm run build

# Run migrations
php artisan migrate --force

# Clear and cache config
php artisan config:cache
php artisan route:cache
php artisan view:cache

# Restart services
sudo systemctl restart php8.3-fpm
sudo systemctl restart nginx

# Run queue workers
php artisan queue:restart

Update WorkOS for Production

  1. Switch to Production environment in WorkOS Dashboard
  2. Add production redirect URIs
  3. Configure production authentication methods
  4. Set up production webhooks
  5. Configure production session settings
  6. Test thoroughly before going live!

Best Practices and Security Tips

Follow these best practices to ensure your Laravel + WorkOS integration is secure, performant, and maintainable.

Security Best Practices

  • Never Commit API Keys: Always use environment variables, never commit credentials to Git
  • Verify Webhook Signatures: Always validate WorkOS webhook signatures to prevent spoofing
  • Validate Organization IDs: When processing SSO callbacks, always validate the organization belongs to your customer
  • Use HTTPS in Production: Never use WorkOS over plain HTTP in production
  • Implement Rate Limiting: Protect your authentication endpoints from abuse
  • Log Security Events: Log all authentication attempts and failures
  • Regular Security Audits: Review your WorkOS integration and access patterns regularly

Performance Optimization

<?php

// Cache user roles to reduce API calls
use Illuminate\Support\Facades\Cache;

class User extends Authenticatable
{
    public function getWorkosRolesAttribute()
    {
        return Cache::remember(
            "user.{$this->id}.roles",
            now()->addMinutes(15),
            function () {
                // Fetch roles from WorkOS
                return $this->fetchRolesFromWorkOS();
            }
        );
    }
    
    private function fetchRolesFromWorkOS()
    {
        // Implement WorkOS API call to get user roles
        // Return array of role names
    }
}

Error Handling

<?php

use WorkOS\Exception\WorkOSException;

try {
    $profile = $workos->sso->getProfile([
        'code' => $code,
        'clientId' => env('WORKOS_CLIENT_ID'),
    ]);
} catch (WorkOSException $e) {
    // Log the error
    Log::error('WorkOS authentication failed', [
        'error' => $e->getMessage(),
        'code' => $code,
    ]);
    
    // Show user-friendly error
    return redirect('/login')->with('error', 
        'Authentication failed. Please try again or contact support.'
    );
}

Testing Strategy

  • Unit Tests: Test your authentication logic with mocked WorkOS responses
  • Feature Tests: Test complete authentication flows in staging
  • Integration Tests: Verify SSO with test identity providers
  • Load Testing: Ensure your app handles authentication load during traffic spikes

Monitoring and Observability

<?php

// Log important authentication events

use Illuminate\Support\Facades\Log;

// Successful login
Log::info('User authenticated via WorkOS', [
    'user_id' => $user->id,
    'email' => $user->email,
    'method' => 'sso',
    'organization_id' => $organizationId,
]);

// Failed authentication
Log::warning('WorkOS authentication failed', [
    'error' => $exception->getMessage(),
    'code' => $code,
]);

// Directory sync event
Log::info('User synced from directory', [
    'user_id' => $user->id,
    'directory_id' => $directoryId,
    'event_type' => 'user.created',
]);

Troubleshooting Common Issues

Issue 1: Invalid Redirect URI Error

Problem: Getting "Invalid redirect URI" error during authentication

Solution:

  • Verify redirect URI in WorkOS Dashboard exactly matches your .env file
  • Check for trailing slashes (they matter!)
  • Ensure you're using the correct environment (staging vs production)
  • Clear Laravel config cache: php artisan config:clear

Issue 2: Session Not Persisting

Problem: Users get logged out immediately or on page refresh

Solution:

# Check session driver
php artisan config:cache

# Verify SESSION_DRIVER is set correctly
# For production, use 'redis' or 'database', not 'file'

# If using database sessions, run:
php artisan session:table
php artisan migrate

# Check storage permissions
chmod -R 775 storage
chmod -R 775 bootstrap/cache

Issue 3: WorkOS API Key Not Working

Problem: Getting 401 Unauthorized errors

Solution:

  • Verify you're using the correct API key (staging vs production)
  • Check that CLIENT_ID matches the environment's API key
  • Regenerate API keys if they've been exposed
  • Clear config cache after updating .env

Issue 4: Webhooks Not Received

Problem: Directory Sync events not triggering

Solution:

  • Verify webhook URL is publicly accessible (use ngrok for local testing)
  • Check that webhook URL is excluded from CSRF protection
  • Verify webhook signature validation isn't blocking requests
  • Check webhook logs in WorkOS Dashboard for delivery failures
// Exclude webhook from CSRF in app/Http/Middleware/VerifyCsrfToken.php

protected $except = [
    'webhooks/workos',
    'webhooks/*',
];

Issue 5: SSO Test Organization Not Working

Problem: Can't authenticate with test organization

Solution:

  • Make sure you're using staging API keys
  • Verify you're using the test organization ID from WorkOS Dashboard
  • Check that redirect URI includes localhost for development
  • Try clearing browser cookies and cache

Real-World Use Cases

Let's look at how real companies use Laravel + WorkOS to solve business problems:

Use Case 1: B2B SaaS Project Management Tool

Challenge: A project management startup was losing enterprise deals because they didn't support SSO and automatic user provisioning.

Solution: Integrated WorkOS AuthKit and Directory Sync. Now enterprise customers can:

  • Sign in with their corporate credentials (Okta, Azure AD)
  • Automatically provision new employees when they're hired
  • Automatically deprovision users when they leave the company
  • Map corporate groups to project teams automatically

Result: Closed 3 enterprise deals worth $500K ARR in the first quarter after integration. Implementation took 2 weeks instead of the estimated 3 months.

Use Case 2: Healthcare Platform

Challenge: Healthcare platform needed HIPAA-compliant authentication with audit logging and MFA for hospital staff.

Solution: Used WorkOS AuthKit with:

  • Mandatory MFA for all users
  • Passkeys for doctors (faster access during emergencies)
  • SSO integration with hospital's Active Directory
  • Audit logs for compliance requirements
  • Directory Sync to ensure only active employees have access

Result: Passed HIPAA compliance audit. Reduced support tickets by 70% (no password resets needed). Improved doctor satisfaction scores.

Use Case 3: EdTech Platform

Challenge: Education platform needed to support multiple schools, each with their own authentication requirements.

Solution: Multi-tenant Laravel app with WorkOS:

  • Each school gets its own organization in WorkOS
  • Students use Magic Auth (no passwords for kids to forget)
  • Teachers use SSO with Google Workspace
  • Administrators have full role-based access control
  • Directory Sync keeps class rosters updated automatically

Result: Scaled from 5 schools to 50 schools in 6 months. Zero authentication-related incidents. Teachers love the seamless Google login.


WorkOS vs Alternatives: Making the Right Choice

How does WorkOS compare to other authentication solutions for Laravel? Let's break it down:

WorkOS vs Laravel's Built-in Authentication

FeatureLaravel Built-inWorkOS
Basic Authโœ“ Freeโœ“ Free (1M MAU)
Social Loginโœ“ Via Socialiteโœ“ Built-in
Enterprise SSOโœ— DIYโœ“ SAML & OIDC
Directory Syncโœ— Not availableโœ“ SCIM
Admin Portalโœ— Build yourselfโœ“ Pre-built
Setup TimeHours for basicMinutes
Best ForSimple B2C appsB2B SaaS

WorkOS vs Auth0/Okta

  • Pricing: WorkOS free up to 1M MAU; Auth0/Okta expensive for smaller companies
  • Developer Experience: WorkOS built for developers; Auth0/Okta enterprise-focused
  • Integration Speed: WorkOS faster setup; Auth0/Okta more configuration needed
  • Laravel Support: WorkOS official Laravel starter kits; Auth0/Okta generic SDKs
  • Best For: WorkOS for B2B SaaS startups; Auth0/Okta for large enterprises

When to Choose WorkOS

WorkOS is the perfect choice when:

  • You're building a B2B SaaS application
  • You need enterprise features but don't want to build them
  • You're selling to companies that require SSO
  • You want to focus on your core product, not auth infrastructure
  • You need to scale from startup to enterprise smoothly
  • You want modern auth methods (Magic Auth, Passkeys)
  • You need Directory Sync for automatic user provisioning

Next Steps: Mastering WorkOS

Congratulations! You now have a solid foundation in Laravel + WorkOS integration. Here's how to continue your journey:

Advanced Features to Explore

  • Admin Portal: Let customers self-service their SSO configuration
  • Audit Logs: Implement compliance-ready activity logging
  • MFA: Add multi-factor authentication for enhanced security
  • Magic Auth: Implement passwordless authentication
  • Passkeys: Add WebAuthn for the ultimate user experience
  • Custom Domains: Brand your authentication flow with custom domains
  • Advanced RBAC: Implement fine-grained permissions

Recommended Resources

Join the Community

  • WorkOS Community Slack (check WorkOS website for invite)
  • Laravel Discord - #enterprise-apps channel
  • Stack Overflow - [laravel] [workos] tags

Conclusion

You've just completed a comprehensive journey through integrating WorkOS with Laravel 12! From basic setup to advanced features like SSO, Directory Sync, and role-based access control, you now have all the tools you need to build enterprise-ready B2B SaaS applications.

Remember, the key advantage of WorkOS is that it lets you focus on building your unique product features instead of spending months on authentication infrastructure. With features like AuthKit, SSO, and Directory Sync available out of the box, you can say "yes" to enterprise customers from day one.

Whether you're building the next unicorn startup or adding enterprise features to an existing Laravel application, WorkOS provides the foundation you need to scale from your first customer to thousands of enterprise users.

๐Ÿš€ Ready to Build?

Start building your enterprise-ready Laravel application with WorkOS today! The free tier includes everything you need to get started, supporting up to 1 million monthly active users.

  • โœ“ Sign up for free at dashboard.workos.com
  • โœ“ Follow this guide to integrate with your Laravel 12 app
  • โœ“ Start closing enterprise deals faster

Happy coding, and welcome to the world of enterprise-grade authentication made simple! ๐ŸŽ‰


Frequently Asked Questions

What is WorkOS and why should I use it with Laravel?+
Is WorkOS free for Laravel applications?+
Can I use WorkOS with Laravel 12?+
What's the difference between WorkOS AuthKit and the standalone SSO API?+
Does WorkOS support social login providers like Google and GitHub?+
How do I implement SSO for enterprise customers in Laravel with WorkOS?+
What is Directory Sync and why do I need it?+
Can I migrate from Laravel Breeze/Fortify to WorkOS?+