Authentication
The admin shell authenticates with a single bearer token. A successful login mints a short-lived in-memory session, carried by an HttpOnly cookie. The token can be rotated from within the UI, and a startup warning nudges you away from weak secrets.
Bearer token
Sign in at GET /_admin/login, which renders an empty login card where you enter the admin token. The submitted token is compared in constant time against the configured value. A failed token re-renders the form with the inline error Token does not match. Try again. and consumes a rate-limit permit.
Failed attempts are rate-limited to 10 per minute, counted together across the login form and POST /_admin/reload, so brute-forcing across both surfaces is bounded. Once the limit is spent, a failed attempt gets 429 with the same error shape. A request with the correct token is never throttled, so an attacker spending the allowance cannot lock you out. In development, where POST /_admin/reload checks no token, every reload request counts against the limit.
Session cookie
On a successful login the server mints a 32-byte random session ID, stores it in an in-memory session store, and returns it as the accentcms_admin cookie. The cookie is:
HttpOnlySameSite=Lax- scoped to
Path=/_admin/ Securein production mode only (--production); theSecureattribute is omitted in dev mode so the cookie works over plain HTTP on localhost- valid for 8 hours (the session TTL)
Sessions live in memory only and do not persist across server restarts. A background sweep task prunes expired sessions every 60 seconds.
GET /_admin and GET /_admin/ redirect an authenticated session to /_admin/dashboard, and otherwise to /_admin/login. POST /_admin/logout clears the session cookie, drops the in-process session, and redirects to /_admin/login.
Token rotation
Open Settings → Rotate token (POST /_admin/settings/rotate-token). On confirm the server:
- mints a fresh 32-byte token (written as hex),
- writes it to a
.env.adminfile next toconfig.yaml, - clears every active session, and
- redirects you back to the login screen.
Persisting in .env.admin rather than rewriting config.yaml keeps the secret out of any file you might commit to source control. The rotation timestamp is logged in ISO 8601 form, and the Settings screen surfaces the last rotation time.
Minimum token length
There is no hard length enforcement at config-parse time, but a startup warning is logged when the token is shorter than 16 characters in production. The recommended minimum is 32 bytes of entropy.