Authentication & Security
TanStack Ship authentication system with Google OAuth SSO, email/password login, JWT session management, and role-based access control (RBAC).
Overview
The authentication and security system in TanStack Ship provides a comprehensive, production-ready solution for user identity management. It supports multiple authentication methods including Google OAuth 2.0 single sign-on and traditional email/password login, all built on secure session management with server-side token validation.
Access control is enforced at every layer of the application — from route guards to API-level authorization checks. The RBAC (Role-Based Access Control) system ensures that users only access resources appropriate to their role, while administrators have the tools needed to manage the platform effectively.
As part of the platform, the authentication module integrates with the billing system for subscription-gated access, the invitation system for team growth, and the admin dashboard for user management.
Authentication Flow
The authentication system supports multiple sign-in methods, all converging into a unified session management layer:
Design Philosophy
The authentication system is guided by three core security principles:
- Defense in Depth — Access control is enforced at multiple independent layers: route guards, API authorization, and UI-level rendering. If one layer is compromised, the others remain effective. Unlike all-in-one auth providers like Auth0 or Clerk that externalize authentication to third-party domains, our approach keeps session validation entirely server-side within your infrastructure, eliminating reliance on external services for core security decisions.
- Least Privilege — Users are assigned the minimum permissions required for their role. The RBAC system ensures that standard users cannot access admin functionality, and API endpoints validate permissions before executing every operation.
- Server-Side Trust — All session validation happens server-side. JWT tokens are signed with a server secret, stored in HTTP-only cookies, and verified on every protected request. Client-side checks are for UX only — real security is enforced on the server.
Core Capabilities
Google OAuth 2.0 Integration
Users can sign in with their Google account via the OAuth 2.0 authorization code flow. The implementation follows Google's recommended security practices, including CSRF protection through state parameters and PKCE (Proof Key for Code Exchange) for enhanced security.
OAuth Flow:
- User clicks "Sign in with Google" on the login page
- Application redirects to Google's OAuth consent screen with configured scopes
- User grants permission on Google's domain
- The authorization callback exchanges the code for authentication tokens
- The server creates or updates the user record and issues a session
- User is redirected to their authenticated dashboard
The OAuth callback validates the state parameter to prevent CSRF attacks and handles both new user creation and existing user login seamlessly.
Email & Password Authentication
Traditional email/password authentication with enterprise-grade security:
- Password Hashing — All passwords are hashed using bcrypt with a configurable cost factor. No plaintext passwords are ever stored.
- Registration Flow — New users register with email, password, and optional invitation code. Input validation is performed on both client and server.
- Email Verification — Verified email addresses are required for accessing protected features. Verification emails include time-limited tokens.
- Password Reset — Secure token-based password reset flow with expiration. Users receive a reset link via email.
The entire registration and login pipeline follows OWASP authentication best practices.
Session Management
Sessions are managed through JWT tokens stored as HTTP-only cookies:
- Secure Tokens — Signed with a server-side secret, containing user ID, role, and expiration claims
- Server Validation — Every protected route verifies the token's validity and expiration server-side
- Configurable Expiration — Session TTL is configurable; default is 7 days
- Logout — Token invalidation on logout clears the server-side session
Session middleware ensures that unauthenticated users are redirected to the login page before any protected content is rendered.
Role-Based Access Control (RBAC)
Two built-in roles provide clear access boundaries:
- User — Standard access to dashboard, billing management, profile settings, and feature usage
- Admin — Full access to admin panels, user management, billing administration, system configuration, and analytics
Access control is enforced at multiple layers:
- Route Level — Route loaders check user role before rendering protected pages
- API Level — Server functions validate permissions before executing operations
- UI Level — Components conditionally render admin-only menus and actions
The RBAC system is extensible — additional roles can be added through configuration.
Account Security & Profile Management
Users can manage their security settings through the dashboard:
- Update profile information (name, avatar, contact email)
- Change password with current password verification
- Manage connected Google account
- View account activity and active sessions
- Request account deletion with confirmation flow
Example — User profile API response:
{
"id": "user_abc123",
"email": "user@example.com",
"name": "Jane Doe",
"role": "user",
"emailVerified": true,
"authProvider": "google",
"createdAt": "2025-01-15T10:30:00Z"
}
**Example — Login component with Google OAuth:**
```tsx
import { useNavigate } from '@tanstack/react-router'
export function LoginPage() {
const navigate = useNavigate()
const handleGoogleLogin = () => {
// Redirects to server-side OAuth endpoint
window.location.href = '/api/auth/google'
}
const handleEmailLogin = async (e: React.FormEvent) => {
e.preventDefault()
const form = new FormData(e.target as HTMLFormElement)
const res = await fetch('/api/auth/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
email: form.get('email'),
password: form.get('password'),
}),
})
if (res.ok) navigate({ to: '/dashboard' })
}
return (
<div>
<button onClick={handleGoogleLogin}>Sign in with Google</button>
<hr />
<form onSubmit={handleEmailLogin}>
<input name="email" type="email" placeholder="Email" required />
<input name="password" type="password" placeholder="Password" required />
<button type="submit">Sign In</button>
</form>
</div>
)
}
Best Practices
Password Policy Enforcement
Implement a strong password policy requiring minimum 12 characters, mixed case, numbers, and special characters. Validation runs on both client and server to provide immediate feedback during registration.
OAuth State Parameter Validation
Always validate the state parameter in OAuth callbacks to prevent CSRF attacks. The system generates a unique state value for each authentication request and verifies it matches on callback return.
Session Rotation on Privilege Escalation
Issue a new session token whenever a user's role changes or they perform sensitive operations (password change, email update). This limits the window of opportunity for stolen tokens.
Rate Limiting on Auth Endpoints
Apply rate limiting to login, registration, and password reset endpoints to prevent brute force attacks. Track failed attempts per IP address and temporarily block excessive requests.
Frequently Asked Questions
How do I set up Google OAuth for my domain? Create a Google Cloud Console project, configure the OAuth consent screen, create credentials with your domain's callback URL, and set the client ID and secret in your environment configuration.
Can I add more OAuth providers like GitHub or Microsoft? Yes. The authentication architecture supports multiple OAuth providers. Each provider requires its own callback endpoint and credential configuration.
How long do sessions last? Session TTL is configurable. The default is 7 days. Sessions can be extended on each authenticated request to keep active users logged in.
What happens when a session expires? The system detects expired tokens and redirects to the login page with a session expired message. Users re-authenticate to obtain a new session.
Can I disable email/password login and use only OAuth? Yes. The authentication system is modular. Disable email/password login by removing the corresponding route handlers, and the login page automatically adapts.
How are user roles assigned initially?
New users are assigned the user role by default. Admin promotion can be done through the database, a seed script, or an admin management interface.
How does invitation-based registration work? Existing users generate invitation codes through the invitation system. New users register using an invitation code, which links them to the inviting user and optionally assigns a predefined role.
Configuration
Configure these environment variables:
GOOGLE_CLIENT_ID=xxx.apps.googleusercontent.com
GOOGLE_CLIENT_SECRET=GOCSPX-...
JWT_SECRET=your-secure-secret-key-min-32-chars
JWT_EXPIRES_IN=7d
For Google OAuth, create a project in the Google Cloud Console, configure the OAuth consent screen, and add your callback URL to the authorized redirect URIs.
Integration Points
The authentication system integrates with these platform modules:
- Billing — Subscription status is linked to user account; premium features are gated by active subscription
- Invitation System — New users can be invited via invitation codes; invited users are linked to the inviter
- Admin Dashboard — Admin role grants access to user management, system configuration, and analytics
- Dashboard Routes — Session middleware protects all dashboard routes, redirecting unauthenticated users to login
- Campaign Offers — User authentication is required for claiming promotional offers
- Blog CMS — Authors and editors are authenticated users with content management permissions