Quickback Docs

Using Auth

Sign-in flows, session handling, and organization context in the Quickback Stack

This page covers how to use Better Auth in your Quickback Stack application — sign-in flows, session management, and working with organization context.

Sign-In Flows

Better Auth supports multiple sign-in methods:

  • Email/Password — Traditional credential-based authentication
  • Email OTP — One-time passwords sent via email
  • Magic Links — Passwordless email links
  • Passkeys — WebAuthn biometric/hardware key authentication

Session Handling

Sessions live in the auth database — that is the source of truth. When your project uses the cloudflare-kv storage provider, the compiler wires that KV namespace up as Better Auth's secondaryStorage, which caches session lookups at the edge in front of the database. KV is a cache, not the store.

The generated auth middleware resolves the session once per request and hydrates a single Hono context variable, ctx — it does not set session or user variables:

// Access the auth context in a Hono route
app.get('/api/me', async (c) => {
  const ctx = c.get('ctx');
  if (!ctx.authenticated) return c.json({ error: 'Unauthorized' }, 401);

  return c.json({
    userId: ctx.userId,     // Better Auth user id
    user:   ctx.user,       // { id, email, name }
    roles:  ctx.roles,      // org member roles: ['owner' | 'admin' | 'member']
  });
});

ctx also carries authMethod ('session' | 'jwt' | 'api-key' | 'oauth' | 'principal'), userRole (the global user-table role), activeTeamId, and scope. In action and CRUD handlers this same object arrives as the ctx argument — you rarely call c.get('ctx') directly.

Organization Context

When organizations are enabled, the active organization is on the auth context as activeOrgId:

const orgId = c.get('ctx').activeOrgId;

`activeOrgId`, not `activeOrganizationId`

activeOrganizationId is Better Auth's session field name (session.session.activeOrganizationId). Quickback canonicalises it to ctx.activeOrgId; firewall rules written against ctx.activeOrganizationId are rewritten to ctx.activeOrgId at compile time.

On this page