Shield · Mobile apps

Mobile apps

Shield scores the network behind each sensitive action in your iOS or Android app, the same way it does for a website: VPN, proxy, Tor, hosting and malicious networks, with a recommendation of allow, monitor, challenge or block. Your backend confirms the verdict before it acts.

How it works

Three steps

1In the Shield dashboard, create a mobile app site and register your app's id: the iOS bundle identifier, the Android applicationId, or both.
2Your app calls Shield once before each sensitive action, such as a signup, a login, a password reset or a checkout. Shield answers with a verdict.
3Your app sends the Shield session ID with the request to your backend. Your backend asks Shield about that session with the secret key (Server Verification) and allows, challenges or blocks.

The site key in your app is public, like any key shipped in an app. It identifies your app and proves nothing. Only the answer your server gets with the secret key counts.

Three ways to connect

The dashboard's Install page has each one with your key filled in

Your appWhat to add
Native iOS (Swift)The FindIPShield Swift package, findip-net/findip-shield-swift, from 1.0.1. iOS 15+, no dependencies, privacy manifest included.
Native Android (Kotlin)The FindIP Shield library from Maven Central, net.findip:shield-android:1.0.1 (findip-net/findip-shield-android). Android 8+, INTERNET permission only.
WebView (Capacitor, Ionic, Cordova, a page in a native WebView)The website script with data-integration="webview" and data-app-id (SDK 1.13.0 or later). Form detection and in-page enforcement work as on a website.

Projects without a package manager can paste a single-file helper instead; the Install page offers it under each guide.

// iOS: Package.swift (or Xcode → Add Package Dependencies…)
.package(url: "https://github.com/findip-net/findip-shield-swift", from: "1.0.1")

// Android: build.gradle.kts
implementation("net.findip:shield-android:1.0.1")
<script src="https://cdn.findip.net/shield/v1.js"
  data-site-key="pub_xxxxxxxxx"
  data-integration="webview"
  data-app-id="com.example.app"
  async></script>

What the app sends

Metadata only

SentNever sent
The app id, version and buildAnything the user typed: passwords, form values, messages
The OS and its versionAdvertising IDs (IDFA, GAID) or any cross-app identifier
The device family (iPhone, iPad, Pixel), never the exact modelContacts, location, photos, or any other device data
Locale and timezoneA device fingerprint
A session ID per app launch and a visitor ID kept in the app's own storagePlain emails or user IDs (only hashes and encrypted values, if you identify users)
The event name, for example login_attempt

Shield reads the IP address from the network connection, never from the app. The full field list is in the Events reference.

For the App Store's App Privacy form and Google Play's Data safety form, the SDKs collect a device or other ID (the app-scoped visitor ID), app interactions (the event names), and app info (app and OS version). Purpose: fraud prevention and security. It is not used for tracking or advertising, and it is not linked to the user's identity unless you send identity yourself.

Verdicts in an app

The app reacts; the backend decides

recommendationWhat to do
allowProceed.
monitorProceed; log it if you keep a review queue.
challengeYour backend asks for its own step-up: a one-time code, a re-login, an email link.
blockYour backend refuses after verifying the session. The app shows a neutral "could not complete" message.

No answer from Shield (no network, a timeout) means unknown, never safe. Decide per action.

Refusals

Shown on the dashboard's Install page

ErrorFix
app_mismatch (403)The app id is not registered for that platform. Add it under Settings → Apps & keys. Debug builds with an id suffix count as separate apps.
integration_not_allowed (403)A website used an app site's key, or an app used a website's key. Each needs its own kind of site.
daily_quota_exceeded (429)The site's daily quota is used up. Events are accepted again from 00:00 UTC.

Custom rules for apps

Retire old builds with one rule

Custom rules work on an app site the same way as on a website: a matching rule replaces the recommendation your app and your backend receive. Two conditions are made for apps:

  • Platform: iOS app, Android app, or WebView.
  • App version: below, at or below, exactly, at or above, or above a version such as 4.0.

The App version or platform match uses them on their own, for example "block Android app versions below 4.0". Any other rule can use them to narrow itself, for example "challenge this country, but only in the Android app". The app reports its own version, so use these conditions to retire old builds, not as proof that a request comes from your genuine app.

Shield, App Attest and Play Integrity

Different questions; use them together

FindIP ShieldApp Attest (iOS)Play Integrity (Android)
AnswersIs the network behind this action risky?Is this your genuine app on a genuine Apple device?Is this your genuine app, from Google Play, on a certified device?
SeesVPN, proxy, Tor, relay, hosting, malicious IP; IP, network and country changes in the sessionThe app and the device keyThe app, the device and the Play licence
Does not seeWhether the app binary is genuineThe network: a real app on a real phone behind a proxy or in a phone farm passes
Your backendVerifies the session with your secret keyVerifies Apple's attestationDecodes Google's verdict

Integrity proves the request comes from your app; Shield shows where it comes from. Device integrity is not part of Shield today, so run App Attest or Play Integrity on your own backend next to the Shield verify call.

Limits

Free Preview

  • The same quota as a website: 10,000 events a day per site. Send sensitive actions, not every screen.
  • One site holds up to 10 apps, so the iOS, Android and staging builds of one product share sessions, rules and alerts.
  • Device integrity checks (App Attest, Play Integrity) are not part of this release; see how they fit together.