Evaluates real-time risk indicators for identity-driven threats and exposes them to the journey
This step evaluates user interactions in real time using Identity Threat Protection, returns a set of discrete risk indicators, and branches the journey based on the rule engine outcome. To analyze risk level using this step:
- Ensure Identity Threat Protection is enabled as the risk engine for your tenant. Contact your Customer Success Manager to enable it.
- Configure evaluation rules under Journey Tools.
- Initialize Orchestration SDK with
collectRiskDataset totrue. For Web, see SDK initialization.
Upon detection, the risk signal is evaluated against the rule engine, which maps the signal to an Allow, Deny, or Custom decision. The step branches accordingly:
- Allow (rule-based): The matched rule allows the interaction. The journey proceeds along the Allow branch.
- Deny (rule-based): The matched rule denies the interaction. The journey proceeds along the Deny branch.
- Custom: No rule matched. The journey proceeds along the Custom branch, you can use Condition steps with
@std.contains()expressions to check for specific risk factors.
Identity Threat Protection returns risk indicators, not a full recommendation. If you need ML-driven recommendations, risk scoring, or full analytics, use the Risk Recommendation step with Fraud Prevention instead.
| Field | Description |
|---|---|
| Action type | Specifies the action being evaluated for risk, such as login, or register. |
| Output variable | Name of the variable used to store the result data from the completed step, including a list of risk signals, reasons and applied rule. |
| Error behavior | Determines the behavior in case an unexpected error occurs during the process. You can choose to either abort the journey (default) or handle errors using a dedicated error branch. |
This step can be configured to record step input and output data, or a custom payload, which is then surfaced in journey events in Journey Analytics for diagnostic purposes. For details, see Additional data reporting.
The output variable contains the risk evaluation result and, if a rule matched, the rule decision. For example:
{
"risk_analysis": {
"risk_result": {
"context": {
"action_id": "735a3fd1f1103b5ed64b..",
"action_type": "login",
"action_performed_at": 1779463611509,
"device_timestamp": 1779463611509,
"device_id": "eyJhbGciOiJIUzI1NiIsI..",
"correlation_id": "N/A",
"device_public_key": null,
"user_id": null,
"location": "https://example.com/login",
"ip": "185.220.101.34",
"ip_country": "DE",
"ip_location_region": "Hesse",
"ip_location_city": "Frankfurt am Main",
"ip_location_zip": "60306",
"ip_location_longitude": "8.68417",
"ip_location_latitude": "50.11552",
"ip_asn_name": "Zwiebelfreunde e.V.",
"ip_asn_id": "AS47163",
"ip_organization_name": "Zwiebelfreunde e.V.",
"ip_organization_type": "hosting",
"ip_location_timezone": "Europe/Berlin",
"device_timezone": "N/A",
"device_languages": [],
"device_platform": "desktop",
"os_name": "Mac OS",
"os_version": "10.15.7",
"browser_name": "Chrome",
"browser_version": "N/A",
"user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
},
"risk_signals": {
"device": {
"ram": null,
"total_storage": null,
"available_storage": null,
"battery_level": null,
"core_number": null,
"graphic_card": "N/A",
"model": "Macintosh",
"screen_height": null,
"screen_width": null,
"screen_color_depth": null,
"screen_pixel_depth": null,
"incognito": false,
"private_browser": false,
"tampered": true,
"emulated": false,
"spoofed": true,
"tz_mismatch": false,
"esim_usage": null,
"accept_languages": "en-US,en;q=0.9",
"mobile_network_code": null,
"screen_avail_width": null,
"screen_avail_height": null,
"font_count": null,
"cpu_arch": null,
"navigator_useragent": null,
"true_useragent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
"device_timezone_offset": null,
"device_name": null,
"summer_timezone_offset": null,
"winter_timezone_offset": null,
"device_power_state": null
},
"network": {
"vpn": false,
"tor": true,
"hosting": true,
"proxy": false,
"anonymizer": false,
"x_forwarded_for": [
"203.0.113.42"
]
},
"history": {
"ip_action_rate_60_sec": 1,
"user_action_rate_60_sec": 0,
"device_action_rate_60_sec": 1,
"ip_device_count_last_hour": 0,
"ip_user_count_last_hour": 0,
"linking_user_to_device_count": 0,
"linking_device_to_users_count": 0
}
},
"reasons": [
"DENY_BY_Risky devices",
"IP_RISKY_REPUTATION",
"DEVICE_RISKY_REPUTATION"
]
},
"rule_decision": {
"decision": "deny",
"matched_rule": {
"rule_id": "c07b5448-2279-45f2-aba2-4311802b1854",
"rule_name": "Risky devices"
}
}
}
}Consider a login journey that adapts its flow based on real-time risk indicators. After the user authenticates, the Risk Level Analysis step evaluates the interaction and branches based on the rule engine outcome:
- Allow branch: The rule engine determined the interaction is safe. The journey proceeds directly to the Complete journey step.
- Deny branch: The rule engine determined the interaction is malicious. The journey moves to the Reject access step.
- Custom branch: No rule matched. The journey uses a Condition step to check for specific risk factors in the output. For example, the expression
@std.contains(risk_analysis.risk_result.reasons.IP_RISKY_REPUTATION)checks whether IP address is compromized and branches accordingly.
You can chain multiple Condition steps on the Custom branch to evaluate additional risk factors sequentially. For example, after ruling out risky IP addresses, a second condition can check for DEVICE_NEW and branch to a step-up authentication step (such as Email OTP Authentication) if a new device is detected.