Skip to main content

Authentication

Terra uses WorkOS AuthKit for authentication, decoupling identity from the database.

Why WorkOS?

Government agencies often require enterprise SSO (SAML, OIDC) with Azure AD, Okta, or Google Workspace. WorkOS makes this configuration, not code.

Authentication Flow

Session Management

Sessions are stored as encrypted cookies:
// src/lib/auth.ts

export async function getSession(): Promise<Session | null> {
  const cookie = cookies().get("wos-session");
  if (!cookie) return null;

  try {
    const session = await decrypt(cookie.value);
    if (session.expiresAt < Date.now()) return null;
    return session;
  } catch {
    return null;
  }
}
Cookie properties:
  • Encrypted with WORKOS_COOKIE_PASSWORD
  • HttpOnly (no JavaScript access)
  • Secure (HTTPS only in production)
  • 7-day expiry

User Sync

On first login, we sync WorkOS user data to user_profiles:
async function syncUser(workosUser: WorkOSUser) {
  await supabaseAdmin.from("user_profiles").upsert({
    workos_user_id: workosUser.id,
    email: workosUser.email,
    first_name: workosUser.firstName,
    last_name: workosUser.lastName,
    role: "applicant", // Default role
  });
}

Protected Routes

The middleware checks authentication:
// src/middleware.ts
export async function middleware(request: NextRequest) {
  const session = await getSession();

  if (!session && isProtectedRoute(request.pathname)) {
    return NextResponse.redirect(new URL("/auth/login", request.url));
  }

  return NextResponse.next();
}