Login factor
Getting started with @railman/auth-login-factor — L0 stamps and requireAccess maps.
Getting started — Login factor
@railman/auth-login-factor stamps how the session was established and exposes requireAccess maps for L0 / L1 gates. Cookie lastLoginMethod is never an authorization input.
HTTP: none (plugin hooks + server helpers) · API helpers: API — privilege
Install
pnpm add @railman/auth-login-factorSetup
import { betterAuth } from "better-auth";
import {
AUTH_REQUIRE_PRESETS,
createElevateOpener,
loginFactors,
requireAccess,
} from "@railman/auth-login-factor";
const secret = process.env.BETTER_AUTH_SECRET!;
export const auth = betterAuth({
secret,
session: {
// Required: cookieCache would expose returned session fields to the client
cookieCache: { enabled: false },
},
plugins: [loginFactors()],
});
export async function assertPrivileged(session: {
userId: string;
sessionToken: string;
loginFactor?: string | null;
elevateClaim?: string | null;
}) {
await requireAccess({
secret,
session,
map: AUTH_REQUIRE_PRESETS.privilegedAction,
elevateOpener: createElevateOpener({
secret,
userId: session.userId,
sessionToken: session.sessionToken,
ttlSec: 300,
maxElevatedSec: 3600,
}),
// enrolled: { passkey, totp, password }, // server lookup for password AMR
});
}Ensure the Better Auth schema includes the optional loginFactor string field before enabling the plugin.
Presets
| Preset | Meaning |
|---|---|
sessionOnly | Signed L0 session |
elevateSudo | Session + elevate (distinct when required) |
privilegedAction | Elevate: passkey/TOTP; password only if no stronger enrolled |
recoveryControlPlane | Session + passkey/TOTP, distinct from session factor |
Maps must be server constants — never from request body/query.
With elevate
Install loginFactors() whenever you use requireDistinctInitialFactor or requireAccess with elevate AMR. Strict elevate setup rejects a missing login-factor plugin. Pass elevateOpener: createElevateOpener({ secret, userId, sessionToken }) into requireAccess whenever the map inspects elevate claims.