Authdog

RedwoodJS

Last updated Jul 19, 2026npmlatestCI passing
View as Markdown

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

Install

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

// 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:

// 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:

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:

// 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 bearer/local-storage flow, also call clearAuthdogToken() in browser. Treat requireAuth on API side as security boundary and pair it with your authorization model.

Next steps

Learn more