Server-verifiable, hardware-backed device attestation via the opt-in package
react-native-nitro-device-integrity.
DCAppAttestService) + DeviceCheck (DCDevice)This is a separate, opt-in package from the core library. Install it only if you need real attestation; it pulls in Play Integrity / App Attest dependencies and requires Google Cloud / Apple console setup.
This API complements the core Device Integrity API.
isDeviceCompromised()) — instant,
offline, easily bypassed. A first-line pre-filter.Use the local check as a fast pre-filter and attestation as the gate your server trusts.
Every method returns an opaque token. The library cannot decode it and never returns a boolean "is this device safe?" — that decision belongs to your server. You must send the token to your backend for verification.
| Responsibility | Owner |
|---|---|
| Issue token / attestation / assertion on the device | this library |
Compute clientDataHash (SHA-256), assemble client data |
your app |
| Send the token to your backend | your app |
| Decrypt / verify signature / interpret the verdict | your server |
Persist the App Attest keyId |
your app (library is stateless) |
| Google Cloud / Apple console setup | you (developer) |
Requirements: iOS 14.0+ (App Attest) / 11.0+ (DeviceCheck), Android API 23+ with Google Play Services.
isSupportedBest-effort check. On Android, true when Google Play Services is available
(does not guarantee the Play Integrity API is onboarded for your app). On
iOS, DCAppAttestService.shared.isSupported — always false on the Simulator.
providerTypeWhich provider backs this device. Branch your client logic on this before calling platform-specific methods.
prepareStandardProvider()Warms up the Play Integrity Standard token provider. Call once per session;
the provider is cached natively. cloudProjectNumber is passed as a string to
avoid JS number-precision loss.
Rejects with (in the error message): CLOUD_PROJECT_NUMBER_IS_INVALID,
PLAY_STORE_NOT_FOUND, NETWORK_ERROR, etc. On iOS: UNSUPPORTED_PLATFORM.
requestIntegrityToken()Requests a Standard token. Requires a prior prepareStandardProvider. If the
cached provider has expired (INTEGRITY_TOKEN_PROVIDER_INVALID), it is
re-prepared once automatically and the request retried.
requestHash is a base64 SHA-256 of your request's critical parameters
(max 500 bytes) — not a server nonce; the caller computes it. Returns an
opaque, encrypted token string.
requestClassicIntegrityToken()Play Integrity Classic flow (one-off, server-nonce based). Prefer Standard
for frequent checks. nonce must be a server-generated, single-use, URL-safe
base64 value of 16–500 bytes.
generateKey()Generates an App Attest key pair in the Secure Enclave and returns its keyId.
The keyId is the only handle to this key — store it (e.g. Keychain). The
library is stateless. App Attest keys do not survive app reinstall;
regenerate on DCError.invalidKey.
attestKey()Attests a key (once per key, per install). Makes a network call to Apple.
clientDataHash is base64 of SHA-256(server challenge) — the library does
not hash for you. Returns base64 of the opaque CBOR attestation object.
generateAssertion()Generates an assertion for a subsequent request (offline). Returns base64 of the opaque CBOR assertion object. Your server checks its monotonic counter to detect replays.
getDeviceCheckToken()Generates an Apple DeviceCheck token (device-level, lighter than App Attest). Your server queries/updates the device's 2 bits of state via Apple's DeviceCheck API.
This library stops at issuing the token. Your backend verifies it.
Send the token to your server, then call Google's decode endpoint (recommended):
Interpret the decoded verdict:
deviceIntegrity.deviceRecognitionVerdict containing MEETS_DEVICE_INTEGRITYappIntegrity.appRecognitionVerdict === 'PLAY_RECOGNIZED'deviceRecognitionVerdict signals a compromised/emulated device.See Validating apps that connect to your server.
prepareStandardProvider /
requestClassicIntegrityToken.com.apple.developer.devicecheck.appattest-environment entitlement..p8 key in the Apple
Developer portal.All of the above lives in your developer accounts and app target. The library
cannot set it up — it only issues tokens once your app is configured.
:::warning Be honest about what attestation can and cannot do
isSupported is false on the iOS Simulator;
Play Integrity returns weak/empty verdicts on emulators.deviceRecognitionVerdict — your server must treat that as a failure.attestKey. Control call
frequency in your app; the library adds no retry/timer (it stays stateless).
:::