Risk-based Authentication using Auth0 Actions and "have i been pwned" APIs


9 min read

Risk-based Authentication using Auth0 Actions and "have i been pwned" APIs

In this article, we look at how to improve the security of a system by implementing Risk-based Authentication. To achieve this we will integrate have i been pwned APIs into our login flow using Auth0 Actions.

What is Risk-based Authentication?

To put it simply, Risk-based Authentication or RBA uses real-time intelligence about a user to decide if their activity is normal (low-risk) or suspicious (high-risk).

RBA estimates a risk score based on login behaviour. The calculation of risk score typically happens for any given access attempt in real-time, based on a predefined set of rules. Users are then presented with authentication options appropriate to that risk level.

Many factors are considered when assessing the risk of login activity. For example:

  • Location of the user
  • Device/browser
  • IP and network information
  • Number of attempts to log in

Or factors related to a user and their context. For example, a login attempt to the company's HR system at 2 am can be considered suspicious (high risk).

And many more factors that might make sense in a particular context. d1.png

Most Authentication providers support RBA.

Here are links to few examples, Auth0, Okta, Azure AD, AWS Cognito and Google support RBA.

Using RBA you do not need to always enforce MFA and can only ask for additional authentication if it's required based on the risk score. This helps to improve the user experience of the login flow and make it easier for low-risk logins to happen with less friction.

Built-in Auth0 features for Risk-based Authentication

Luckily, Auth0 has some features to support you here

  • Adaptive MFA - this feature triggers MFA and asks the user to complete an MFA Challenge when the confidence is low (activity is high-risk).

Auth0 also provides a range of Attack Protection features which goes hand in hand with the RBA.

  • Breached Password Detection - Auth0 tracks large security breaches that are happening on major third-party sites. If a user password is leaked in a data breach, they will be notified and also they might get blocked from logging in.

  • Bot Detection - Bot detection mitigates scripted attacks by detecting when a request is likely to be coming from a bot and presenting a Captcha challenge that blocks the Bot attack.

These features support most of the typical scenarios for Risk-based Authentication and you can further customise them to best match your usage.

What is have i been pwned and how can it help?

Created by security expert Troy Hunt, have i been pwned is a website that allows Internet users to check whether their data has been compromised by data breaches.

As a user, you can go to this website, enter your email and get a list of data breaches that your email address has been involved in.

Screen Shot 2022-01-23 at 11.09.49 pm.png

have i been pwned also offers REST APIs that you can use to make the same queries through code.

