Skip to main content

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
  • 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

EndpointMethodDescription
/loginGETLogin page (themed per app)
/api/auth/loginPOSTJSON login
/api/auth/logoutPOSTSign out
/api/auth/meGETGet current user
/api/verifyGETVerify token (backend-to-backend)
/oauth/googleGETGoogle OAuth flow

Integration Checklist

  • Set JETTA_SSO_URL and APP_URL environment variables
  • Create /sso/callback route
  • 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

  • Ensure your app is on *.jettaintelligence.com subdomain
  • Check browser dev tools for cookie domain

Redirect loop

  • Verify /sso/callback is 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