The `@authdog/astro` SDK provides cookie-reading middleware, userinfo-backed server validation, logout, and a browser token bootstrap for SSR-capable Astro sites.

## Install

```package-install
@authdog/astro
```

Requires Astro `^5` or `^6` with SSR enabled (`output: "server"` or `"hybrid"`). The package ships `@authdog/astro/server` and `@authdog/astro/client`.

## Add the middleware

`authdogMiddleware` populates `Astro.locals.authdog` (`{ session, isAuthenticated }`) on every request. `session` is the raw `authdog-session` cookie, and `isAuthenticated` means only that this cookie exists:

```ts
// src/middleware.ts
import { defineMiddleware } from "astro:middleware"
import { authdogMiddleware } from "@authdog/astro/server"

export const onRequest = defineMiddleware(
  authdogMiddleware({
    publicKey: import.meta.env.PUBLIC_AUTHDOG_PUBLIC_KEY ?? "",
  }),
)
```

Declare the locals type in `src/env.d.ts`:

```ts
declare namespace App {
  interface Locals {
    authdog: import("@authdog/astro/server").AuthdogLocals
  }
}
```

## Read the user in a page

`createAuthdogServer().getUser()` validates the cookie through Authdog userinfo. Use that result, not the middleware boolean, as the authentication decision:

```astro
---
import { createAuthdogServer } from "@authdog/astro/server"

const authdog = createAuthdogServer({
  publicKey: import.meta.env.PUBLIC_AUTHDOG_PUBLIC_KEY ?? "",
})

const profile = await authdog.getUser(Astro.request).catch(() => null)
if (!profile) {
  return Astro.redirect("/sign-in")
}
---

<p>Signed in as {profile.user.emails?.[0]?.value}</p>
```

## Sign out

Expose an endpoint that calls `authdog.logout`, which clears the cookie and redirects:

```ts
// src/pages/api/logout.ts
import type { APIRoute } from "astro"
import { createAuthdogServer } from "@authdog/astro/server"

const authdog = createAuthdogServer({
  publicKey: import.meta.env.PUBLIC_AUTHDOG_PUBLIC_KEY ?? "",
})

export const GET: APIRoute = ({ request }) => authdog.logout(request)
```

## Client bootstrap

Run `initAuthdog()` once on the client to shape-check `?token=`, store it in `localStorage`, remove it from the URL, and reload:

```astro
<script>
  import { initAuthdog } from "@authdog/astro/client"
  initAuthdog()
</script>
```

This browser bootstrap does not create the server's `authdog-session` cookie. Your callback/backend must validate the token and set that cookie as `HttpOnly`, `Secure`, and `SameSite`; the package does not include that exchange. Pair validated identity with [authorization](/docs/concepts/authorization).

## Next steps

- [Sign up & sign in](/docs/authentication): the flows behind the redirect.
- [Backend requests](/docs/backend): the verification model, in depth.
