`@authdog/elysia` resolves Authdog sessions for Elysia. Its plugin injects session context into handlers and exposes an authentication guard.

## Availability

**Unreleased:** `@authdog/elysia` is not on npm at the time of writing (the registry returns 404). `bun add @authdog/elysia` will fail until it is published. Source lives in the [`packages/elysia` directory](https://github.com/authdog/web-sdk/tree/main/packages/elysia) of the web SDK repository (version `0.3.0`, configured to publish to npm with public access). Vendor a repository checkout until a release ships.

## Install

```package-install
@authdog/elysia elysia
```

`elysia` is a peer dependency (`^1.0.0`); `@authdog/node-commons` installs automatically. The SDK is aimed at Bun-first Elysia apps; `logout` returns a Web `Response`, so it is not tied to one runtime.

## Configure

Create one instance with your environment's public key (`pk_...`):

```ts
import { Elysia } from "elysia"
import { createAuthdog } from "@authdog/elysia"

const authdog = createAuthdog({ publicKey: process.env.PK_AUTHDOG! })
```

The key is safe to expose. It is parsed once at startup; a missing key throws `Public key is not defined`, and malformed keys or identity hosts outside the trusted HTTPS allowlist fail immediately. `createAuthdog` also accepts an optional `secretKey`, which is reserved and currently unused.

## Attach the session

Apply the plugin on the root app before routes:

```ts
const app = new Elysia().use(authdog.attachSession())
```

`attachSession()` returns an Elysia plugin that derives a global `authdog` property into every handler context. It prefers the `authdog-session` cookie, then reads `Authorization: Bearer <token>`. A valid token requires a successful `userinfo` response (`meta.code === 200` with a user). Missing, invalid, or unverifiable tokens never fail the request or return a 500; they yield anonymous context:

```ts
{
  token: string | null,
  user: unknown | null,
  isAuthenticated: boolean,
  userInfo?: UserInfoResponse | null,
}
```

`attachSession({ fetchUser: false })` only surfaces the unverified token. It leaves `user` null and `isAuthenticated` false, so `requireAuth` rejects the request with 401. Use this option only when separate server-side validation and enforcement replace Authdog's gate.

## Protect a route

`requireAuth` (a `beforeHandle` hook in Elysia) is the security boundary and returns `401 {"error":"Unauthorized"}` unless `isAuthenticated` is true:

```ts
new Elysia()
  .use(authdog.attachSession())
  .get("/me", ({ authdog: ctx }) => ctx.user, {
    beforeHandle: authdog.requireAuth,
  })
```

Authentication identifies a caller; it does not authorize actions. Apply your [authorization](/docs/concepts/authorization) checks after `requireAuth`. Client-side checks never protect server routes.

## Sign out

`logout` expires the `authdog-session` cookie (`HttpOnly`, `SameSite=Lax`, `Secure` when `NODE_ENV` is `production`) and redirects (302) to a sanitized same-origin `redirect_uri`, falling back to `/`:

```ts
new Elysia().use(authdog.attachSession()).get("/logout", authdog.logout)
```

This does not revoke a bearer token or end an upstream identity-provider session.

## Next steps

- [Backend requests](/docs/backend)
- [Fastify](/docs/backend/fastify)
- [Express](/docs/backend/express)
- [Calling the REST API](/docs/api)
