This article contains a sample workflow to notify users when their credentials have appeared in a list of breached credentials. It also serves as a useful reference guide for using event hooks alongside Okta Workflows.
Overview
This template provides a sample workflow to notify users when their credentials have appeared in a list of breached credentials. The Okta System Log records this as a Breached Password event.
The template uses an event hook to trigger an API endpoint and start the flow. Then it composes a notification message and sends it to your user through the Gmail and Slack connectors.
This template also serves as a useful reference guide for using event hooks alongside Okta Workflows. There are several scenarios where you may want to consider using event hooks rather than one of the built-in Okta connectors:
- If an event-hook eligible event is available but not yet built into a connector
- If a use case would benefit from Event Hook Filtering, a feature that isn’t currently available in an Okta connector.
Prerequisites
Before you get started, here are the things you need:
- Access to an Okta tenant with Okta Workflows enabled for your org
- Authorized connectors for Slack and Gmail (or any other notification mechanism)
Setup Steps
Import and prepare the flows
The flows described in this article can be downloaded from: https://iamse.blog/download/send-notifications-for-a-breached-password-event-with-okta-workflows/
You can then create a new folder in Workflows and import the file.
- The connectors in both flows must have valid connections.
- For the Close card in the Event Initiated Flow, you can use a
No Authtype connection.
- For the Close card in the Event Initiated Flow, you can use a
- Select a Slack channel in the If Error section of the Process event object flow.
- After making any necessary changes, save both flows.
- Optional. To keep the data that passes through your flow, enable the Save all data that passes through the Flow? option. This data is helpful for the design and troubleshooting stages.
- In the Event Initiated Flow, click the Endpoint settings
</>icon at the bottom of the API Endpoint card.- Copy the Invoke URL. You need this value to create the event hook.
Create the Event Hook in the Admin Console
- Open your Okta Admin Console and go to Workflow > Event Hooks.
- Click Create event hook.
- In the Add hook details dialog, fill in the following fields:
- Name: Give your event hook a memorable name, for example Breached Passwords Notification. You can optionally provide a description as well.
- URL: Paste in the Invoke URL that you copied for the API endpoint.
- In the Subscribe to events field, type
A credential,and then select the event namedA credential, such as a password, which is associated with a known breach was used during an authentication flow. - Click Save & Continue.
- Continue to proceed and activate the hook.
Assuming the flows and hook are activated, everything is set up and the flow executes when a security.breached_credential.detected event occurs.
Optionally, you can modify or extend the Process event object flow for various other use cases.
- Change what the notifications say, who they’re sent to, or what systems they’re sent from.
- Create tickets in downstream systems
- Add a user to an Okta group that is subject to more stringent policies
This template also serves as a useful starting point when you need to work with Okta Event Hooks.
Testing this Flow
The only way that this flow can be invoked is when a security.breached_credential.detected event occurs and fires the associated event hook.
As the breached credential detection process is fully automated, there’s no way to manually trigger one of these events. Instead, you can use a preview of the payload to test the flow.
Note: It’s possible to open the previously configured event hook and click Deliver Request on the Preview tab. This sends a sample event to the Workflows API endpoint.
Using a payload preview is a good way to test event hook flows in many cases. However, without an existing security.breached_credential.detected event in the System Log, the sample event preview lacks some necessary data – such as an actor object that is populated with data – which this Workflow template attempts to parse values from.
Of course, when a real event occurs in your tenant, the payload will include the full set of data that these flows need; in our case, for testing purposes, we can manually trigger the flows using some sample data.
The following steps explain how to alter the JSON sample provided below to manually test your flow.
- Copy the sample JSON into a text editor and modify the following values:
actor.displayName- This is the user’s name for the notification message
- Currently this is set as
Test User
actor.alternateId- This is the email address where the message is sent
- The flow also uses this to look up the Slack User ID
- Currently this is set as
test@example.com
displayMessage- This is the email subject line
- Open the Event Initiated Flow in Workflows
- Click Run and in the body input, paste the modified JSON text. Then click
Runagain.
Sample JSON
Click here for Sample JSON
{
"eventType": "com.okta.event_hook",
"eventTypeVersion": "1.0",
"cloudEventsVersion": "0.1",
"source": "https://vl2.okta1.com/api/v1/eventHooks/example",
"eventId": "example",
"data": {
"events": [
{
"uuid": "exampleID1234",
"published": "2024-06-17T22:00:56.423Z",
"eventType": "security.breached_credential.detected",
"version": "0",
"displayMessage": "test@example.com - Credential set matches to known compromised credentials.",
"severity": "WARN",
"client": {
"userAgent": {
"rawUserAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36",
"os": "Mac OS X",
"browser": "CHROME"
},
"zone": "null",
"device": "Computer",
"id": null,
"ipAddress": "555.555.55.5",
"geographicalContext": {
"city": null,
"state": null,
"country": null,
"postalCode": null,
"geolocation": {
"lat": 55.55,
"lon": -111.55
}
},
"ipChain": [
{
"ip": "555.555.55.5",
"geographicalContext": {
"city": null,
"state": null,
"country": null,
"postalCode": null,
"geolocation": {
"lat": 55.55,
"lon": -111.55
}
},
"version": "V4",
"source": null
}
]
},
"device": null,
"actor": {
"id": "exampleOktaID12345",
"type": "User",
"alternateId": "test@example.com",
"displayName": "Test User",
"detailEntry": null
},
"outcome": {
"result": "SUCCESS",
"reason": null
},
"target": [
{
"id": "exampleID1234",
"type": "AuthenticatorEnrollment",
"alternateId": "unknown",
"displayName": "Password",
"detailEntry": null
}
],
"transaction": {
"type": "WEB",
"id": "exampleID1234",
"detail": {}
},
"debugContext": {
"debugData": {
"authnRequestId": "exampleID1234",
"deviceFingerprint": "exampleFingerprint1234",
"behaviors": "{New Geo-Location=UNKNOWN, New Device=UNKNOWN, New IP=UNKNOWN, New State=BAD_REQUEST, New Country=BAD_REQUEST, Velocity=UNKNOWN, New City=BAD_REQUEST}",
"requestId": "exampleID1234",
"dtHash": "exampleHash1234",
"risk": "{reasons=Anomalous Location, Anomalous Device, level=HIGH}",
"requestUri": "/idp/idx/challenge/answer",
"targetEventHookIds": "exampleID1234",
"url": "/idp/idx/challenge/answer?"
}
},
"legacyEventType": null,
"authenticationContext": {
"authenticationProvider": null,
"credentialProvider": null,
"credentialType": null,
"issuer": null,
"authenticationStep": 0,
"rootSessionId": "exampleID1234",
"externalSessionId": "exampleID1234",
"authenticatorContext": null,
"interface": null
},
"securityContext": {
"asNumber": null,
"asOrg": null,
"isp": null,
"domain": null,
"isProxy": null
},
"insertionTimestamp": null
}
]
},
"eventTime": "2024-06-17T22:01:21.809026Z",
"contentType": "application/json"
}
How it works
In the Event Initiated Flow:
- API Connector – Close is used to return a
200status code to the Okta Event Hooks system. Acknowledging receipt of an event is helpful because it tells the system it doesn’t need to redeliver the event.- See this section of Event Hooks docs for more details.
- Object – Get Multiple is used to get the
data.eventslist of objects so we can iterate over it.- Event Hooks might contain multiple events, so as a best practice, we work with the list and iterate over it with a List – For Each, in case multiple events were included in the payload.
Finally, in the Process event object flow:
- Another Object – Get Multiple is used to parse values out of the security.breached_credential.detected event payload.
- See Okta Workflows How-To: Read a JSON Path With Dot-Notation for more information.
- Text – Compose is used to build the notification message.
- The Gmail and Slack connectors are leveraged to send notifications and lookup a user.
- Those actions are placed in the “Try” block of an If Error function, which allows us to perform an alternate set of actions in the “If Error” block if one of them should fail.
- Building error handling like this into flows is a good way to increase their reliability and resiliency, and can alert your team if there is something that needs attention.
Screenshots



Limitations & Known Issues
No known issues, please refer to:

One thought on “Send Notifications for a Breached Password Event with Okta Workflows”