The `@authdog/redwood` SDK provides browser callback utilities and an API-side `requireAuth` gate for RedwoodJS Functions and services.

## Install

```bash
yarn workspace web add @authdog/redwood @authdog/react-elements
yarn workspace api add @authdog/redwood
```

Requires React 18 or 19. The package exposes `@authdog/redwood/web` and `@authdog/redwood/api`.

## Handle the web callback

```tsx
// web/src/App.tsx
import { useEffect } from "react"
import { initAuthdog } from "@authdog/redwood/web"
import { RedwoodProvider } from "@redwoodjs/web"
import Routes from "src/Routes"

const App = () => {
  useEffect(() => {
    initAuthdog()
  }, [])

  return (
    <RedwoodProvider titleTemplate="%PageTitle | %AppTitle">
      <Routes />
    </RedwoodProvider>
  )
}
```

`initAuthdog()` strips `?token=`, stores values that match JWT structure in `localStorage`, and reloads. This is not cryptographic validation. The exported `AuthdogProvider` only strips the token and reloads; it does not persist or exchange it, so do not wrap this bootstrap with that provider. Expose browser configuration as `REDWOOD_ENV_AUTHDOG_PUBLIC_KEY` and add it to `includeEnvironmentVariables` in `redwood.toml`.

## Protect a Function

On the api side, `createAuthdog` uses your environment's **public key** (`pk_...`, server-only via `PK_AUTHDOG`). `requireAuth` accepts either `Authorization: Bearer <token>` or an `authdog-session` cookie, validates it through userinfo, returns `401` on failure, and attaches `event.authdog` on success:

```ts
// api/src/functions/me.ts
import { createAuthdog } from "@authdog/redwood/api"
import type { LambdaEvent } from "@authdog/redwood/api"

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

export const handler = authdog.requireAuth(async (event: LambdaEvent) => ({
  statusCode: 200,
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ user: event.authdog?.user ?? null }),
}))
```

Send the stored token when calling the Function:

```ts
import { initAuthdog } from "@authdog/redwood/web"

const token = initAuthdog()
const response = await fetch("/.redwood/functions/me", {
  headers: token ? { Authorization: `Bearer ${token}` } : {},
})
```

The SDK does not create `authdog-session`; if you prefer an HttpOnly cookie, implement a server callback that validates the token before setting it.

Re-export the logout handler to clear `authdog-session`:

```ts
// api/src/functions/logout.ts
export { logoutHandler as handler } from "@authdog/redwood/api"
```

In services, resolve the user from the GraphQL context: `await authdog.getUser(context.event)`.

When using the bearer/local-storage flow, also call `clearAuthdogToken()` in the browser. Treat `requireAuth` on the api side as the security boundary and pair it with your [authorization](/docs/concepts/authorization) model.

## Next steps

- [Component reference](/docs/components): the `@authdog/react-elements` UI.
- [Backend requests](/docs/backend): the verification model, in depth.
