Logical Architecture
The architecture of @frame/auth builds on Better Auth’s native flexibility to compose the identity layer through plugins and strict configuration.
Export and Consumption Flow
Section titled “Export and Consumption Flow”graph LR
A(Central Auth Configuration) --> B(Server Instance)
A --> C(React Client)
B --> D[NestJS Validation]
B --> E[Next.js Auth API]
C --> F[Next.js useSession Hooks]
Plugin Architecture
Section titled “Plugin Architecture”Better Auth is modular by design. In FRAME, we inject functionality through official and custom plugins:
- Internationalization Support: Full integration of
@better-auth/i18nso emails, error messages, and authentication flows respect the user’s language (essential for a locale-aware ecosystem). - Organization Access Control: Better Auth organization clients and the server instance share the access-control definition and standard roles exported from
src/permissions.ts.
Configuration and Creation
Section titled “Configuration and Creation”To make a new OAuth provider (for example, Google or GitHub) or sign-in flow available everywhere:
- Define the Plugin/Provider: In the central configuration file, inject the extension into the
pluginslist or define the secret keys forsocialProviders. - Update the Drizzle Adapter: If the provider requires new columns, update
@frame/modelsfirst, then map the field in Auth’s database configuration. - Export the Client: Ensure the client (
createAuthClient) regenerates correctly, deriving its full typing from your new configuration so TypeScript picks it up inapps/next.
Organization Authorization
Section titled “Organization Authorization”src/permissions.ts is the canonical organization permission vocabulary. It defines product resources, standard roles, typed permission constants, and the conversion used by Better Auth’s hasPermission API.
| Role | Organization management | Product data |
|---|---|---|
owner | Full organization, member, and invitation control | Cats and owners: CRUD |
admin | Organization update, member, and invitation control | Cats and owners: CRUD |
member | No management permissions | Cats and owners: read |
The global user role and organization membership role are separate. A global administrator can enter the platform /admin area, but organization data still requires membership and an organization permission.
Adding a protected resource
Section titled “Adding a protected resource”- Add the resource actions to
organizationAccessControland assign them to the standard roles. - Add reusable entries to
ORGANIZATION_PERMISSIONSinstead of constructing permission objects at call sites. - Configure both the Better Auth server organization plugin and client organization plugin with the shared access control and roles.
- Enforce the permission in NestJS and scope persistence by
organizationId. - Use the shared permission in Next.js only to control action visibility; never treat hidden UI as authorization enforcement.
- Add role-matrix and denied-access tests.
The rationale and complete enforcement boundary are recorded in ADR 0003.