---
title: "@kovojs/better-auth"
description: Better Auth adapter: typed session/sign-in/up/out mutations, authed/role guards, and the redirect-protocol mount.
order: 7
---

# @kovojs/better-auth

Generated from 3 public subpaths — 28 exports, 28 documented. Do not edit by hand.

## `@kovojs/better-auth`

**Task:** Shared app-binding contracts, session guards, CSRF configuration, and redirect-protocol mounting.

Source: [`packages/better-auth/src/index.ts`](https://github.com/kovojs/kovo/blob/main/packages/better-auth/src/index.ts)

### Values

#### `authed` {#authed}

Guard that requires an authenticated session, narrowing the request to an
`AuthenticatedRequest`. A thin re-export of the framework's `guards.authed` for use on
auth-protected mutations and routes; an unauthenticated request denies with a
login-redirect intent (SPEC.md §6.5).

**Signature**

```ts
function authed<Request extends SessionRequestLike>(): Guard<
  Request,
  AuthenticatedRequest<Request>
>;
```

#### `role` {#role}

Guard that requires the session user to hold a given role. Denies with an
unauthenticated (→ login redirect) intent when there is no session user, and with a
forbidden (→ 403) intent when the user lacks the role. The role name is type-checked
against the request's own `roles` element type when known (SPEC.md §6.5).

**Signature**

```ts
function role<Request extends BetterAuthRoleRequest>(
  requiredRole: NonNullable<NonNullable<Request['session']>['user']> extends {
    roles?: readonly (infer Role)[] | null;
  }
    ? Extract<Role, string>
    : string,
): Guard<Request>;
function role(requiredRole: string): Guard<BetterAuthRoleRequest>;
```

#### `betterAuthCsrfFromEnvironment` {#betterauthcsrffromenvironment}

Create a frozen CSRF config from bootstrap-pinned operator signing material.

The raw environment string is consumed inside this first-party package and converted to an
opaque signing-key ring before the result crosses into generated source (SPEC §6.6 C9).

**Signature**

```ts
function betterAuthCsrfFromEnvironment<
  Request extends BetterAuthCsrfRequestLike = BetterAuthCsrfRequestLike,
>(options: BetterAuthEnvironmentCsrfOptions): Readonly<CsrfOptions<Request>>;
```

#### `mount` {#mount}

Mounts Better Auth's own request handler at a prefix endpoint so its browser redirect
protocol — OAuth/magic-link callbacks and similar safe-method provider round-trips — is served
under one declared path, while credential forms stay on typed mutations (SPEC.md §9.1).

SECURITY — this endpoint is always declared with `csrf: false`. Per SPEC.md §6.6, CSRF
protection is default-ON for server-rendered, cookie-authenticated mutations, and
`csrf: false` is the framework's *sanctioned opt-out* reserved for endpoints that are
not browser-form-driven or are authenticated by some other means (e.g. non-browser /
externally-authenticated callers). Better Auth's redirect protocol handler is exactly
such an endpoint: the inbound requests are external-provider redirects and the
library-supplied OAuth `state` parameter (not a Kovo CSRF token) carries the
anti-forgery guarantee, so a Kovo CSRF token cannot be present or required here.
Disabling CSRF on this prefix does NOT relax protection on the app's own credential
mutations, which keep CSRF on. The framework hardcodes GET: an unsafe-method callback needs a
separate framework-owned, self-verifying adapter rather than widening this prefix authority.

**Signature**

```ts
function mount<const Path extends string>(
  path: Path,
  adapter: BetterAuthMountAdapter,
): EndpointDeclaration<Path, 'GET', 'prefix'>;
```

#### `betterAuthPasswordResetMailDoor` {#betterauthpasswordresetmaildoor}

Validate and capture a deployer mail sender behind an opaque password-reset-only capability.

The type brand is ergonomics; exact registry membership is the runtime authority.

**Signature**

```ts
function betterAuthPasswordResetMailDoor(
  send: BetterAuthPasswordResetMailSender,
): BetterAuthPasswordResetMailDoor;
```

### Supporting types

#### `BetterAuthAppBindings` {#betterauthappbindings}

Capability-minimized result shared by the Postgres and SQLite app binding constructors.

The raw Better Auth instance, Drizzle adapter, system database, deployment secret, and signing
controls are structurally absent (SPEC §6.6/§10.3 C9).

**Signature**

```ts
interface BetterAuthAppBindings<
  SessionValue extends { id: string },
  Request extends BetterAuthAppRequest<SessionValue> = BetterAuthAppRequest<SessionValue>,
  AuthenticatedRequest extends Request = Request & { session: SessionValue },
> {
  /** Opaque provider/callback router token accepted only by `mount()`. */
  mountAdapter: BetterAuthMountAdapter;
  /** Create the configured fixed development account, or do nothing when disabled/production. */
  seedDemoUser(): Promise<void>;
  /** Runtime-sanitized Better Auth session provider. */
  sessionProvider: SessionProvider<Request, SessionValue>;
  /** CSRF-protected Better Auth email/password sign-in mutation. */
  signIn: BetterAuthAppSignInMutation<Request>;
  /** CSRF-protected Better Auth sign-out mutation with framework-fixed authenticated access. */
  signOut: BetterAuthAppSignOutMutation<Request, AuthenticatedRequest>;
}
```

#### `BetterAuthAppBindingsOptions` {#betterauthappbindingsoptions}

Human-authored options shared by the Postgres and SQLite app binding constructors.

Deployment secrets, base URL, persistent revocation storage, authenticated sign-out posture,
and system database authority are framework-owned and therefore cannot be supplied here (SPEC
§6.6/§10.3 C9).

**Signature**

```ts
interface BetterAuthAppBindingsOptions<
  SessionValue extends { id: string },
  Request extends BetterAuthAppRequest<SessionValue> = BetterAuthAppRequest<SessionValue>,
> {
  /** Kovo CSRF configuration shared by the credential mutations. */
  csrf: CsrfOptions<Request>;
  /** Sanitized projection from Better Auth's credential-free session/user records. */
  mapSession: BetterAuthSessionMapper<Session, User, SessionValue>;
  /** Exact Better Auth Drizzle table record from the app's pinned schema. */
  schema: Record<string, unknown>;
  /** Explicit pre-auth access decision for the sign-in mutation. */
  signInAccess: AccessDecision;
}
```

#### `BetterAuthAppCredentialResult` {#betterauthappcredentialresult}

Public wire result returned by the first-party credential mutations.

**Signature**

```ts
interface BetterAuthAppCredentialResult<Status extends string> {
  /** Same-origin destination applied after the credential transition. */
  redirectTo: string;
  /** Stable credential-transition outcome. */
  status: Status;
}
```

#### `BetterAuthAppRequest` {#betterauthapprequest}

Lifecycle request consumed by the first-party Better Auth app binding.

The request contains only Kovo's native request carrier, resolved client identity, CSRF identity,
and sanitized session. Raw Better Auth request/context objects are deliberately absent (SPEC
§6.6).

**Signature**

```ts
type BetterAuthAppRequest<SessionValue extends { id: string } = { id: string }> = {
  /** Framework-resolved anonymous pre-auth identity, when available. */
  authCsrfId?: string | null;
  /** Framework-resolved client IP attached by Kovo's request lifecycle (SPEC §9.5). */
  clientIp?: string;
  /** Native request headers used by the fixed Better Auth session provider. */
  headers: Headers;
  /** Sanitized app session returned by the configured mapper. */
  session?: SessionValue | null;
  /** Absolute incoming request URL from Kovo's native request carrier. */
  url: string;
} & BetterAuthCsrfRequestLike;
```

#### `BetterAuthAppSignInMutation` {#betterauthappsigninmutation}

CSRF-protected email/password sign-in mutation returned by an app binding constructor.

**Signature**

```ts
type BetterAuthAppSignInMutation<Request extends BetterAuthAppRequest> = MutationDefinition<
  'auth/sign-in',
  Schema<{ email: string; next: string | undefined; password: string }>,
  {
    INVALID_CREDENTIALS: Schema<Record<string, never>>;
    RATE_LIMITED: Schema<Record<string, never>>;
  },
  Request,
  BetterAuthAppCredentialResult<'signed-in'>,
  Request
> &
  MutationFormDefinition<'auth/sign-in', Request> &
  AppMutationAdapter;
```

#### `BetterAuthAppSignOutMutation` {#betterauthappsignoutmutation}

CSRF-protected sign-out mutation returned by an app binding constructor.

**Signature**

```ts
type BetterAuthAppSignOutMutation<
  Request extends BetterAuthAppRequest,
  AuthenticatedRequest extends Request,
> = MutationDefinition<
  'auth/sign-out',
  Schema<Record<string, never>>,
  Record<string, never>,
  Request,
  BetterAuthAppCredentialResult<'signed-out'>,
  AuthenticatedRequest
> &
  MutationFormDefinition<'auth/sign-out', Request> &
  AppMutationAdapter;
```

#### `BetterAuthRoleRequest` {#betterauthrolerequest}

Minimal request shape the `role` guard reads: an optional `session`.

**Signature**

```ts
interface BetterAuthRoleRequest {
  session?: BetterAuthRoleSession | null;
}
```

#### `BetterAuthRoleSession` {#betterauthrolesession}

Minimal session shape the `role` guard reads: an optional `user`.

**Signature**

```ts
interface BetterAuthRoleSession {
  user?: BetterAuthRoleUser | null;
}
```

#### `BetterAuthRoleUser` {#betterauthroleuser}

Minimal user shape the `role` guard reads: an optional `id` and an optional `roles`
list. Apps' own session-user types structurally satisfy this (SPEC.md §6.5).

**Signature**

```ts
interface BetterAuthRoleUser {
  id?: string;
  roles?: readonly string[] | null;
}
```

#### `BetterAuthCsrfRequestLike` {#betterauthcsrfrequestlike}

Request fields the framework-owned Better Auth CSRF binding is permitted to inspect.

**Signature**

```ts
interface BetterAuthCsrfRequestLike {
  /** Anonymous pre-auth identity, when the request lifecycle has already resolved one. */
  authCsrfId?: string | null;
  /** Sanitized Better Auth session identity resolved by the framework session provider. */
  session?: { id: string } | null;
}
```

#### `BetterAuthEnvironmentCsrfOptions` {#betterauthenvironmentcsrfoptions}

Options used to build a CSRF config from boot-pinned signing material.

**Signature**

```ts
interface BetterAuthEnvironmentCsrfOptions {
  /** Form field name used by generated credential mutations. */
  field: string;
}
```

#### `BetterAuthMountAdapter` {#betterauthmountadapter}

Opaque handle for the Better Auth router privately constructed by Kovo's fixed database
bindings. It exposes no handler or auth object; {@link mount} is its only app-facing consumer
(SPEC §6.6/§9.1).

**Signature**

```ts
interface BetterAuthMountAdapter {
  readonly [betterAuthMountAdapterBrand]: 'kovo-better-auth-mount-adapter';
}
```

#### `BetterAuthPasswordResetMailDoor` {#betterauthpasswordresetmaildoor-1}

Opaque capability for the single password-reset mail purpose.

Construct it with {@link betterAuthPasswordResetMailDoor}; structural objects and callbacks
cannot be supplied directly to a fixed binding (SPEC §6.6 C9-C10).

**Signature**

```ts
interface BetterAuthPasswordResetMailDoor {
  readonly [betterAuthPasswordResetMailDoorBrand]: 'better-auth-password-reset-mail-door';
}
```

#### `BetterAuthPasswordResetMailMessage` {#betterauthpasswordresetmailmessage}

The only data Kovo permits to cross its password-reset email-egress door (SPEC §6.6/§9.2).

**Signature**

```ts
interface BetterAuthPasswordResetMailMessage {
  /** Validated recipient selected by the fixed Better Auth account-recovery operation. */
  readonly to: string;
  /** Same-origin Better Auth callback URL carrying the opaque reset token. */
  readonly resetUrl: string;
}
```

#### `BetterAuthPasswordResetMailSender` {#betterauthpasswordresetmailsender}

A deployer-owned mail sender invoked only with a password-reset message.

**Signature**

```ts
type BetterAuthPasswordResetMailSender = (
  message: Readonly<BetterAuthPasswordResetMailMessage>,
) => Promise<void>;
```

#### `BetterAuthPasswordResetOptions` {#betterauthpasswordresetoptions}

Feature-conditional password-reset options accepted by fixed SQLite/Postgres bindings.

**Signature**

```ts
interface BetterAuthPasswordResetOptions {
  /** Explicit pre-auth access decision for the CSRF-protected request mutation. */
  access: AccessDecision;
  /** Constructor-minted, purpose-closed mail capability. */
  mail: BetterAuthPasswordResetMailDoor;
  /** Canonical same-origin path that receives Better Auth's reset token redirect. */
  resetPath: string;
}
```

#### `BetterAuthSafeField` {#betterauthsafefield}

Author-time field-key filter used by Better Auth's sanitized session projection. Credential
nouns are omitted when they are the whole key, a snake/kebab suffix, or a camel-case suffix.
Runtime recursive reconstruction remains the confidentiality proof (SPEC §10.3 C9-C10).

**Signature**

```ts
type BetterAuthSafeField<Key> = Key extends string
  ? Lowercase<Key> extends
      | 'apikey'
      | 'apisecret'
      | 'backupcode'
      | 'backupcodes'
      | 'certificate'
      | 'code'
      | 'codes'
      | 'credential'
      | 'credentials'
      | 'hash'
      | 'key'
      | 'keys'
      | 'otp'
      | 'passcode'
      | 'passphrase'
      | 'password'
      | 'pin'
      | 'privatekey'
      | 'salt'
      | 'secret'
      | 'secrets'
      | 'seed'
      | 'signature'
      | 'token'
      | 'tokens'
    ? never
    : Key extends
          | `${string}${
              | 'ApiKey'
              | 'ApiSecret'
              | 'BackupCode'
              | 'BackupCodes'
              | 'Certificate'
              | 'Code'
              | 'Codes'
              | 'Credential'
              | 'Credentials'
              | 'Hash'
              | 'Key'
              | 'Keys'
              | 'Otp'
              | 'Passcode'
              | 'Passphrase'
              | 'Password'
              | 'Pin'
              | 'PrivateKey'
              | 'Salt'
              | 'Secret'
              | 'Secrets'
              | 'Seed'
              | 'Signature'
              | 'Token'
              | 'Tokens'}`
          | `${string}${'_' | '-'}${
              | 'apikey'
              | 'apisecret'
              | 'backupcode'
              | 'backupcodes'
              | 'certificate'
              | 'code'
              | 'codes'
              | 'credential'
              | 'credentials'
              | 'hash'
              | 'key'
              | 'keys'
              | 'otp'
              | 'passcode'
              | 'passphrase'
              | 'password'
              | 'pin'
              | 'privatekey'
              | 'salt'
              | 'secret'
              | 'secrets'
              | 'seed'
              | 'signature'
              | 'token'
              | 'tokens'}`
      ? never
      : Key
  : Key;
```

#### `BetterAuthSanitizedRecord` {#betterauthsanitizedrecord}

A Better Auth row after Kovo removes credential-shaped fields before app code sees it. The
mapped type is author-time defense-in-depth; recursive runtime reconstruction owns enforcement
(SPEC §10.3 C9 and AGENTS.md's type-level security ergonomics rule).

**Signature**

```ts
type BetterAuthSanitizedRecord<Value> = Value extends object
  ? {
      [Key in keyof Value as BetterAuthSafeField<Key>]: BetterAuthSanitizedValue<Value[Key]>;
    }
  : Value;
```

#### `BetterAuthSanitizedSessionPayload` {#betterauthsanitizedsessionpayload}

The reconstructed `{ session, user }` projection delivered to an app-authored session mapper.
Better Auth bearer tokens, password hashes, API keys, and similarly credential-shaped fields
are absent at runtime and omitted from the common TypeScript field vocabulary.

**Signature**

```ts
interface BetterAuthSanitizedSessionPayload<Session, User> {
  session: BetterAuthSanitizedRecord<Session>;
  user: BetterAuthSanitizedRecord<User>;
}
```

#### `BetterAuthSanitizedValue` {#betterauthsanitizedvalue}

A recursively reconstructed Better Auth value. JSON objects lose credential-shaped fields,
arrays and dates are copied, and scalar values are preserved.

**Signature**

```ts
type BetterAuthSanitizedValue<Value> = Value extends Date
  ? Date
  : Value extends readonly unknown[]
    ? { [Index in keyof Value]: BetterAuthSanitizedValue<Value[Index]> }
    : Value extends object
      ? BetterAuthSanitizedRecord<Value>
      : Value;
```

#### `BetterAuthSessionMapper` {#betterauthsessionmapper}

Function the app supplies to a fixed SQLite/Postgres binding constructor to project Better
Auth's `{ session, user }` payload into the app's own session value. Called once per authenticated
request (SPEC §6.5/§6.6).

**Signature**

```ts
type BetterAuthSessionMapper<AuthSession, AuthUser, SessionValue> = (
  value: BetterAuthSanitizedSessionPayload<AuthSession, AuthUser>,
) => SessionValue;
```

## `@kovojs/better-auth/postgres`

**Task:** Purpose-closed Better Auth bindings for one framework-owned Postgres app runtime.

Source: [`packages/better-auth/src/public-postgres.ts`](https://github.com/kovojs/kovo/blob/main/packages/better-auth/src/public-postgres.ts)

### Values

#### `createBetterAuthPostgresAppBindings` {#createbetterauthpostgresappbindings}

Bind Better Auth to an exact framework-owned Postgres app runtime.

Kovo mints the purpose-closed system database capability internally, fixes persistent principal
revocation and authenticated sign-out posture, consumes deployment secrets/base URL from the
boot-pinned environment, and returns only sanitized app bindings (SPEC §6.6/§10.3 C9).

**Signature**

```ts
function createBetterAuthPostgresAppBindings<
  SessionValue extends { id: string },
  Request extends BetterAuthAppRequest<SessionValue> = BetterAuthAppRequest<SessionValue>,
>(
  runtime: KovoPostgresAppRuntimeDb,
  options: BetterAuthAppBindingsOptions<SessionValue, Request>,
): Readonly<BetterAuthAppBindings<SessionValue, Request>>;
```

## `@kovojs/better-auth/sqlite`

**Task:** Purpose-closed Better Auth bindings for one framework-owned SQLite app runtime.

Source: [`packages/better-auth/src/public-sqlite.ts`](https://github.com/kovojs/kovo/blob/main/packages/better-auth/src/public-sqlite.ts)

### Values

#### `createBetterAuthSqliteAppBindings` {#createbetterauthsqliteappbindings}

Bind Better Auth to an exact framework-owned SQLite app runtime.

Kovo recovers the purpose-closed system database capability internally, fixes principal
revocation and authenticated sign-out posture, consumes deployment secrets/base URL from the
boot-pinned environment, and returns only sanitized app bindings (SPEC §6.6/§10.3 C9).

**Signature**

```ts
function createBetterAuthSqliteAppBindings<
  SessionValue extends { id: string },
  Request extends BetterAuthAppRequest<SessionValue> = BetterAuthAppRequest<SessionValue>,
>(
  runtime: KovoSqliteAppRuntime,
  options: BetterAuthAppBindingsOptions<SessionValue, Request>,
): Readonly<BetterAuthAppBindings<SessionValue, Request>>;
```

