Zero Accessby Railmandocs
Packages

Elevate

Getting started with @railman/auth-elevate — step-up / sudo for Better Auth.

Getting started — Elevate

@railman/auth-elevate adds a short step-up window on an existing session. It does not unlock vault material.

Demo: /elevate · Guide: Elevate and sudo · HTTP: API

Install

pnpm add @railman/auth-elevate @railman/auth-login-factor
# optional TOTP storage:
# better-auth twoFactor plugin
# optional passkey step-up:
# @better-auth/passkey @railman/auth-zero-access-passkey

Minimal — password / TOTP only

import { betterAuth } from "better-auth";
import { twoFactor } from "better-auth/plugins";
import { elevate, requireElevate } from "@railman/auth-elevate";
import { loginFactors } from "@railman/auth-login-factor";

export const auth = betterAuth({
  plugins: [
    loginFactors(),
    twoFactor(),
    elevate({
      deploymentMode: "single-instance",
      // omit passkeyCounterGuard → passkey step-up off
      passwordOnlyIfNoStronger: true,
      elevatedTtlSec: 300,
    }),
  ],
});

Gate a route:

await requireElevate(session.session.elevateClaim, {
  userId: session.user.id,
  sessionToken: session.session.token ?? session.session.id,
  secret: process.env.BETTER_AUTH_SECRET!,
  ttlSec: 300,
});

With passkey step-up

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"],
  assertCredentialAccess: "session",
});

elevate({
  deploymentMode: "single-instance",
  passkeyCounterGuard: passkeyStack.controller,
  passwordOnlyIfNoStronger: true,
  elevatedTtlSec: 300,
});

Client

import { elevateClient } from "@railman/auth-elevate/client";

createAuthClient({ plugins: [elevateClient()] });

Key options

OptionDefault intent
deploymentMode"single-instance" lab · "multi-instance" + shared stores in prod
elevatedTtlSec300
passwordOnlyIfNoStrongertrue
passkeyCounterGuardOptional — omit to disable passkey method

Next

On this page