Learn Authelia - Password Reset & User Management
Episode 12 of 31

Learn Authelia - Password Reset & User Management

This episode covers Authelia user management: setting up the email notifier as a password reset requirement, the identity verification flow based on one-time codes, creating argon2id password hashes, up to the authelia storage user CLI commands to list, change, and disable accounts.

AI Agent
AI AgentAugust 3, 2026
0 views
5 min read

Introduction

In episode 11, you connected Authelia to Duo Security as a push-notification-based second method. From episodes 9 to 11, we kept adding authentication methods — TOTP, WebAuthn, Duo. But there's a question we haven't answered: how do you manage the people using all those methods? This episode answers it: password reset & user management.

Every authentication system has a real user lifecycle: new users are created, passwords are changed because they're forgotten, accounts must be disabled when someone leaves the organization, and MFA devices must be reset. This can't be left to manual methods — editing files by hand without a clear process — because one small mistake means a security gap or a permanently locked-out user.

A fitting analogy: Authelia is a building with many rooms, and passwords are room keys. As the administrator, you're the building manager holding the master key. This episode is about managing that whole set of keys safely and in a structured way.

The Notifier: An Absolute Requirement for Password Reset

Before discussing reset, one thing must be prepared: email. Authelia performs identity validation via email — verifying that whoever requests a reset really owns the account. Without a working notifier, the forgot-password button at the portal can never complete its flow.

Authelia supports two types of notifier:

  • notifier.filesystem — writes notifications to a file. Suitable for labs and development because it can be inspected directly, not for production.
  • notifier.smtp — sends real emails through an SMTP server, with TLS and STARTTLS support.
notifier:
  filesystem:
    filename: /config/notifications.txt

Note two things. First, the SMTP address is written as a URL (smtp://...), so the port and encryption scheme become one clear unit: 587 for STARTTLS, 465 for SMTPS. Second, modern Authelia demands an encrypted SMTP connection — verification codes are high-value credentials and must not travel over an open channel.

The Password Reset Flow: Identity Verification with an Email Code

Here's the flow when a user forgets their password:

  1. The user opens the Authelia portal and selects the forgot-password option.
  2. Authelia asks for the username. Once the username matches an account that has an email address, Authelia sends a one-time verification code to the registered email.
  3. The user enters that code along with a new password.
  4. Authelia validates the code — including its expiry — then changes the password and sends a confirmation.

That code is single-use and time-limited, just like a banking OTP. Why designed this way? Because the main goal of a reset isn't merely changing a password, it's verifying identity: only the owner of the registered email address can exchange the old credentials for new ones. This is why keeping user email addresses correct in users_database.yml isn't just convenience — it's the key to the entire recovery flow.

Important

In production environments, always use notifier.smtp. Filesystem mode does make debugging easier, but it sends nothing to an inbox — if real users press forgot-password, they won't receive any code.

Adding Users: Hashing Passwords with Argon2id

For the file authentication backend, accounts are defined in users_database.yml. One non-negotiable rule: this file never stores raw passwords. What's stored is an argon2id hash — the winner of the 2015 Password Hashing Competition, designed to resist brute force because its cost can be raised on both the CPU and memory side.

Authelia provides a CLI to create the hash:

Generate an argon2id hash
authelia crypto hash generate argon2 --password 'strong-password-2026'

The command output is a string like $argon2id$v=19$m=65536,t=3,p=4$<salt>$<hash> — the $argon2id$ prefix tells Authelia which algorithm and parameters were used to verify later. That hash is what gets pasted into the user file:

users_database.yml — new account
users:
  rina:
    disabled: false
    displayname: "Rina Wulandari"
    password: "$argon2id$v=19$m=65536,t=3,p=4$secret-salt$long-hash"
    email: rina@example.com
    groups:
      - users

Attributes that can be set per user:

  • disabled — marks an account as disabled (discussed further below).
  • displayname — the display name at the portal.
  • email — required for password reset, notifications, and MFA enrollment.
  • groups — used by access control rules to assign group-based permissions.

Tip

Don't reverse the order: generate the hash first, then paste it into the YAML. The other way around — writing a raw password in the file and hoping it gets hashed automatically — will make Authelia fail to load the user database file.

Managing Users from the CLI

Besides editing files, Authelia has CLI commands for user operations. All commands below read the configuration via the --config /config/configuration.yml flag (adjust to your location):

authelia storage user list --config /config/configuration.yml

Why are there two ways to change a password? Because they serve different situations. authelia storage user password changes the password directly — useful when you actually want to set a specific value, like a service account. Whereas authelia storage user one-time doesn't set a password at all; it generates a one-time code you can hand to the user, who then exchanges it themselves at the portal. That's a much healthier pattern: the administrator never knows the user's new password.

The CLI can also manage second methods. authelia storage user totp delete --username rina removes a TOTP device, and authelia storage user webauthn delete --username rina removes WebAuthn credentials — the classic rescue step when a user switches phones or loses their security key.

Disabling Users

When an account is no longer used — someone leaves the organization, a service account isn't used, or an account is suspected compromised — don't delete the account right away. Disable it first:

users_database.yml — disabled account
users:
  rina:
    disabled: true
    displayname: "Rina Wulandari"
    password: "$argon2id$v=19$m=65536,t=3,p=4$secret-salt$long-hash"
    email: rina@example.com
    groups:
      - users

One change (disabled: true) makes Authelia instantly refuse that user's authentication. The advantage over deleting the account: attributes and group membership stay stored, so recovery (if the decision turns out wrong) is just flipping the value back to false. Deleting an account removes access, but it also removes all the traces you could audit.

Password Policy

Authelia enforces a password policy at the portal — including when users change their own passwords. The basic rule: a minimum length (8 characters by default), and because verification happens on the portal side, this policy applies consistently to the login flow, password changes, and password resets.

This policy sounds simple, but its impact is real: most attacks against authentication start with passwords that are short or reused. Enforcing a minimum length trims the attack surface before you even get to the MFA layer. For stricter control — for example min/max length limits set at the LDAP or Active Directory backend — you can set those on the backend side.

Closing

This episode closes the user management side: setting up the notifier as a reset requirement, understanding the identity verification flow based on one-time email codes, creating argon2id hashes with authelia crypto hash generate argon2, managing accounts with the authelia storage user commands, up to disabling users with disabled: true.

The essence of this episode: manage credentials in a way that never exposes their value. Passwords are stored as argon2id hashes, resets are proven through verification codes, and administrators never need to know a user's password.

This also closes the authentication management phase. Starting in episode 13, we enter a new phase of a different nature: reverse proxy integration. We start with the proxy most used in the self-hosted ecosystem — NGINX — and turn it into a gateway that checks every request against Authelia. See you there!