Authentication
Kenresoft CMS uses Better Auth for authentication, mounted at /api/v1/auth/*. There is one identity system: CMS staff, website visitors and Commerce customers are all rows in the same user, account and session tables.
Core user (Better Auth: user, account, session, verification) ├── role: owner | admin | editor | author | viewer → CMS access ├── role: none (default) → website / application account └── plugin profile (optional), e.g. Commerce customer profileRoles and access
Section titled “Roles and access”- New accounts default to role
none. Anoneaccount cannot reach the admin API, on any route. - A CMS role is only ever assigned by trusted server-side code: the Owner bootstrap, Add user, and the role and ownership routes. Sign-up and profile updates cannot set it.
- A disabled account is treated as signed out everywhere, and its sessions are revoked.
- Role capabilities are in Users & Roles.
A normal website or application account therefore never receives CMS administrative access, however it registers.
Sessions
Section titled “Sessions”Authentication is cookie-session based. There is no JWT or bearer-token mode configured for API clients. The session cookie is set by the API with SameSite=None and Secure always on, because the admin and API are on different origins by default. Consequences:
- Browsers that block third-party cookies drop it. A website with accounts should use the same-origin proxy, which makes the cookie first-party to the website.
- Any origin that sends credentialed requests must be listed in
CORS_ORIGINS.
Email verification
Section titled “Email verification”Every email/password account must verify its email address before it can sign in. Signing in with an unverified address fails with EMAIL_NOT_VERIFIED and a fresh link is sent. The one exception is the bootstrap Owner. If email is not configured, verification links are written to the Worker logs.
For staff accounts the link opens the admin’s /verify-email page. For a website account the link is Better Auth’s verification URL, which redirects to the callbackUrl your site passed at sign-up (an origin in CORS_ORIGINS).
Password reset and change
Section titled “Password reset and change”POST /api/v1/public/password-reset/requestalways returns the same generic message, whether or not an account exists. The token is random, single-use, expires after one hour and is stored only as a hash.redirectUrlis honored only for website accounts and only for an origin inCORS_ORIGINS.POST /api/v1/public/password-reset/confirmsets the new password.POST /api/v1/auth/change-passwordneeds a session, and signs out other devices by default.
Two-factor authentication
Section titled “Two-factor authentication”TOTP with backup codes, enabled per account (on the admin Profile page, or through cms.auth.twoFactor on a website). There is no SMS or email one-time-code method. A sign-in for a two-factor account returns twoFactorRequired and creates no session until the code is verified.
Recovery
Section titled “Recovery”Account recovery has three layers, from least to most privileged. See Account and owner recovery.
Endpoints
Section titled “Endpoints”Auth endpoints are listed in Astro authentication and the API routes reference.