`@authdog/hono` resolves Authdog sessions for Hono. Its middleware stores session context on the Hono context and exposes an authentication guard.

## Availability

**Unreleased:** `@authdog/hono` is not on npm at the time of writing (the registry returns 404). `bun add @authdog/hono` will fail until it is published. Source lives in the [`packages/hono` directory](https://github.com/authdog/web-sdk/tree/main/packages/hono) 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/hono hono
```

`hono` is a peer dependency (`^4`); `@authdog/node-commons` installs automatically. Hono runs on Bun, Node.js, Cloudflare Workers, and Deno.

## Configure

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

```ts
import { Hono } from "hono"
import { createAuthdog } from "@authdog/hono"

const app = new Hono()
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

Mount `attachSession()` before routes:

```ts
app.use(authdog.attachSession())
```

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 stored as `c.get("authdog")`:

```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` is the security boundary and returns `401 {"error":"Unauthorized"}` unless `isAuthenticated` is true:

```ts
app.get("/me", authdog.requireAuth, (c) => c.json(c.get("authdog")!.user))
```

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
app.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)
