Authdog

Redwood

Last updated Jul 11, 2026
View as Markdown

The @authdog/redwood SDK integrates Authdog with RedwoodJS across both sides of the app: a React provider on the web side and a server client on the api side with a requireAuth gate for Functions and services. It reads the session Authdog issues.

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.

Wrap the web app

TSX
// web/src/App.tsx
import "@authdog/react-elements/styles.css"
import { AuthdogProvider } from "@authdog/redwood/web"

const App = () => (
  <AuthdogProvider>
    <RedwoodProvider titleTemplate="%PageTitle | %AppTitle">
      <Routes />
    </RedwoodProvider>
  </AuthdogProvider>
)

The provider captures the ?token= from the sign-in redirect and persists the session. Expose the browser public key as REDWOOD_ENV_AUTHDOG_PUBLIC_KEY (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). Its requireAuth wrapper is the enforcement point — it returns a 401 result and attaches event.authdog:

TypeScript
// 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 }),
}))

Re-export the ready-made logout handler for sign-out:

TypeScript
// 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).

The web provider is UX only — treat requireAuth on the api side as the security boundary and pair it with your authorization model.

Next steps