Skip to content

Security

Authentication_

Learn how Appwrite protects your passwords and helps users pick better passwords.

1 min read

Raw

Appwrite helps you implement secure authentication in your applications by using password hashing to protect passwords in storage. Appwrite also provides tools to help users pick better passwords, making them harder to break.

Persistence

Appwrite handles the persistence of the session in a consistent way across SDKs. After authenticating with an SDK, the SDK will persist the session so that the user will not need to log in again the next time they open the app. The mechanism for persistence depends on the SDK.

Framework Storage method
Javascript logoWebUses a secure session cookie and falls back to local storage when a session cookie is not available.
Javascript logoFlutterUses a session cookie stored in Application Documents through the path_provider package.
Javascript logoAppleUses a session cookie stored in UserDefaults.
Javascript logoAndroidUses a session cookie stored in SharedPreferences.

Session limits

In Appwrite versions 1.2 and above, you can limit the number of active sessions created per user to prevent the accumulation of unused but active sessions. New sessions created by the same user past the session limit delete the oldest session.

You can change the session limit under Auth > Policies > Sessions > Sessions limit in the Appwrite Console. The default session limit is 10 with a maximum configurable limit of 100.

Permissions

Security is very important to protect users' data and privacy. Appwrite uses a permissions model coupled with user sessions to ensure users need correct permissions to access resources. With all Appwrite services, including databases and storage, access is granted at the table, bucket, row, or file level. These permissions are enforced for client SDKs and server SDKs when using JWT, but are ignored when using a server SDK with an API key.

Password strength

Password strength lets you set the minimum requirements a password must meet when a user creates an account or changes their password. Enforcing these rules makes passwords harder to guess and brute-force.

You can configure two kinds of requirements:

  • Minimum length: the smallest number of characters a password is allowed to have.
  • Character requirements: require any combination of an uppercase letter, a lowercase letter, a number, and a special character. Each requirement is an independent toggle, so you can enforce as few or as many as your app needs.

Passwords that don't meet the configured requirements are rejected when a user signs up and whenever they change their password. To configure password strength, navigate to Auth > Policies > Passwords > Strength, set the minimum length and character requirements, then click Update.

Password history

Password history prevents users from reusing recent passwords. This protects user accounts from security risks by enforcing a new password every time it's changed.

Password history can be enabled under Auth > Policies > Passwords > History in the Appwrite Console. You can choose how many previous passwords to remember, up to a maximum of 20, and block users from reusing them.

Password dictionary

Password dictionary protects users from using bad passwords. It compares the user's password to the 10,000 most common passwords and throws an error if there's a match. Together with rate limits, password dictionary will significantly reduce the chance of a malicious actor guessing user passwords.

Password dictionary can be enabled under Auth > Policies > Passwords > Dictionary in the Appwrite Console.

Breached passwords

Breached password detection checks user passwords against Have I Been Pwned, a public corpus of passwords exposed in known data breaches. A leaked password is a target for credential stuffing even when it passes every strength and dictionary rule, so checking it against real breach data catches passwords that other checks miss.

The check uses k-anonymity. Appwrite hashes the password with SHA-1 and sends only the first five characters of the hash to the service. The service returns every known hash suffix for that prefix, and Appwrite compares them on its own servers, so neither the password nor its full hash is shared.

How the check works

On Appwrite Cloud, breached password detection is turned on by default for every project and only records a result. Whenever a user signs up, signs in with email and password, changes their password, or completes a password recovery, Appwrite checks the password and stores the outcome on the user as passwordPwned:

ValueMeaning
trueThe password was found in a known data breach the last time it was checked.
falseThe password was not found in any known data breach.
nullThe password has never been checked, for example because the user signs in with OAuth or the check is turned off.

Sign-ins are checked too, so the flag stays current. If a user's password shows up in a new breach, it is flagged the next time they sign in with it.

On top of recording, you can turn on two enforcement options:

  • Reject breached passwords. A breached password can't be set when a user signs up, changes their password, or completes a password recovery. Users created or updated through the server-side Users API are checked too. The request fails with the password_pwned error.
  • Block sign-in with a breached password. An email and password sign-in with a breached password is refused with the user_password_reset_required error until the user resets their password through password recovery.

