Skip to content

Password reset

  1. Login page, "Forgot password?".
  2. Enter email and submit.
  3. z4j always responds "check your email" regardless of whether the email exists (prevents enumeration).
  4. If the email exists, a one-shot reset link is sent. The reset token TTL is 30 minutes.
  5. User clicks the link, fills in a new password, which must satisfy the password policy.
  6. On save, all existing sessions for that user are invalidated.

Password reset emails go through the project's email notification channel (the same channel used for invitations). Without an active email channel on at least one of the user's projects, the reset link cannot be sent and the user must reset via the CLI path below.

Both POST /auth/password-reset/request and POST /auth/password-reset/confirm share a single per-IP bucket: 10 hits per minute combined. Tighter than the login cap because a legitimate user only needs one or two hits (one to request, one to confirm); higher rates indicate enumeration or token brute-force attempts.

For lost admin accounts or stretches without email delivery, change the password directly from the brain container:

Terminal window
# Prompt for the password on stdin (recommended; never echoed):
z4j changepassword [email protected] --password-stdin

Or pass it inline (not recommended, ends up in shell history):

Terminal window
z4j changepassword [email protected] --password 'new-password'

Requires direct brain-container access.

Recover access to the brain CLI or restore the installation from a verified backup. Updating only users.password_hash with direct SQL is not a supported recovery procedure: it does not clear locked_until, reset the failed-login counter, revoke existing sessions and trusted devices, or remove an enrolled MFA requirement. It can therefore leave the account locked or still dependent on the lost second factor while bypassing the normal audit path.

z4j changepassword clears the account lockout and revokes sessions and trusted devices in the same transaction. If the authenticator and recovery codes are also lost, run z4j reset-mfa as a separate, audited break-glass step. If neither CLI access nor a verified backup can be recovered, stop the brain, preserve the database and external evidence, and obtain schema-specific incident assistance rather than applying a password-hash-only update.

  • Reset requested writes an audit entry with the email and IP (not the token).
  • Reset completed writes an audit entry with the user_id.
  • CLI changepassword writes an audit entry attributed to the operator.