DEV Community

Play Console Store
Play Console Store

Posted on

Play Integrity: Device Integrity vs Account Integrity — What Each Signal Means


Play Integrity: Device Integrity vs Account Integrity — What Each Signal Means

Play Integrity verdicts hand you two very different signals in one response: what the device looks like, and what the account looks like. Developers often mush them together into a single pass/fail — and then wonder why legitimate users get locked out, or why abuse slips through.

This post breaks down play integrity device integrity labels versus account integrity labels, how to combine them into risk tiers, and how to act on each tier without torpedoing your UX.

Device integrity labels

The deviceRecognitionVerdict is a list of labels. The three that matter:

  • MEETS_BASIC_INTEGRITY — the device passes basic checks but can't prove much more. Emulators and many custom-ROM devices land here. It tells you "this looks like a real device, probably," and not much else.
  • MEETS_DEVICE_INTEGRITY — the device is a genuine, Play Protect-certified device passing Google's device checks. This is the label most production apps should target for standard features.
  • MEETS_STRONG_INTEGRITY — hardware-backed attestation: verified boot, locked bootloader, hardware key attestation. The strongest signal. Not all legitimate devices can produce it (older hardware, some regional variants), so requiring it universally will exclude real users.

Key point: these labels are about the device, not the user. A rooted power-user's Pixel can fail strong integrity while being a perfectly legitimate customer.

Account integrity labels

The appLicensingVerdict describes the Google account's relationship to your app:

  • LICENSED — the account acquired the app through Play (installed it, bought it, or has a valid entitlement). This is what you want for paid apps and in-app entitlements.
  • UNLICENSED — the account has no Play entitlement for this app. Could be piracy — or could be a sideloaded build, a tester on an unmanaged account, or an enterprise distribution.
  • UNEVALUATED — Play couldn't evaluate licensing (transient state, account issues, or Play services hiccups). Treat this as "unknown," not "guilty."

Account integrity answers "did this user get the app legitimately?" Device integrity answers "is this device trustworthy?" Those are independent questions with independent failure modes.

Combining signals into risk tiers

Don't AND them into one boolean. Build tiers on your backend:

Tier 0 — Trusted: MEETS_DEVICE_INTEGRITY (or strong) + LICENSED + app recognized. Full access. This is the happy path for the vast majority of users.

Tier 1 — Caution: basic integrity only, or UNEVALUATED account, with recognized app. Allow normal use; require step-up verification (email OTP, re-auth) before high-value actions like purchases, payouts, or account changes.

Tier 2 — Restricted: UNLICENSED, or no device integrity labels at all. Read-only or demo-mode access. For paid apps, this is your "please acquire the app from Play" branch — not a ban screen.

Tier 3 — Hostile: app not recognized (tampered/repackaged) regardless of other signals. Block sensitive actions; the binary itself can't be trusted.

// Backend policy sketch (pseudo-Kotlin)
fun policyFor(v: Verdict): AccessTier {
    if (v.appIntegrity != PLAY_RECOGNIZED) return AccessTier.RESTRICTED
    val deviceOk = v.deviceLabels.containsAny(MEETS_DEVICE_INTEGRITY, MEETS_STRONG_INTEGRITY)
    val licensed = v.accountVerdict == LICENSED
    return when {
        deviceOk && licensed -> AccessTier.FULL
        licensed -> AccessTier.CAUTION          // real user, weak device signal
        deviceOk -> AccessTier.CAUTION          // real device, licensing unclear
        else -> AccessTier.RESTRICTED
    }
}
Enter fullscreen mode Exit fullscreen mode

Emulator and root detection interplay

Play Integrity labels already encode a lot of what people try to detect with root/emulator checks — MEETS_BASIC_INTEGRITY-only on an emulator is the API telling you what your Build.FINGERPRINT heuristics would guess. Prefer the verdict over home-grown detection:

  • Home-grown root checks are an arms race you'll lose, and they false-positive on legitimate devices (work profiles, some OEM skins).
  • The verdict is signed by Google and verified server-side; a local isRooted() check is not.
  • If you must add client-side checks, treat them as telemetry, not enforcement.

UX guidance: explain, don't just error

When you restrict a user based on integrity signals, the worst thing you can do is show "Error 403." Users on custom ROMs or in regions with limited Play certification are often your most technical — and most vocal — users. Good patterns:

  • Say what happened in plain language: "We couldn't verify this installation. Some features are limited."
  • Give a path back: "Install the app from Google Play," "Update Google Play services," "Sign in with the account that purchased the app."
  • Offer an appeal path: a support link with the verdict labels (redacted) so your team can diagnose.
  • Never accuse: "Your device is compromised" is a great way to earn a 1-star review from someone running GrapheneOS.

Log the exact labels server-side for every restriction. When a user writes in, you want to see device=[MEETS_BASIC_INTEGRITY], account=UNEVALUATED — not a generic "integrity failed" entry.

Testing the tiers

Use Play Console's test verdicts to force each combination through your internal track: strong+licensed, basic+unlicensed, unevaluated, tampered app. Walk the app as each persona and confirm the UX reads correctly. Most teams test the happy path and the hard block; the tiers in between are where real users live.

Getting it right before review

Integrity policy is one of those things that's cheap to design early and expensive to retrofit after a security review or an abuse incident. If you want an experienced second pair of eyes on your verdict handling or your Play compliance posture, Play Console Store offers Google Play publishing services for Android developers.

About the author: This guide was written by the team at Play Console Store, an independent marketplace helping Android developers with Google Play publishing — account setup, verification, and closed testing. Not affiliated with or endorsed by Google LLC.

Top comments (0)