Compose
Passkey login
Hardened WebAuthn login without step-up, vault, or chat.
Passkey login
Use this when you want hardened WebAuthn sign-in (counter guard, secure stock options) and nothing else yet — no elevate, no vault, no chat.
enhancePasskey(passkey, …) builds stock @better-auth/passkey from frozen secure options and pairs the guard plugin. You never hand raw options to stock yourself.
Chooser: Use cases · Primer: WebAuthn and PRF
What you install
| Package | Role |
|---|---|
@better-auth/passkey | Stock passkey factory — passed into enhancePasskey only |
@railman/auth-zero-access-passkey | Guard + stock composition + posture |
Server composition
import { betterAuth } from "better-auth";
import { passkey } from "@better-auth/passkey";
import { enhancePasskey } from "@railman/auth-zero-access-passkey";
const passkeyStack = enhancePasskey(passkey, {
rpID: "example.com",
origin: ["https://example.com"],
// Integrate: any session may manage credentials.
// Production: custom step-up assertion (see Passkey + step-up).
assertCredentialAccess: "session",
});
export const auth = betterAuth({
secret: process.env.BETTER_AUTH_SECRET!,
plugins: [...passkeyStack.plugins],
});Spread ...passkeyStack.plugins — that is the stock passkey plugin plus the counter guard.
Gradual security
| Rung | Option | Until then |
|---|---|---|
| 0 — integrate | assertCredentialAccess: "session" or "deny" | Management open to any session, or off |
| 1 — management | custom assertion (e.g. elevate sudo) | Session-wide or denied management |
| 2 — graduate | securityLevel: "strict" | Standard keeps integration warnings |
Pin posture in CI when you are production-ready:
expect(passkeyStack.posture).toMatchObject({
level: "strict",
management: "custom",
next: [],
});passkeyStack.posture.next lists what is still missing.
Client
import { createAuthClient } from "better-auth/client";
import { passkeyClient } from "@better-auth/passkey/client";
export const authClient = createAuthClient({
plugins: [passkeyClient()],
});Next
- Add step-up on the same counter: Passkey + step-up
- Ceremony and PRF detail: Passkeys & PRF
- Package getting started: Passkey
- HTTP / plugin surface: API · Plugin contract
Vault and Chat require this passkey composition. Elevate alone does not.