This addon provides passkey (WebAuthn) authentication for a RedwoodSDK project.

This addon provides passkey (WebAuthn) authentication for a RedwoodSDK project.
These instructions assume you are starting with a new RedwoodSDK project, for example from npx create-rwsdk -t minimal my-project-name.
To use your editor's AI agent support to add this addon for you (e.g. Cursor, VSCode Copilot):
npx create-rwsdk -t minimal my-project-nameAgent modePlease apply this addon to my RedwoodSDK project using these instructions: https://raw.githubusercontent.com/redwoodjs/passkey-addon/refs/heads/main/README.md
Alternatively, to apply this addon manually, simply follow the steps below.
npx degit redwoodjs/sdk-experiments/passkey-addon _tmp_passkey_addon
Copy the src directory from this addon into your project's root directory. This will add the following directories:
src/passkey: Core logic for passkey authentication.src/session: Session management using a Durable Object.package.jsonAdd the following dependencies to your package.json file:
"dependencies": {
"@simplewebauthn/browser": "^13.1.0",
"@simplewebauthn/server": "^13.1.1",
}
Then run pnpm install.
wrangler.jsoncUpdate your wrangler.jsonc to add Durable Object bindings, environment variables, and database migrations.
{
// ... existing configuration ...
// Durable Objects configuration
"durable_objects": {
"bindings": [
{
"name": "SESSION_DURABLE_OBJECT",
"class_name": "SessionDurableObject"
},
{
"name": "PASSKEY_DURABLE_OBJECT",
"class_name": "PasskeyDurableObject"
}
]
},
// Migrations
"migrations": [
{
"tag": "v1",
"new_sqlite_classes": ["PasskeyDurableObject"]
}
]
}
src/worker.tsxModify your src/worker.tsx to integrate the passkey authentication and routes.
// ...
import { authRoutes } from "@/passkey/routes";
import { setupPasskeyAuth } from "@/passkey/setup";
import { Session } from "@/session/durableObject";
export { SessionDurableObject } from "@/session/durableObject";
export { PasskeyDurableObject } from "@/passkey/durableObject";
export type AppContext = {
// ...
session: Session | null;
};
export default defineApp([
// ...
setCommonHeaders(),
setupPasskeyAuth(),
render(Document, [
// ...
index([
({ ctx }) => {
if (!ctx.session?.userId) {
return new Response(null, {
status: 302,
headers: { Location: "/auth/login" },
});
}
},
Home,
]),
prefix("/auth", authRoutes()),
]),
]);
src/app/pages/Home.tsxAdd a login link to your Home.tsx page.
// ...
export function Home({ ctx }: RequestInfo) {
return (
<div>
{/* ... */}
<p>
<a href="/auth/login">Login</a>
</p>
</div>
);
}
The first time you run the development server, it will generate the .wrangler folder and local Cloudflare environment.
pnpm dev
This will ensure that all the environmental types needed for the Passkey Auth are generated
You should now have a working passkey authentication flow in your RedwoodSDK application!