---
layout: integration
title: Breached password detection with Have I Been Pwned
description: Flag, reject, or block passwords that appear in known data breaches
date: 2026-11-06
featured: false
isPartner: true
isNew: true
cover: /images/integrations/breached-passwords-hibp/cover.avif
category: auth
product:
    vendor: Have I Been Pwned
    description: "Have I Been Pwned is a data breach search service run by security researcher Troy Hunt, with a Pwned Passwords corpus of passwords exposed in breaches."
platform:
    - 'Self-hosted'
    - 'Cloud'
---

[Have I Been Pwned](https://haveibeenpwned.com/Passwords) is a data breach search service run by security researcher Troy Hunt. Its Pwned Passwords corpus collects passwords exposed in real data breaches, and its range API lets services check a password against it without sending the password.

# How does the integration work?

Breached password detection is a password policy in Appwrite Auth that checks your users' passwords against Have I Been Pwned. Appwrite runs the check when a user signs up, signs in with email and password, changes their password, or completes a password recovery, and stores the result on the user as `passwordPwned`.

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

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

- **Reject breached passwords.** A breached password can't be set at sign-up, password change, or password recovery, including through the server-side Users API. 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 fails with the `user_password_reset_required` error until the user resets their password.

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

**Defaults on Cloud and self-hosted**

On Appwrite Cloud, checking and recording are on by default for every project, and both enforcement options are off. Self-hosted Appwrite 2.3 and later needs the `_APP_PWNED_PASSWORDS_DSN` environment variable set before any password is actually checked.

# How to implement

To implement breached password detection in Appwrite Auth, there are several steps you must complete:

## Step 1: Connect your self-hosted instance to Have I Been Pwned

Skip this step on Appwrite Cloud. If you [self-host Appwrite](/docs/advanced/self-hosting), the default value of `_APP_PWNED_PASSWORDS_DSN`, `none://localhost`, reports every password as safe. Point it at the public Pwned Passwords range API in the `.env` file of your Appwrite installation:

```bash
_APP_PWNED_PASSWORDS_DSN=hibp://localhost
```

Then recreate your Appwrite stack and confirm the variable was applied:

```bash
docker compose up -d
docker compose exec appwrite vars
```

## Step 2: Configure the breached passwords policy

For this step, you must [create an account on Appwrite Cloud](/sign-up) or have a self-hosted instance configured as in the previous step.

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**.

The users table then 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.

## Step 3: Handle breached password errors in your app

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](/docs/products/auth/email-password#password-recovery) email so they can set a new password.

```js
import { Client, Account, ID } from "appwrite";

const client = new Client()
    .setEndpoint('https://<REGION>.cloud.appwrite.io/v1')
    .setProject('<PROJECT_ID>');

const account = new Account(client);

// Sign-up rejected by "Reject breached passwords"
try {
    await account.create({
        userId: ID.unique(),
        email: 'email@example.com',
        password: '<PASSWORD>'
    });
} catch (error) {
    if (error.type === 'password_pwned') {
        // Ask the user to choose a different password
    }
}

// Sign-in refused by "Block sign-in with a breached password"
try {
    await account.createEmailPasswordSession({
        email: 'email@example.com',
        password: '<PASSWORD>'
    });
} catch (error) {
    if (error.type === 'user_password_reset_required') {
        await account.createRecovery({
            email: 'email@example.com',
            url: 'https://example.com/recovery'
        });
    }
}
```

## Step 4: Find users with breached passwords

To notify affected users before you turn on enforcement, query the `passwordPwned` attribute with the server-side Users API:

```js
import { Client, Users, Query } from 'node-appwrite';

const client = new Client()
    .setEndpoint('https://<REGION>.cloud.appwrite.io/v1')
    .setProject('<PROJECT_ID>')
    .setKey('<YOUR_API_KEY>');

const users = new Users(client);

const result = await users.list({
    queries: [Query.equal('passwordPwned', true)]
});
```

In a client app, the `passwordPwned` field on the account returned by `account.get()` tells you whether the signed-in user's password was flagged.

# Read more about Have I Been Pwned and Appwrite Auth

If you would like to learn more about Have I Been Pwned and Appwrite Auth, we have some resources that you should visit:

- [Pwned Passwords on Have I Been Pwned](https://haveibeenpwned.com/Passwords)
- [Breached passwords in Appwrite Auth](/docs/products/auth/security#breached-passwords)
- [Configure breached passwords on self-hosted Appwrite](/docs/advanced/self-hosting/configuration/breached-passwords)
- [Announcing breached password detection for Appwrite Auth](/blog/post/announcing-breached-password-detection)
- [Authentication error types](/docs/apis/response-codes#authentication-errors)
