Skip to main content

Overview

ZeroStarter uses Better Auth for authentication, providing a secure and feature-rich authentication system. All authentication endpoints are mounted at /api/auth/*.

Better Auth Configuration

The authentication system is configured in packages/auth/src/index.ts:
packages/auth/src/index.ts
import { betterAuth } from "better-auth"
import { drizzleAdapter } from "better-auth/adapters/drizzle"
import { openAPI, organization } from "better-auth/plugins"

export const auth = betterAuth({
  baseURL: env.HONO_APP_URL,
  trustedOrigins: env.HONO_TRUSTED_ORIGINS,
  database: drizzleAdapter(db, {
    provider: "pg",
    schema: {
      account,
      invitation,
      member,
      organization,
      session,
      team,
      teamMember,
      user,
      verification,
    },
  }),
  plugins: [
    openAPIPlugin(),
    organizationPlugin({
      teams: { enabled: true },
    }),
  ],
  socialProviders: {
    github: {
      clientId: env.GITHUB_CLIENT_ID,
      clientSecret: env.GITHUB_CLIENT_SECRET,
    },
    google: {
      clientId: env.GOOGLE_CLIENT_ID,
      clientSecret: env.GOOGLE_CLIENT_SECRET,
    },
  },
})

Authentication Endpoints

All Better Auth endpoints are available under /api/auth/*. The router handles both GET and POST requests:
api/hono/src/routers/auth.ts
export const authRouter = new Hono()
  .get("/get-session", (c) => auth.handler(c.req.raw))
  .on(["GET", "POST"], "/*", (c) => auth.handler(c.req.raw))

Core Endpoints

Retrieve the current authenticated session.Response:
{
  "session": {
    "id": "session_id",
    "userId": "user_id",
    "expiresAt": "2026-01-28T13:06:25.712Z",
    "token": "session_token"
  },
  "user": {
    "id": "user_id",
    "email": "[email protected]",
    "name": "John Doe",
    "emailVerified": true
  }
}
Sign in with email and password.Request Body:
{
  "email": "[email protected]",
  "password": "your-password"
}
Create a new account with email and password.Request Body:
{
  "email": "[email protected]",
  "password": "your-password",
  "name": "John Doe"
}
Sign out and invalidate the current session.Request Body:
{}
Initiate GitHub OAuth flow. Redirects to GitHub for authorization.
Initiate Google OAuth flow. Redirects to Google for authorization.
GitHub OAuth callback endpoint. Handles the redirect from GitHub.
Google OAuth callback endpoint. Handles the redirect from Google.

Better Auth API Reference

Better Auth provides its own comprehensive API documentation. You can access it at:
GET /api/auth/reference
This endpoint provides a complete reference of all available authentication endpoints, including:
  • Email/password authentication
  • Social OAuth providers
  • Session management
  • Organization management
  • Team management
  • Email verification
  • Password reset
  • Account linking

Authentication Flow

Email/Password Sign Up

1

Submit registration form

POST to /api/auth/sign-up/email with email, password, and name
2

Account created

User account is created in the database
3

Session established

Session cookie is set automatically
4

Redirect to dashboard

User is redirected to the application

OAuth Sign In

1

Initiate OAuth flow

Navigate to /api/auth/sign-in/github or /api/auth/sign-in/google
2

Provider authorization

User authorizes the application on GitHub or Google
3

Callback handling

Provider redirects to /api/auth/callback/{provider}
4

Account linking

Account is created or linked to existing account
5

Session established

Session cookie is set and user is redirected

Session Management

Better Auth uses secure HTTP-only cookies for session management:
  • Cookie Name: Configurable via cookiePrefix (based on HONO_APP_URL)
  • Cookie Domain: Automatically configured for cross-subdomain support
  • Security: HTTP-only, Secure (in production), SameSite=Lax
  • Expiration: Configurable session duration

Session Schema

interface Session {
  id: string
  userId: string
  token: string
  expiresAt: string
  createdAt: string
  updatedAt: string
  ipAddress: string | null
  userAgent: string | null
}

Organization & Team Support

ZeroStarter includes the Better Auth organization plugin with team support:
plugins: [
  organizationPlugin({
    teams: { enabled: true },
  }),
]
This enables:
  • Multi-tenant organizations
  • Team management within organizations
  • Role-based access control
  • Member invitations
  • Organization switching

Environment Variables

Required environment variables for authentication:
HONO_APP_URL
string
required
Base URL of your application (e.g., https://app.example.com)
HONO_TRUSTED_ORIGINS
string[]
required
Array of trusted origins for CORS (e.g., ["https://app.example.com"])
GITHUB_CLIENT_ID
string
GitHub OAuth application client ID
GITHUB_CLIENT_SECRET
string
GitHub OAuth application client secret
GOOGLE_CLIENT_ID
string
Google OAuth application client ID
GOOGLE_CLIENT_SECRET
string
Google OAuth application client secret

Protected Routes

Routes under /api/v1/* require authentication and use the authMiddleware:
api/hono/src/routers/v1.ts
export const v1Router = new Hono<{
  Variables: Session
}>()
  .use("/*", authMiddleware)
  // ... routes
The middleware:
  1. Validates the session cookie
  2. Retrieves the session and user from the database
  3. Injects session and user into the context
  4. Returns 401 Unauthorized if authentication fails

Security Best Practices

HTTP-Only Cookies

Sessions are stored in HTTP-only cookies, preventing XSS attacks

CORS Protection

Only trusted origins can access the API

Secure Connections

Production enforces HTTPS for all authentication requests

Rate Limiting

Authentication endpoints are rate-limited to prevent brute force

Next Steps

Session API

Learn how to retrieve session data

User API

Access authenticated user information

Better Auth Docs

Explore the full Better Auth documentation

Build docs developers (and LLMs) love