Permission Architecture
Map Better Auth entrypoints, session behavior, and role-based middleware boundaries.
MuseMVP's permission architecture is built on the Better Auth framework, offering a secure, flexible, and scalable authentication solution. Through unified configuration files and middleware, we achieve full-stack coverage from user login and session management to permission control.
Auth Entrypoints
Server Config
src/backend/auth/auth.ts — Defines Better Auth core options, plugins (admin, 2FA, emailOTP, captcha), and Drizzle database adapter.
Client Helper
src/backend/auth/client.ts — Provides hooks and utilities for the frontend (useSession, signIn, signOut).
API Route Mount
src/backend/api/routes/auth.ts — Mounts Better Auth handlers to the Hono API.
Core Configuration
Authentication behavior is configured in the auth object within src/config/index.ts, split into auth.gates and auth.lifecycle.
Feature Toggles
| Config Item | Type | Default | Description |
|---|---|---|---|
gates.allowRegister | boolean | true | Whether to enable new user registration. If disabled, new users can only be added by admins. |
gates.allowSocialSignIn | boolean | true | Whether to enable social login (GitHub, Google). Requires OAuth env vars. |
gates.allowPasswordSignIn | boolean | true | Whether to allow traditional email/password login. |
gates.allowTwoFactorAuth | boolean | true | Whether to enable Two-Factor Authentication (2FA). |
Session and Redirects
| Config Item | Default | Description |
|---|---|---|
lifecycle.redirectAfterLogin | "/app" | Path to redirect after successful login. |
lifecycle.redirectAfterSignOut | "/" | Path to redirect after logout. |
lifecycle.redirectWhenSessionExpired | "/auth/login" | Redirect when session expires or unauthenticated. |
lifecycle.sessionTtlSeconds | 30 days | Session Cookie validity period in seconds. |
Config Example
// src/config/index.ts
auth: {
gates: {
allowRegister: true,
allowSocialSignIn: true,
allowPasswordSignIn: true,
allowTwoFactorAuth: true,
},
lifecycle: {
redirectAfterLogin: "/app",
redirectAfterSignOut: "/",
redirectWhenSessionExpired: "/auth/login",
sessionTtlSeconds: 60 * 60 * 24 * 30,
},
}Role and Admin Enforcement
We use a lightweight middleware-based permission control scheme:
User Auth (src/backend/api/middleware/auth.ts): Intercepts unauthenticated requests and returns 401. Validates session integrity.
Admin Auth (src/backend/api/middleware/admin.ts): Checks if user role is admin in addition to login. Protects admin routes.
Middleware Chain
Admin routes use adminMiddleware which first validates session, then checks session.user.role === "admin". Non-admin users receive 403 Forbidden.
| Middleware | Applied To | Behavior |
|---|---|---|
authMiddleware | /api/aichat, /api/api-keys, /api/upload, etc. | Requires valid session; returns 401 if missing |
adminMiddleware | /api/admin/*, /api/openapi, /api/docs | Requires session + admin role; returns 403 if not admin |
Extension Points
- Add Social Login: Configure new Providers in
src/backend/auth/auth.tsand add corresponding Keys to environment variables. - Custom Auth Logic: Extend complex permission requirements (e.g. organization-based) by writing custom middleware or Better Auth plugins.
- I18n: Authentication-related text is configurable; sync
src/i18n/translations/*/auth.jsonfor multi-language support.