> ## Documentation Index
> Fetch the complete documentation index at: https://docs-terra.withunify.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Authentication

> How Terra handles user authentication with WorkOS AuthKit

# 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

```mermaid theme={null}
sequenceDiagram
    participant U as User
    participant T as Terra
    participant W as WorkOS

    U->>T: Visit /auth/login
    T->>W: Redirect to AuthKit
    W->>W: User authenticates (SSO/password)
    W->>T: Callback with code
    T->>W: Exchange code for session
    W-->>T: Session + user data
    T->>T: Create encrypted cookie
    T->>U: Redirect to dashboard
```

## Session Management

Sessions are stored as encrypted cookies:

```typescript theme={null}
// 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`:

```typescript theme={null}
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:

```typescript theme={null}
// 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();
}
```

***

<CardGroup cols={2}>
  <Card title="Authorization" icon="shield" href="/core-systems/identity/authorization">
    Role-based access control
  </Card>

  <Card title="Applicant Identity" icon="user" href="/core-systems/identity/applicant-identity">
    Portal user management
  </Card>
</CardGroup>
