On the Free plan,
risk_score is null in the attestation JWT. Use risk_category to make access decisions. See Backend Verification for details.Score ranges
On Pro, Business, and Enterprise plans, the numeric score maps to these levels: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.
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.
Using risk data
By category (all plans)
Every plan returns arisk_category in the attestation JWT. Use the numeric score ranges to branch in Swift:
The
risk_category string is also available directly from the decoded JWT on your backend. See Backend JWT Verification.By numeric score (Pro / Business / Enterprise)
If your plan includes the numeric score, you can use finer-grained thresholds: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.On your backend
Decode the JWT to read risk data:Webhooks
On Pro, Business, and Enterprise plans, webhooks fire for risk-related events:device.high_risk— A device exceeds your risk thresholddevice.new— First attestation from a new devicedevice.attestation_failed— A device fails attestationattestation.anomaly— Unusual attestation pattern detected