App attestation is a check that lets your server confirm a request comes from a genuine, unmodified copy of your app running in an environment you accept. The app obtains signed evidence, from the platform and from checks inside the app, and your backend verifies it before trusting the call. Judge any attestation design on three questions: what the evidence proves, how the server keeps it fresh, and what happens across reinstalls and key changes. Attestation establishes the identity of the app, not the identity of the person using it.
What an attestation result proves
An attestation result is a statement about the caller, signed by something the attacker should not control. Read it narrowly.
| Signal | What it supports | What it does not establish |
|---|---|---|
| App identity | The binary matches the release you signed and distributed | That the user is who they claim to be |
| Device environment | The operating system passed the platform’s integrity checks at that moment | That no malware runs alongside your app |
| Freshness | The evidence was produced for this challenge or request | That the next request comes from the same app |
On Android
The Play Integrity API returns a protected token with verdicts on the app (recognised by Google Play or not), on the device’s integrity and on licensing. Your server decodes the token and reads each verdict. Hardware-backed key attestation can add a certificate chain describing where a key lives and the device’s boot state.
On iOS
App Attest, part of the DeviceCheck framework, creates a key pair in the Secure Enclave for one installation of your app. Apple certifies that key once, through an attestation object your server validates. After that the app signs assertions with the key, and each assertion carries a counter your server must see increase.
How verification works on your server
A sound design keeps every decision on the backend:
- Your server issues a random, single-use challenge.
- The app requests evidence bound to that challenge, or to a hash of the request it is about to send.
- The app sends the evidence together with the request.
- The server checks the signature, the app identity, the challenge, the validity window and, on iOS, the counter, then marks the challenge as used.
- Your policy decides: allow, limit, ask for step-up authentication or refuse.
If the app decides for itself whether it passed, an attacker only needs to patch that decision. Evidence that the server checks is what makes attestation worth having.
Reinstall, reset, rotation and data kept
Attestation keys belong to an installation, not to a person. On Android, Play Integrity tokens are requested fresh for each check, and Keystore keys used for key attestation are deleted with the app. On iOS a reinstall creates a new App Attest key that Apple must certify again. A factory reset or a new phone starts from nothing on both platforms, so your server should expect re-attestation and not treat it as suspicious in itself. Plan how old keys are retired and how often you ask for fresh evidence. Keep only what the decision needs: a key identifier, the verdicts, the time and the outcome. Avoid storing hardware identifiers, and set a retention period for rejected evidence.
How Otukan applies app attestation
Otukan combines platform attestation with its own runtime evidence. Next to Play Integrity and App Attest verdicts, the app reports rooted or jailbroken devices, hooking, debugging, emulators and altered code, and every item is labelled with its source. Android and iOS share one verification contract, your backend or gateway performs the check, and you choose how strictly each endpoint enforces it.
The product control is covered on mobile app attestation. For binding a session to one installation, see what is device binding. More definitions are in the mobile security glossary.