> ## 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.

# signToken

> Sign short-lived HMAC tokens for GatelitSigned authentication. Backend-only — Node.js, Deno, Bun, and edge runtimes.

```ts theme={null}
import { signToken } from "@gatelit/sdk/sign"
```

`signToken` creates an HMAC-SHA256 signed JWT for the `GatelitSigned` auth scheme. It runs on your backend using the Web Crypto API — available natively in Node.js 18+, Bun, Deno, and all edge runtimes (Cloudflare Workers, Vercel Edge).

<Info>
  Import from `@gatelit/sdk/sign` (not `@gatelit/sdk`) to tree-shake the rest
  of the SDK. The `/sign` subpath export only includes `signToken` and its
  dependencies.
</Info>

## Signature

```ts theme={null}
function signToken(
  options: SignedTokenOptions,
  secret: string,
): Promise<string>
```

Returns a dot-separated token string: `header.payload.signature`.

## Options

| Field           | Type                             | Required | Default | Description                                      |
| --------------- | -------------------------------- | -------- | ------- | ------------------------------------------------ |
| `sub`           | `string`                         | Yes      | —       | Subject identifier — typically the user ID       |
| `orgId`         | `string`                         | No       | —       | Org ID for org-scoped provider key resolution    |
| `model`         | `string`                         | No       | —       | Restrict to one model in `provider/model` format |
| `maxTokens`     | `number`                         | No       | —       | Cap output tokens per request                    |
| `ttl`           | `number`                         | No       | `60`    | Token lifetime in seconds                        |
| `endUserId`     | `string`                         | No       | —       | End-user ID for log filtering                    |
| `requestSource` | `"api" \| "dashboard" \| "eval"` | No       | —       | Tag for request source filtering                 |

## Examples

### Minimal — user identity only

```ts theme={null}
await signToken({ sub: "user_123" }, process.env.GATELIT_SIGNING_SECRET!)
```

### Constrained — specific model with a token cap

```ts theme={null}
await signToken(
  {
    sub: "user_123",
    orgId: "org_456",
    model: "openai/gpt-4o",
    maxTokens: 500,
    ttl: 30,
  },
  process.env.GATELIT_SIGNING_SECRET!,
)
```

### Full — end-user tracking with request source

```ts theme={null}
await signToken(
  {
    sub: "user_123",
    orgId: "org_456",
    model: "anthropic/claude-3-5-haiku-20241022",
    maxTokens: 1000,
    ttl: 60,
    endUserId: "customer_789",
    requestSource: "api",
  },
  process.env.GATELIT_SIGNING_SECRET!,
)
```

## Nuxt server route

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

export default defineEventHandler(async (event) => {
  const { user } = await requireUserSession(event)
  if (!user) throw createError({ statusCode: 401 })

  const token = await signToken(
    {
      sub: user.id,
      orgId: user.orgId,
      model: "openai/gpt-4o",
    },
    useRuntimeConfig().gatewaySigningSecret,
  )
  return { token }
})
```

## Next.js API route

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

export async function GET() {
  const token = await signToken(
    { sub: "user_123", model: "openai/gpt-4o", ttl: 60 },
    process.env.GATELIT_SIGNING_SECRET!,
  )
  return Response.json({ token })
}
```

## Express route

```ts theme={null}
import { signToken } from "@gatelit/sdk/sign"

app.get("/api/ai-token", async (req, res) => {
  const token = await signToken(
    { sub: req.user!.id, model: "openai/gpt-4o-mini" },
    process.env.GATELIT_SIGNING_SECRET!,
  )
  res.json({ token })
})
```

## Token structure

The signed token embeds the following JWT claims the gateway reads:

* **`iat`** — Issued at (epoch seconds)
* **`exp`** — Expires at (`iat` + `ttl`)
* **`sub`** — Subject (user ID)
* **`orgId`** — (optional) Organisation context
* **`policyOverride`** — (optional) Encoded model restriction and token cap
* **`endUserId`** — (optional) End-user identifier
* **`requestSource`** — (optional) `api` | `dashboard` | `eval`

The gateway verifies the HMAC signature without a database call — fast, stateless, and cache-friendly.