For example, this is the response for an API that returns the list of data breaches for an email address.




        "Name": "XYZ",
        "Title": "XYZ",
        "Domain": "xyz.com",
        "BreachDate": "2020-03-22",
        "AddedDate": "2020-11-15T00:59:50Z",
        "ModifiedDate": "2020-11-15T01:07:10Z",
        "Description": "In March 2020, the stock photo site .....",
        "LogoPath": ".../Images/PwnedLogos/xyz.png",
        "DataClasses": [
            "Email addresses",
            "IP addresses",
            "Phone numbers",
            "Physical addresses",
        "IsVerified": true,
        "IsFabricated": false,
        "IsSensitive": false,
        "IsRetired": false,
        "IsSpamList": false,
        "IsMalware": false

I think you can guess where I am going with all this by now. I want to use have i been pwned REST APIs as part of my login flow to detect if a username (email) has been listed in a data breach and react appropriately based on the risk factor.

For example, if the user (email address) is listed in a recent data breach, I will send the user a change (reset) password email and ask them to complete an MFA challenge. I will further describe the login flow in the rest of this article.

To use the APIs you will need to purchase an API key. Please read these instructions to get your HIBP API key.

Use Auth0 Actions to extend the Risk-based Authentication

As mentioned Auth0 built-in features already provide a solid ground for Risk-based Authentication but based on your business requirement you might need to consider more factors as part of your risk assessment.

This is where Auth0 Actions shine and let you extend the capabilities of Auth0 beyond what is defined.

have i been pwned provides data for data breaches and also Pastes and usually has the data before other sources. So it can be a good accompanying source to secure your system.

However, using the have i been pwned REST APIs is just an example to demonstrate how you can use other data sources to enhance your risk assessment. So please do your research before adopting this data source.

What are Auth0 Actions?

Auth0 Actions are secure, tenant-specific, versioned functions written in Node.js that execute at certain points during the Auth0 runtime. Actions are used to customize and extend Auth0’s capabilities with custom logic. auth0.com/docs/customize/actions

So the idea for this integration is to use a Login Action and write a Node.js function to:

  • Call have i been pwned REST APIs to figure out if the email address (username) is listed in a data breach.
  • have i been pwned response will give me a list of data breaches for a given email address.
  • I will pick the most recent breach.
  • Then I check to see if the user has changed their password after the most recent data breach.
  • If so user can login without extra authentication.
  • If Not, the user needs to complete an MFA challenge and they receive an email to change(reset) their password.

This flow chart shows how the new login flow looks like this.


Note: Users signing in with social or enterprise connections must reset their passwords with the identity provider (such as Google or Facebook).

In the case of social users, you might want to limit their access to sensitive data in the system or warn them about the breach. So they can take any required actions. (not in the scope of this example)

Examples of other things you can do are:

  • Completely block user access if you are dealing with a high-risk activity. For example, if the leaked account belongs to a company's Finance department staff that can do high valued monetary transactions. In this case, you might take more drastic measures involving in-person account recovery or using KYC services like Onfido to make sure of the user identity.

For sake of this blog, we will stick with a simpler REST API integration example.

Create your first Action

To start you need an Auth0 account. If you don’t already have one, follow these instructions to set up one.

After you log in to your Auth0 account click on the Actions > Flows > Login to create the login Action.

Screen Shot 2022-01-15 at 10.34.41 am 1.png This creates a post-login trigger that runs as part of the Login flow. It is executed after a user logs in and when a Refresh Token is requested.


Click on the + button in Add Action and select Build Custom. Call it have I been pwned and leave the rest as is.

Screen Shot 2022-01-20 at 7.58.59 am.png

After Creation, you come to the edit screen. Here you can write the code for your Action, test it and deploy it.

Next, we write the logic to call have i been pwned APIs to check if the user email address has been involved in a data breach.

Screen Shot 2022-01-20 at 8.11.10 am.png

We will use the onExecutePostLogin function which is a handler that will be called during the execution of a PostLogin flow.

onExecutePostLogin function recieves two parameters, api (of type PostLoginApi) and event (of type Event)

For this example, we will use the event.user to find the user's email address. event.user contains information on the user on whose behalf the current transaction was initiated, like email, identities and more.

We also use the event.client to get the client id. Knowing the client id we can send a reset password email to the user.

You can read more on the full capabilities of the api and event in the Auth0 documentation.

We will use two APIs from have i been pwned:

  • Get the list of data breaches for an email address. This will return an array of breach names that are sorted by date already. So the first item on the list is the most recent breach.
  • Get the details of a particular breach. We will use the name of the first breach from the previous list to get the details of it. This includes the BreachDate.

You can read about the capabilities of have i been pwned APIs here

Code for Login Action

Test your action

On the left side of the Actions editor, you have 3 more options. The one that looks like a play button is Test. If you click on it give you an example login payload and once you hit run it will simulate a call to the action with the same body that you would get on a Login / Post Login flow.

You can edit the payload as you like. For example, I changed the email address to account-exists@hibp-integration-tests.com.

This is a test email address provided in have i been pwned API documentation for the scenario that the user has data breaches.

After you run the action you can see the results in the bottom right panel.

Here is an example from my test.

Screen Shot 2022-01-23 at 11.46.26 pm.png

You can use console.log to see the result of each step in your function call.

Actions editor saves your code automatically and once you are happy you can click the deploy button.

Now when a user tries to log in they will go through our login Action and need to successfully get through our enhanced Risk-based Authentication before they can successfully log in.

Other features of Actions

Actions have more to offer. You get a secret manager, a package manager (for npm packages) and the version history of the code built-in.

This makes up for a better developer experience.

Screen Shot 2022-01-23 at 11.14.11 pm.png

Actions limitations

Actions give you an excellent way to customise and extend Auth0 capabilities but there are some limitations. For example, each execution of a flow must complete in 10 seconds or less or the processing will end in an error.

Some of these limitations are in place to ensure that the user experience stays smooth as you add more code and capabilities.

Make sure to check these limitations before you start.


Auth0 Actions provide an easy way for development teams to implement authentication and authorisation based on their unique needs and open the door to many possibilities.

We only scratched the surface with this Login Action example. Actions offer more hooks and there are plenty of examples for each. The same goes for our risk calculation function. For example, we can make use of the type of breach (e.g: email, password, ...) and more data that is available in have i been pwned response to have a more meaningful risk calculation.

If this looks like something you have been looking for, I encourage you to read the Actions documentation to learn more about the capabilities of different Actions and find more examples.

Thanks for reading this article. Please reach out here or on Twitter if you have any feedback or questions.


Did you find this article valuable?

Support Parham by becoming a sponsor. Any amount is appreciated!