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

# Authentication

> Built-in SSO for all Cubby apps

# Authentication

Every Cubby app gets built-in authentication via Cubby SSO. You don't need to implement any auth logic.

## How It Works

When users access your app:

1. **Request arrives** at `https://myapp.username.cubby.pro`
2. **Envoy Gateway intercepts** and checks for valid session cookie
3. **If not logged in**: User is redirected to `auth.cubby.pro`
4. **User authenticates**: Magic link or password
5. **Redirect back**: User returns to your app with session
6. **Headers injected**: User info available in your code

## Request Headers

Authenticated requests include these headers:

| Header             | Description      | Example               |
| ------------------ | ---------------- | --------------------- |
| `X-Cubby-User-Id`  | User's unique ID | `clm1234567890abcdef` |
| `X-Cubby-Username` | User's username  | `johndoe`             |

<Warning>
  These headers are set by Cubby's infrastructure. They're stripped from incoming requests and re-added after authentication. You cannot spoof them.
</Warning>

## Accessing User Info

### In API Routes

```typescript theme={null}
// app/api/profile/route.ts
import { headers } from 'next/headers'

export async function GET() {
  const h = await headers()
  const userId = h.get('X-Cubby-User-Id')
  const username = h.get('X-Cubby-Username')

  return Response.json({ userId, username })
}
```

### In Server Components

```typescript theme={null}
// app/profile/page.tsx
import { headers } from 'next/headers'

export default async function ProfilePage() {
  const h = await headers()
  const username = h.get('X-Cubby-Username')

  return <h1>Hello, {username}!</h1>
}
```

### In Server Actions

```typescript theme={null}
// app/actions.ts
'use server'

import { headers } from 'next/headers'

export async function createTodo(title: string) {
  const h = await headers()
  const userId = h.get('X-Cubby-User-Id')

  await prisma.todo.create({
    data: { title, userId: userId! }
  })
}
```

## User-Scoped Data

Most apps need to scope data by user. Use the `userId` from headers:

```typescript theme={null}
// app/api/todos/route.ts
import { headers } from 'next/headers'
import { prisma } from '@/lib/db'

export async function GET() {
  const h = await headers()
  const userId = h.get('X-Cubby-User-Id')!

  const todos = await prisma.todo.findMany({
    where: { userId },
    orderBy: { createdAt: 'desc' }
  })

  return Response.json(todos)
}

export async function POST(request: Request) {
  const h = await headers()
  const userId = h.get('X-Cubby-User-Id')!
  const { title } = await request.json()

  const todo = await prisma.todo.create({
    data: { title, userId }
  })

  return Response.json(todo, { status: 201 })
}
```

## Owner vs Shared Access

Apps can be shared with other users. Both owners and shared users are authenticated, but they have different permissions:

| Capability        | Owner | Shared User |
| ----------------- | ----- | ----------- |
| Access app        | Yes   | Yes         |
| View in dashboard | Yes   | Yes         |
| Modify secrets    | Yes   | No          |
| Delete app        | Yes   | No          |
| Share with others | Yes   | No          |

Your app code receives the same headers for both. If you need to distinguish:

```typescript theme={null}
// The app owner's userId is stored in your database
// Compare with the current user's userId
const isOwner = (currentUserId === app.ownerId)
```

## What NOT To Do

Since Cubby handles authentication, you should NOT:

* Install auth libraries (NextAuth, Clerk, Auth0, etc.)
* Create user/session tables in your database
* Implement login/logout pages
* Handle password reset flows
* Store passwords or tokens

All of this is handled by Cubby SSO.

## Login Methods

Users can authenticate via:

* **Magic link**: Email with one-time login link
* **Password**: Traditional email + password

Users manage their login methods at `auth.cubby.pro`.

## Session Duration

* **Inactivity timeout**: 7 days without activity
* **Absolute timeout**: 90 days maximum

Users are automatically logged out after either timeout.
