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

# Authentication

> How to authenticate with the Gatelit gateway from the SDK. Service keys and signed tokens.

The SDK's `GatelitClient` calls `getToken()` before every request. What that function returns determines how the gateway identifies and authorizes the request. Three schemes are available — pick the right one for your deployment.

## Service keys (`GatelitKey`)

Long-lived keys for backend use. Create them in the dashboard under **Settings → Service Keys**.

```ts theme={null}
const client = new GatelitClient({
  gatewayUrl: "https://gateway.yourapp.com",
  getToken: async () => ({
    token: process.env.GATELIT_SERVICE_KEY!,
    scheme: "GatelitKey",
  }),
})
```

**Pros:** Simple. No token lifecycle management.
**Cons:** Long-lived. Revocation requires deleting the key.
**When:** Server-side scripts, CI, cron jobs, or any backend where managing short-lived tokens is overhead.

<Warning>
  Never use `GatelitKey` in browser code. It's a long-lived secret — anyone who
  extracts it can make requests indefinitely.
</Warning>

## Signed tokens (`GatelitSigned`)

Your backend issues short-lived HMAC-signed JWTs. The gateway verifies them without a database call.

**Backend** — Nuxt server route example:

```ts theme={null}
// server/api/ai-token.get.ts
import { signToken } from "@gatelit/sdk/sign"

export default defineEventHandler(async (event) => {
  const session = await requireAuth(event)
  const token = await signToken(
    {
      sub: session.userId,
      orgId: session.orgId,
      model: "openai/gpt-4o",      // optional — restrict model
      maxTokens: 2000,              // optional — cap output
      ttl: 60,                      // seconds (default: 60)
      endUserId: session.userId,    // optional — appears in logs
    },
    process.env.GATELIT_SIGNING_SECRET!,
  )
  return { token }
})
```

**Frontend** — fetch the token before each request:

```ts theme={null}
const client = new GatelitClient({
  gatewayUrl: "https://gateway.yourapp.com",
  getToken: async () => {
    const res = await fetch("/api/ai-token")
    const { token } = await res.json()
    return { token, scheme: "GatelitSigned" }
  },
})
```

**Pros:** Short-lived (60s default). Encodes per-user constraints. No DB hit for verification.
**Cons:** Requires a backend endpoint to issue tokens.
**When:** Frontend apps with authenticated users. This is the recommended pattern for production browser apps.

<Info>
  `GATELIT_SIGNING_SECRET` must match between your backend and the gateway.
  Both sign and verify with the same secret.
</Info>

## OIDC tokens (`Bearer`)

<Info>
  OIDC authentication is in **Alpha**. Full self-serve configuration is coming soon.
  Contact us if you need OIDC support today.
</Info>

Pass the user's existing OIDC JWT directly:

```ts theme={null}
const client = new GatelitClient({
  gatewayUrl: "https://gateway.yourapp.com",
  getToken: async () => ({
    token: await supabase.auth.getSession().then(s => s.data.session?.access_token),
    scheme: "Bearer",
  }),
})
```

## Caching tokens

`getToken` is called before **every** request. Add caching to avoid unnecessary work:

```ts theme={null}
let cachedToken: { token: string; scheme: TokenScheme } | null = null
let cachedAt = 0

const client = new GatelitClient({
  gatewayUrl: "https://gateway.yourapp.com",
  getToken: async () => {
    const now = Date.now()
    if (cachedToken && now - cachedAt < 50_000) return cachedToken

    const res = await fetch("/api/ai-token")
    const { token } = await res.json()
    cachedToken = { token, scheme: "GatelitSigned" }
    cachedAt = now
    return cachedToken
  },
})
```

For signed tokens with a 60-second TTL, refresh the cache slightly before expiry.
