Jetta SSO Integration
JettaSSO is the centralized Single Sign-On service for all Jetta applications. It provides unified authentication across *.jettaintelligence.com subdomains via a shared cookie.
SSO URL: https://login.jettaintelligence.com
How It Works
1. User visits your app (e.g., myapp.jettaintelligence.com)
↓
2. Middleware checks for jetta_token cookie
↓
3. If missing, redirect to SSO:
https://login.jettaintelligence.com/login?redirect_uri=...
↓
4. User logs in (email/password or Google OAuth)
↓
5. SSO sets jetta_token cookie on .jettaintelligence.com domain
↓
6. User redirected back to your app's callback
↓
7. Your app reads the cookie - user is authenticated
Cookie Details
- Name:
jetta_token - Domain:
.jettaintelligence.com(shared across all subdomains) - HttpOnly: true
- Secure: true
- SameSite: lax
Integration Steps
1. Environment Variables
JETTA_SSO_URL=https://login.jettaintelligence.com
NEXT_PUBLIC_APP_URL=https://myapp.jettaintelligence.com
2. Create SSO Callback Route
Next.js (src/app/sso/callback/route.ts):
import { NextRequest, NextResponse } from 'next/server';
export async function GET(request: NextRequest) {
const searchParams = request.nextUrl.searchParams;
const redirectUri = searchParams.get('redirect_uri') || '/';
return NextResponse.redirect(new URL(redirectUri, request.url));
}
FastAPI (app/routes/auth.py):
from fastapi import APIRouter, Request
from fastapi.responses import RedirectResponse
router = APIRouter()
@router.get("/sso/callback")
async def sso_callback(request: Request, redirect_uri: str = "/"):
return RedirectResponse(url=redirect_uri)
3. Add Auth Middleware
Next.js (src/middleware.ts):
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
const SSO_URL = process.env.JETTA_SSO_URL;
const APP_URL = process.env.NEXT_PUBLIC_APP_URL;
const PUBLIC_PATHS = ['/api/health', '/sso/callback', '/_next'];
export function middleware(request: NextRequest) {
const { pathname } = request.nextUrl;
if (PUBLIC_PATHS.some(path => pathname.startsWith(path))) {
return NextResponse.next();
}
const token = request.cookies.get('jetta_token');
if (!token) {
const callbackUrl = `${APP_URL}/sso/callback?redirect_uri=${encodeURIComponent(request.url)}`;
const loginUrl = `${SSO_URL}/login?redirect_uri=${encodeURIComponent(callbackUrl)}`;
return NextResponse.redirect(loginUrl);
}
return NextResponse.next();
}
4. Add Logout Route
export async function GET() {
const cookieStore = await cookies();
cookieStore.delete('jetta_token');
return NextResponse.redirect(`${SSO_URL}/login`);
}
SSO API Endpoints
| Endpoint | Method | Description |
|---|---|---|
/login | GET | Login page (themed per app) |
/api/auth/login | POST | JSON login |
/api/auth/logout | POST | Sign out |
/api/auth/me | GET | Get current user |
/api/verify | GET | Verify token (backend-to-backend) |
/oauth/google | GET | Google OAuth flow |
Integration Checklist
- Set
JETTA_SSO_URLandAPP_URLenvironment variables - Create
/sso/callbackroute - Add auth middleware to protect routes
- Add logout route
- Define public paths that don't need auth
- (Optional) Add API key auth for programmatic access
- (Optional) Request app theming
Troubleshooting
Cookie not being set
- Ensure your app is on
*.jettaintelligence.comsubdomain - Check browser dev tools for cookie domain
Redirect loop
- Verify
/sso/callbackis in your public paths - Check that callback URL is properly encoded
Token verification failing
- Ensure token is passed in Authorization header
- Check SSO service is healthy:
https://login.jettaintelligence.com/health