# Risk Level Analysis

div
div
Client SDK
div
Mobile approve
div
SSO
div
Sub-journey
> Evaluates real-time risk indicators for identity-driven threats and exposes them to the journey


## Description

This step evaluates user interactions in real time using [Identity Threat Protection](/guides/user/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](/guides/risk/rules) under **Journey Tools**.
- Initialize Orchestration SDK with `collectRiskData` set to `true`. For Web, see [SDK initialization](/sdk-ref/idosdk/overview#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](/guides/orchestration/journeys/condition) steps with `@std.contains()` expressions to check for specific risk factors.


Note
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](/guides/orchestration/journeys/risk_recommendation) step with [Fraud Prevention](/guides/risk/overview) instead.

## Configuration

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


Journey event data
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](/guides/orchestration/getting-started/event_reporting).

## Output

The output variable contains the risk evaluation result and, if a rule matched, the rule decision. For example:

```json
{
  "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"
      }
    }
  }
}
```

## Example

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](/guides/orchestration/journeys/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.