Token auth
The token strategy of @worker-manager/auth protects the dashboard with one or more static
tokens, with no usernames and no identity provider. Scripts send the token in a header; a browser
types it once into a small login form and gets an encrypted session cookie. It suits internal
boards where a Keycloak realm is overkill and a shared Basic password is not wanted in the
browser's credential cache.
Options
Use long random tokens (32 characters or more): there is no lockout, so the token's entropy is the
only defence against guessing. openssl rand -base64 32 is plenty.
NestJS
Express
Fastify
The plugin registers the POST /auth/login route the form needs inside the board's own scope.
CLI and Docker
--token takes a comma separated list. The environment variables are WORKER_MANAGER_TOKENS,
WORKER_MANAGER_TOKEN_HEADER and WORKER_MANAGER_SESSION_SECRET, and a config file takes
token: { tokens, header, user, cookie }. Without a session secret the CLI encrypts sessions with
a random per-process key, so they end on restart.
What happens to a request
The middleware also serves, under the board's base path, when cookie is set:
GET /auth/loginrenders the form: one password field, no scripts, no external assets, a strictContent-Security-PolicyandX-Frame-Options: DENY.POST /auth/loginchecks the token and, on success, sets the session cookie and answers303toreturnTo(same-origin paths only). A wrong token re-renders the form with401; the token is never echoed back.GET /auth/logoutclears the cookie and returns to the form.GET /auth/mereturns{ strategy: 'token', user, logoutUrl }, as for the other strategies.
Security notes
- The session cookie (
wm_sessionby default,wm_session_<name>for a named NestJS board) isHttpOnly,SameSite=Strict, scoped to the base path,Secureon https, and sealed with AES-256-GCM undercookie.secret. It carries the token and an expiry; nothing in it is readable client side, and a tampered or foreign cookie is cleared. - CSRF on the login form: the
POSTis only accepted whenOrigin(or, without it,Referer) is the board's own origin, and aSec-Fetch-Siteother thansame-originis refused, so another site cannot log a browser into a session of its choosing. Together withSameSite=Strict, no cross-site request carries the session either. - Links from other sites: a
SameSite=Strictcookie is withheld from a navigation that starts on another site, such as a link in chat. Such a page load gets a tiny page that reloads itself from the board's origin, which does carry the cookie, so a signed-in user is not asked again. - No secrets in logs: the middleware logs nothing, and neither tokens nor the session secret appear in any response.
Rate-limit POST ${basePath}/auth/login at your proxy if the board is reachable from the internet.