Skip to main content

Authentication

The Loom Loyalty Hub uses WorkOS AuthKit for enterprise-grade authentication, supporting SSO, MFA, and user management.

Overview​

Authentication in the Hub works as follows:

  1. User visits the Hub
  2. Hub loads tenant configuration (including WorkOS settings)
  3. User is redirected to WorkOS for authentication
  4. WorkOS returns an access token
  5. Hub uses the token for API requests

WorkOS Setup​

1. Create a WorkOS Account​

Sign up at workos.com and create an application.

2. Configure Your Application​

In the WorkOS dashboard:

  1. Go to Authentication > AuthKit
  2. Enable AuthKit for your application
  3. Configure the redirect URI: https://your-hub.pages.dev/auth/callback
  4. Note your Client ID

3. Create an Organization​

For each tenant:

  1. Go to Organizations
  2. Create a new organization
  3. Note the Organization ID
  4. Configure SSO connections if needed

4. Add to Tenant Config​

Add WorkOS settings to your tenant configuration:

{
"workos": {
"clientId": "client_01HXYZ...",
"organizationId": "org_01HXYZ..."
}
}

Authentication Flow​

Login​

User visits Hub
│
▼
Hub loads config with WorkOS settings
│
▼
User clicks "Sign In"
│
▼
Redirect to WorkOS AuthKit
│
▼
User authenticates (SSO, password, etc.)
│
▼
WorkOS redirects back with code
│
▼
Hub exchanges code for tokens
│
▼
User is authenticated

Token Management​

The Hub manages tokens automatically:

  • Access Token - Short-lived, stored in memory
  • Refresh Token - HTTP-only cookie for security
  • Auto-refresh - Tokens are refreshed before expiry

Using Authentication​

AuthProvider​

The Hub wraps your application with AuthProvider:

import { AuthProvider } from "@workos-inc/authkit-react";

<ConfigProvider>
<AuthProvider clientId={config.workos.clientId} organizationId={config.workos.organizationId}>
<App />
</AuthProvider>
</ConfigProvider>;

useAuth Hook​

Access authentication state in components:

import { useAuth } from "@workos-inc/authkit-react";

function UserMenu() {
const { user, isLoading, signIn, signOut } = useAuth();

if (isLoading) {
return <Skeleton className="h-8 w-8 rounded-full" />;
}

if (!user) {
return <Button onClick={() => signIn()}>Sign In</Button>;
}

return (
<DropdownMenu>
<DropdownMenuTrigger>
<Avatar>
<AvatarImage src={user.profilePictureUrl} />
<AvatarFallback>{user.firstName?.[0]}</AvatarFallback>
</Avatar>
</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuLabel>{user.email}</DropdownMenuLabel>
<DropdownMenuSeparator />
<DropdownMenuItem onClick={() => signOut()}>Sign Out</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
);
}

Protected Routes​

Protect routes that require authentication:

import { useAuth } from "@workos-inc/authkit-react";
import { Navigate } from "@tanstack/react-router";

function ProtectedRoute({ children }: { children: React.ReactNode }) {
const { user, isLoading } = useAuth();

if (isLoading) {
return <LoadingScreen />;
}

if (!user) {
return <Navigate to="/login" />;
}

return children;
}

SSO Configuration​

Supported Providers​

WorkOS supports these SSO providers:

  • Okta
  • Azure AD
  • Google Workspace
  • OneLogin
  • JumpCloud
  • PingFederate
  • Generic SAML 2.0
  • Generic OIDC

Configuring SSO​

  1. In WorkOS dashboard, go to the organization
  2. Add an SSO connection
  3. Follow the provider-specific setup guide
  4. Users from that domain will use SSO automatically

Domain Verification​

To enable SSO for a domain:

  1. Add the domain to the organization
  2. Verify ownership via DNS TXT record
  3. Users with that email domain will use SSO

Multi-Factor Authentication​

Enabling MFA​

In WorkOS dashboard:

  1. Go to Authentication > MFA
  2. Enable MFA for your application
  3. Choose factors: TOTP, SMS, or both

MFA Flow​

When MFA is required:

  1. User completes primary authentication
  2. WorkOS prompts for second factor
  3. User enters code from authenticator/SMS
  4. Authentication completes

Role-Based Access Control​

User Roles​

Define roles in WorkOS:

// Example roles
const roles = {
admin: ["read", "write", "delete", "manage_users"],
manager: ["read", "write"],
viewer: ["read"],
};

Checking Permissions​

import { useAuth } from "@workos-inc/authkit-react";

function AdminPanel() {
const { user } = useAuth();

// Check user's role
const isAdmin = user?.role === "admin";

if (!isAdmin) {
return <div>Access denied</div>;
}

return <AdminDashboard />;
}

Development Mode​

For local development without WorkOS:

Mock Authentication​

Set VITE_USE_REAL_API=false to use mock authentication:

// Mock user is automatically provided
const mockUser = {
id: "user_mock",
email: "demo@example.com",
firstName: "Demo",
lastName: "User",
};

Bypassing Auth​

In development, you can bypass authentication:

// In your auth provider
if (import.meta.env.DEV && !import.meta.env.VITE_WORKOS_CLIENT_ID) {
// Return mock auth state
return {
user: mockUser,
isLoading: false,
signIn: () => {},
signOut: () => {},
};
}

Security Best Practices​

1. Use HTTPS​

Always use HTTPS in production:

{
"workos": {
"redirectUri": "https://hub.example.com/auth/callback"
}
}

2. Validate Tokens​

The SDK validates tokens automatically, but ensure:

  • Token expiry is checked
  • Audience matches your application
  • Issuer is WorkOS

3. Secure Storage​

  • Never store tokens in localStorage
  • Use HTTP-only cookies for refresh tokens
  • Access tokens in memory only

4. Session Management​

  • Implement session timeout
  • Force re-authentication for sensitive actions
  • Clear tokens on sign out

Troubleshooting​

"Invalid client_id"​

Check that the client ID in your config matches WorkOS:

{
"workos": {
"clientId": "client_01HXYZ..." // Must match exactly
}
}

"Redirect URI mismatch"​

Ensure the redirect URI is configured in WorkOS:

  1. Go to WorkOS dashboard
  2. Check Redirect URIs under AuthKit
  3. Add your Hub's callback URL

"Organization not found"​

Verify the organization ID exists:

{
"workos": {
"organizationId": "org_01HXYZ..." // Must be a valid org
}
}

SSO Not Working​

  1. Check domain verification status
  2. Verify SSO connection is active
  3. Check IdP configuration matches WorkOS

Next Steps​