If the breach service can't be reached, Appwrite does not treat the password as safe. The request fails with the general_pwned_passwords_unavailable error and can be retried.

Configure breached password detection

  1. Open your project in the Appwrite Console.
  2. Navigate to Auth in the sidebar.
  3. Open the Policies tab and select Passwords.
  4. In the Breached passwords card, turn on Check passwords against known data breaches.
  5. Optionally, check Reject breached passwords and Block sign-in with a breached password.
  6. Click Update.

Breached passwords card in the Appwrite Console
Breached passwords card in the Appwrite Console

The enforcement options only apply while the check is turned on. The users table shows the latest result for each user as a shield icon. A red shield means the password was found in a breach, a green one means it wasn't, and a dash means it has never been checked. A user's page shows a breached password badge when their password has leaked.

Users table in the Appwrite Console with breached password results
Users table in the Appwrite Console with breached password results

Handle breached password errors

When enforcement is on, catch the two error types in your sign-up and sign-in flows. On password_pwned, ask the user to choose a different password. On user_password_reset_required, send the user a password recovery email so they can set a new password.

Find users with breached passwords

The passwordPwned attribute can be queried through the server-side Users API. List the users whose password was found in a breach to notify them or ask them to change it, even before you turn on enforcement.

Password hashing

Appwrite protects passwords by using the Argon2 password-hashing algorithm.

Argon 2 is a resilient and secure password hashing algorithm that is also the winner of the Password Hashing Competition.

Appwrite combines Argon 2 with the use of techniques such as salting, adjustable work factors, and memory hardness to securely handle passwords.

If an user is imported into Appwrite with hash differnt than Argon2, the password will be re-hashed on first successful user's sign in. This ensures all passwords are stored as securely as possible.

Personal data

Encourage passwords that are hard to guess by disallowing users to pick passwords that contain personal data. Personal data includes the user's name, email, and phone number.

Disallowing personal data can be enabled under Auth > Policies > Passwords > Personal data in the Appwrite Console.

Email policies

Email policies let you restrict which email addresses can sign up for your project. You can independently block free email providers, aliased addresses, and disposable email services to keep throwaway accounts, signup spam, and bot registrations out of your user base. Policies run at sign-up and on email updates, and existing users can still sign in even if their address would not pass the current policy.

Email policies can be enabled under Auth > Policies > Emails in the Appwrite Console, or programmatically through the Project service. Learn more in the Email policies docs.

Session alerts

Enable email alerts for your users so that whenever a new session is created for their account, they will be alerted with details about the sign-in. This helps users quickly spot unauthorized access and take action to secure their account.

When alerts are not sent

Session alerts are intentionally skipped in a few situations to avoid redundant or confusing emails:

  • First session after sign-up: the very first sign-in a user makes after creating their account does not trigger an alert. A brand-new account doesn't yet hold anything worthy of protection, so alerting at this stage adds no real security value. It also prevents a double-email situation in flows where your project may already be sending a welcome or verification email.
  • Magic URL, Email OTP, and OAuth2 sign-ins: these authentication methods already verify the user's access to the sign-in channel (their inbox or identity provider), so no additional alert is needed.
  • No email address on file: users who have not set an email address on their account will not receive alerts.

To toggle session alerts, navigate to Auth > Policies > Sessions > Session alerts.

Memberships privacy

In certain use cases, your app may not need to share members' personal information with others. You can safeguard privacy by marking specific membership details as private. To configure this setting, navigate to Auth > Policies > Memberships > Privacy.

These details can be made private:

  • userName - The member's name
  • userEmail - The member's email address
  • mfa - Whether the member has enabled multi-factor authentication

Mock phone numbers

Creating and using mock phone numbers allows users to test SMS authentication without needing an actual phone number. This can be useful for testing edge cases where a user doesn't have a phone number but needs to sign in to your application using SMS.

To create a mock phone number, navigate to Auth > Settings > Mock phone numbers. After defining a mock phone number, you need to define a specific OTP code that will be used for SMS sign-in instead of the SMS secret code sent to a real phone number.

Was this page helpful?

Share what worked or what we should fix. Once approved, our agents automatically apply suggested updates to the docs.