App attestation
Accept anon-key traffic only from your genuine apps on real devices: Play Integrity on Android, App Attest and DeviceCheck on iOS, debug tokens for simulators.
Your anon key ships inside the app, so anyone can copy it into a script. With attestation on, requests made with the anon key or by signed-in app users must also carry a short-lived attestation token that only your real app on a real device can get. Console members and server keys are never affected.
Register your apps
Android needs the package name and signing certificate SHA-256 (Play Integrity checks it); iOS the bundle id and team id.
Add verification credentials
Play Integrity: a Google Cloud service account allowed to decode integrity tokens (the FCM one is used if it belongs to the same Google Cloud project). DeviceCheck: an Apple key with DeviceCheck enabled (the APNs key is used if none is set).
Give the client a provider
final sovaria = Sovaria( url: url, anonKey: anonKey, attestation: kReleaseMode ? MyPlatformAttestation() : DebugAttestationProvider(debugToken), );Monitor, then enforce
Authentication › Mobile › App attestation: start with Monitor and watch the last-7-days counts. Switch to Enforce when “missing” is close to zero — older app versions without attestation stop working.
| Provider | Platform | Checks |
|---|---|---|
| Play Integrity | Android | Package name, signing certificate, Play recognised build, device integrity, our challenge, freshness. |
| App Attest | iOS 14+ | Apple-signed attestation of a hardware key for TEAMID.bundle, then signed assertions with an increasing counter. |
| DeviceCheck | Older iOS | A real Apple device running your team's app (cannot bind a challenge, so weaker). |
| Debug token | Simulators, CI | A secret you create in the console (shown once). Never in release builds. |
Unattested requests to an enforcing project get 401 with code APP_ATTESTATION_REQUIRED; the SDK fetches a new token and retries once. Attestation needs auth.app_attestation (Pro and up); after a downgrade enforcement stops.
MyPlatformAttestation implements AttestationProvider.evidence(challenge) through a platform channel: Play Integrity (StandardIntegrityManager, requestHash = challenge) or App Attest (DCAppAttestService, clientDataHash = SHA-256(challenge)). The fields it returns are listed in the SDK docs.