Device binding links an account, a session or a credential to one specific app installation on one device, so that the same credential presented from anywhere else is refused. The app creates a private key that cannot leave the device, registers the matching public key with your server, and signs later requests with it. Binding proves that a request comes from the installation that enrolled. It does not prove who is holding the phone, so it sits alongside user authentication and never replaces it. On Android and iOS the key lives in different platform stores with different lifecycle rules.
What a binding proves
A valid signature shows possession of a key that was created on that installation and has not been exported. That gives your server continuity: this request comes from the same place as the enrolment.
It does not show that the person is the account holder, that the device is free of malware, or that the app calling is your unmodified release. Those questions belong to authentication, to runtime checks and to app attestation.
Android
The app generates the key in Android Keystore. On devices with a trusted execution environment or a StrongBox security chip the key is hardware-backed, and key attestation lets your server check that. A key can require the user’s biometric or screen lock before each use.
iOS
The app generates the key in the Secure Enclave using Apple’s Security framework. The private key cannot be exported, and access control flags can require the device passcode or biometrics before signing.
Challenge, freshness and the server’s decision
Binding is only as strong as its verification step:
- Enrol after a strong sign-in. The server stores the public key against the account and a random installation identifier.
- Challenge before a sensitive action. The server issues a single-use value with a short lifetime.
- Sign in the app. The signature covers the challenge and the key details of the request, such as amount and recipient.
- Verify on the server with the stored public key, then mark the challenge as spent.
- Decide under your policy. A missing or failed binding can mean step-up authentication rather than a flat refusal.
Signing the request details, not only the challenge, stops a valid signature from being attached to a different transaction.
Lifecycle and data minimisation
| Event | Effect on the key | Sensible handling |
|---|---|---|
| App reinstall on Android | Keystore keys are removed with the app | Re-enrol with full authentication |
| App reinstall on iOS | Keychain entries may survive deletion, but this is not dependable | Treat as a new enrolment |
| Factory reset or new phone | Keys are gone | Re-enrol and revoke the old binding |
| Restore from backup | Hardware-bound keys are not restored | Detect the missing key and re-enrol |
| Key rotation | Old key signs approval for the new one | Server swaps keys and logs the change |
| Lost or stolen phone | Key remains on the lost device | User or support revokes the binding |
Store the public key, the installation identifier, enrolment and last-use dates. Skip hardware identifiers entirely.
How Otukan applies device binding
Otukan creates the binding key in the platform’s hardware-backed store where the device offers one, with key handling built separately for Android and iOS and available to Flutter and React Native apps, and signs proofs over your server’s challenge. Each proof travels with Otukan’s runtime signals and attestation evidence, so your backend judges the key, the app and the environment in one step. You own the enrolment, re-enrolment and revocation rules, and every binding event reaches your backend.
The product control is covered on mobile device binding. For proof that the caller is your genuine app, see what is app attestation. Other terms are in the mobile security glossary.