> ## Documentation Index
> Fetch the complete documentation index at: https://docs.grantiva.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Risk Scoring

> Understanding risk categories, numeric scores, and how to use them by plan tier

Every attestation returns a **risk category** — but the full numeric score depends on your plan.

| Plan                        | What you get                                                    |
| --------------------------- | --------------------------------------------------------------- |
| Free                        | Risk category only: **Trusted**, **Suspicious**, or **Blocked** |
| Pro / Business / Enterprise | Full 0–100 numeric risk score + category                        |

<Callout type="info">
  On the Free plan, `risk_score` is `null` in the attestation JWT. Use `risk_category` to make access decisions. See [Backend Verification](/backend-verification) for details.
</Callout>

## Score ranges

On Pro, Business, and Enterprise plans, the numeric score maps to these levels:

| Range  | Level    | Category   | Description                                                  |
| ------ | -------- | ---------- | ------------------------------------------------------------ |
| 0–20   | Low      | Trusted    | Stock OS, legitimate app, normal behavior.                   |
| 21–50  | Medium   | Suspicious | Some risk indicators. May warrant additional verification.   |
| 51–75  | High     | Suspicious | Significant risk. Consider blocking sensitive operations.    |
| 76–100 | Critical | Blocked    | Likely compromised. Block access or require re-verification. |

## Risk factors

The score considers multiple signals:

* **Jailbreak detection** — Actual jailbreak/root signals. The strongest single factor.
* **Development builds** — Debug, Xcode, and TestFlight installs are scored as a separate, lower-weight signal than jailbreak. A dev build alone doesn't mark a device as compromised — it's expected during integration.
* **Device integrity** — Does the attestation pass Apple's checks?
* **Suspicious activity history** — Past suspicious events raise the score, with **recency decay**: each clean week forgives one past event, so a device that stays clean earns its trust back over time.
* **Device age** — New devices (fewer than 3 attestations) carry a temporary penalty that clears as attestation history builds.
* **Anomaly detection** — Rapid country changes, app version downgrades, VPN/proxy networks, device model inconsistencies, and unusual timing patterns.

<Info>
  Scores are dynamic in both directions: they rise on suspicious signals and fall again as a device builds a clean streak. Don't persist a device's score long-term — read it fresh from each attestation.
</Info>

## Using risk data

### By category (all plans)

Every plan returns a `risk_category` in the attestation JWT. Use the numeric score ranges to branch in Swift:

```swift theme={null}
let result = try await grantiva.validateAttestation()
// Trusted: 0–20 | Suspicious: 21–75 | Blocked: 76–100
let score = result.deviceIntelligence.riskScore

if score <= 20 {
    proceedNormally()
} else if score <= 75 {
    requestAdditionalAuth()
} else {
    blockAccess()
}
```

<Info>The `risk_category` string is also available directly from the decoded JWT on your backend. See [Backend JWT Verification](/backend-verification).</Info>

### By numeric score (Pro / Business / Enterprise)

If your plan includes the numeric score, you can use finer-grained thresholds:

```swift theme={null}
let result = try await grantiva.validateAttestation()
let score = result.deviceIntelligence.riskScore

switch score {
case 0...20:
    proceedNormally()
case 21...50:
    requestAdditionalAuth()
case 51...75:
    limitAccess()
default:
    blockAccess()
}
```

<Info>On the Free plan, `riskScore` is `0` and `risk_score` is `null` in the JWT. Use `risk_category` from the decoded JWT to make tier-safe access decisions on Free.</Info>

### On your backend

Decode the JWT to read risk data:

```json theme={null}
{
  "device_intelligence": {
    "risk_score": 15,
    "risk_category": "trusted",
    "jailbreak_detected": false,
    "device_integrity": "valid"
  }
}
```

## Webhooks

On Pro, Business, and Enterprise plans, webhooks fire for risk-related events:

* `device.high_risk` — A device exceeds your risk threshold
* `device.new` — First attestation from a new device
* `device.attestation_failed` — A device fails attestation
* `attestation.anomaly` — Unusual attestation pattern detected

See [Webhooks](/concepts/webhooks) for setup.

## Dashboard analytics

The analytics dashboard shows risk distribution, high-risk device trends, and jailbreak detection rates. See [Analytics](/dashboard/analytics).
