Build

Who is asking, and may they.

Authentication and authorization are one subsystem, not an auth package next to a permissions package that disagree about what a user is. Turn on the useAuth trait and the columns, the passkey tables, the social providers, and the guards arrive together, whether a user signs in with a password, a passkey, a social account, or a magic link.

What you get.

All of it in the same install, with nothing to wire together first.

Sessions and tokens

Cookie sessions for the browser and API tokens for everything else, both resolving to the same authenticated user.

Social login

GitHub, Google, Facebook, and X sign-in over OAuth2 with PKCE, with account linking so a social login and a password resolve to the same user.

Magic links

Passwordless email sign-in with single-use, rate-limited tokens, for the products that would rather not ask for a password at all.

Passkeys

WebAuthn registration and assertion, with the credential tables added by the useAuth trait rather than by hand.

Two-factor

TOTP enrolment, verification, and recovery codes, on the same model as the password.

Gates and policies

app/Gates.ts holds the checks; policies put per-model rules next to the model they guard.

Roles and permissions

RBAC with roles, permissions, and the relations already migrated.

Request protection

CSRF tokens on every state-mutating route by default, plus per-route and per-identity rate limits and account lockout after repeated failed logins.

From the command line.

Buddy scaffolds, runs, and ships this the same way it does the rest of the app.

buddy migrate --auth buddy make:policy PostPolicy buddy make middleware EnsureVerified

These share the same models, config, and types, so using them together costs nothing extra.