Recommended Policies
When the Password Protect API detects a breached password, your application needs to decide what to do. LeakJar supports four policy outcomes—each suited to different risk profiles and user experience requirements.
Block
Reject the password outright. The user must choose a different password before proceeding. This is the strictest policy and the best default for signup and password-reset flows.
When to use
- New user registration
- Password reset / change flows
- High-security applications (finance, healthcare)
const result = await checkPassword(password);
if (result.breached) {
return {
success: false,
error: "This password has appeared in a data breach. "
+ "Please choose a different password.",
};
}Step-up (MFA)
Allow the password but immediately require multi-factor authentication. This balances security with user experience—the user isn't blocked, but they prove their identity through a second factor.
When to use
- Login flows where you want to avoid blocking returning users
- Applications with existing MFA infrastructure
- Moderate-risk scenarios
const result = await checkPassword(password);
if (result.breached) {
// Allow login but flag the session for MFA challenge
session.requireMfa = true;
session.mfaReason = "breached_password";
return {
success: true,
mfaRequired: true,
message: "Additional verification required.",
};
}Force Reset
Allow the current action (e.g. login) to succeed, but require the user to choose a new password before their next session. This avoids disrupting the current flow while ensuring the breached password is replaced.
When to use
- Background monitoring of existing passwords
- Gradual credential hygiene enforcement
- Applications that prioritize user retention
const result = await checkPassword(password);
if (result.breached) {
// Mark user for forced password reset
await db.user.update({
where: { id: user.id },
data: {
mustResetPassword: true,
resetReason: "breached_password",
resetDeadline: new Date(Date.now() + 7 * 86400000),
},
});
return {
success: true,
passwordResetRequired: true,
};
}Notify
Log the event and alert your security team without impacting the user. Useful for monitoring and analytics before enforcing stricter policies, or in low-risk environments where awareness is sufficient.
When to use
- Phased rollout of breach detection
- Low-risk internal applications
- Analytics and reporting dashboards
const result = await checkPassword(password);
if (result.breached) {
// Log for security analytics
await analytics.track("breached_password_detected", {
userId: user.id,
exposureCount: result.count,
flow: "login",
timestamp: new Date().toISOString(),
});
// Optionally notify the security team
await alerts.send({
channel: "security",
message: `Breached password used (seen ${result.count}x)`,
severity: "warning",
});
}Decision matrix
Use this matrix to choose the right policy based on the flow context and breach severity:
| Risk level | Signup / Reset | Login | Background scan |
|---|---|---|---|
| High (>100 exposures) | Block | Step-up MFA | Force Reset |
| Medium (10–100) | Block | Step-up MFA | Notify |
| Low (1–9) | Block | Notify | Notify |
| None (0) | Allow | Allow | No action |
These are recommendations. Adjust thresholds based on your application's security posture and compliance requirements.