Admin account security
Since v1.25 the admin has two-factor sign-in, a device list and an audit log built in, no plugin needed (WordPress needs Wordfence, WP 2FA, Simple History and the like).
Two-factor sign-in (2FA)
Every admin account turns it on under the top-right menu → Account security
(/admin/account):
- "Turn on two-factor sign-in", scan the QR code with an authenticator app (Google Authenticator, Microsoft Authenticator, 1Password, Authy, ...);
- confirm with the 6-digit code the app shows;
- save the 10 recovery codes (shown once). Without the phone, each one signs in once instead of a code.
From then on, signing in asks for a code (or a recovery code) after the password. A code works once; codes and recovery codes are rate limited.
- Turning it off or creating new recovery codes asks for the current password (turning off also for a code or a recovery code).
- Admins can "Reset two-factor sign-in" for a user who lost their phone in Users (which also signs that user out everywhere); the user sets it up again.
- The secret is stored encrypted (AES-GCM, key derived from
NUXT_JWT_SECRET), so a database dump alone does not reveal it. ChangingNUXT_JWT_SECRETinvalidates existing 2FA setups: users sign in with a recovery code, or an admin resets them. - If the only admin loses both phone and recovery codes, delete that user's row in the
cms_user_securitytable. - Accounts with 2FA that use
POST /api/auth/tokenfor API tokens send acode(authenticator or recovery code) too. - On the demo site (
NUXT_PUBLIC_DEMO_MODE) the shared demo account's security settings are locked.
A site's own login page reaches the second step (/admin/verify) by itself as long as it calls
useAuth().login() (every official template does; nuxtcms doctor checks it).
Signed-in devices
The Account security page lists where the account is signed in: browser and system, IP address, country (on Cloudflare), sign-in time and last activity.
- Sign out one device, or all other devices (sign-ins from before the upgrade included);
- a password change signs the other devices out and keeps this one;
- admins can sign a user out everywhere from the Users list.
Changing the password
Everyone (editors too) changes their own password on the Account security page with the current password; the new one needs at least 8 characters.
Audit log
Admin → Audit log (/admin/audit, admins only) records:
- sign-ins, failed sign-ins (with the e-mail typed), sign-outs, API tokens;
- 2FA on / off / wrong code, recovery code used, new recovery codes, password changes, devices signed out;
- every admin change (all
POST /api/admin/**, plugin admin APIs included): who, which resource, which id, which fields. Only field names and short labels (title, slug, e-mail...) are kept, never content or the values of secret fields (their names carry a*).
Filter by action, user / item / IP and dates, and export CSV (up to 10,000 rows, formula-safe).
Entries are kept for 180 days and pruned by the cron (/api/cron/dispatch), which also removes
sign-ins that ended 30 days ago.
Upgrading
New tables user_security, user_sessions, audit_logs, redirects and not_found_log
(migration 0017, applied by upgrade.mjs / nuxtcms fleet upgrade). Sessions from before the
upgrade stay signed in but are not listed as devices.