Verify that requests come from a genuine, untampered app on a real device using Expo App Integrity — App Attest on iOS and Play Integrity on Android — with server-side verification via Expo Router API routes.
- Install packages with
yarnornpm install.- If you have native iOS code run
npx pod-install
- If you have native iOS code run
- Copy
.env.exampleto.envand add your Apple and Google credentials. - Run
yarn startornpm run startto start the bundler (it also serves the API routes on Node). - Open the project in a development build on a real device to try it. App Attest and Play Integrity don't work in Expo Go or on simulators/emulators.
- Set
EXPO_PUBLIC_API_URLto a URL the device can reach (your machine's LAN URL, or a deployed server).
with-app-integrity
├── app
│ ├── _layout.tsx ➡️ Expo Router root stack
│ ├── index.tsx ➡️ Client UI + attestation/assertion flow
│ └── api
│ ├── challenge+api.ts ➡️ Issues one-time challenges
│ └── verify+api.ts ➡️ Verifies attestations, assertions, and tokens
├── helpers
│ ├── store.ts ➡️ In-memory challenge & attested-key store
│ ├── verify-ios.ts ➡️ App Attest verification (node-app-attest)
│ ├── verify-android.ts ➡️ Play Integrity verification (@googleapis/playintegrity)
│ └── is-valid-android-request.ts ➡️ Play Integrity verdict checks
├── app.config.js ➡️ Expo config file
└── .env.example ➡️ Apple & Google credentials template
- Learn more about Expo App Integrity.
- Learn more about Development Builds
- Server verification uses node-app-attest (iOS) and @googleapis/playintegrity (Android).