Privacy and network¶
Scoring happens on the device. In a production app, the input the SDK captures feeds the on-device scoring engine and nothing else: it is never uploaded. The SDK makes network requests for three things only, each described below: model updates, attestation, and proofs.
What the SDK captures¶
| Input | What is recorded | Where |
|---|---|---|
| Touches, stylus, mouse | Position, timing, pressure and its range, contact size, stylus tilt, buttons, the kind of tool | Every platform |
| Scrolling | Wheel and trackpad deltas | Every platform |
| Device motion | Accelerometer and gyroscope readings, at the rate your app sets. On Android, iOS and Flutter only one reading every 3 seconds is kept while the user is idle | Phones and tablets, including their browsers |
| Keys | The class of the key (letter, digit, space, and so on), modifiers and timing, never the character | Desktop browsers, except in password fields. Typing on mobile browsers. Android, iOS and Flutter only when your app reports key classes |
| What a touch landed on | The kind of control, and a short hash of the identifier your app gave it | Android, iOS, Flutter, React Native. On the web, only when you turn on targets, and then the kind of control only |
| App state | Foreground and background | Every platform |
| The device | Screen size and density, rotation, number of touch points. On the web, also the operating system from the user agent and, in Chromium browsers, the platform version and device model from the high-entropy User-Agent Client Hints (getHighEntropyValues), which show no prompt |
Every platform |
The SDK never reads text: not what is typed, not field values, not labels, and not what is on screen. Nothing is captured before the user consents, where consent is required, or while capture is paused (see each platform's User Consent and Sensitive Screens pages).
Where captured input goes¶
In a production app the captured input goes to the on-device scoring engine, which turns it into the score and keeps only the most recent actions. Nothing captured is written to storage or sent over the network. Custom events your app records stay on the device too.
Network requests¶
| Purpose | Requests | When | What is sent |
|---|---|---|---|
| Model updates | GET https://sdk.dep-protocol.com/models/prod/manifest.json, then the model file it names |
Each time the SDK starts, and on Android, iOS, Flutter and React Native again when the app returns to the foreground a day after the last check. Flutter checks only when you pass modelDirectory; the web skips it with modelUpdates: false, and waits for consent when consent is required |
Nothing about the app, the user or the device: a plain request with If-None-Match, no cookies |
| Attestation | GET https://poh-api.dep-protocol.com/api/attest/challenge, then POST https://poh-api.dep-protocol.com/api/attest |
Only after your app calls attest(). Android, iOS and Flutter then renew it shortly before it expires, about once an hour while the app runs; the web registers again on the next attest() call after that |
X-App-Key, the challenge, the device's public key, the platform's attestation token (none on the web), and on Android and iOS, device-integrity codes |
| Proofs | POST https://poh-api.dep-protocol.com/api/sessions and PUT https://poh-api.dep-protocol.com/api/sessions/{id} |
Only through Ads: the ad session on the Web, and the proof calls your app makes on Flutter, Android and iOS | X-App-Key, and a proof signed with the device key: your appId, the score, the number of actions behind it, the model version, the session id, the event it is for and the ad unit you named |
During attestation the operating system also contacts Google Play Integrity (Android) or Apple App Attest (iOS).
The device-integrity codes are short names for what the SDK found on the device, such as a root or jailbreak indicator, a hooking framework, a debugger or an emulator. They never include file paths or other content.
On the web, a Content Security Policy must allow these requests and the SDK's engine; the Web guide lists the directives.
What the SDK stores on the device¶
| What | Android | iOS | Web |
|---|---|---|---|
| The consent answer | SharedPreferences file ai.dea, key ai.dea.consent |
UserDefaults key ai.dea.consent |
localStorage key deapnetwork.consent |
| The device signing key, after Attest | Android Keystore alias dea.device-key (StrongBox or TEE when available) |
Keychain, tag ai.dea.device-key, in the Secure Enclave when available, this device only |
IndexedDB database deapnetwork.device-core, a non-extractable key |
| The attestation receipt | SharedPreferences file ai.dea, key ai.dea.receipt |
Keychain, service ai.dea; it survives reinstalling the app |
In memory only |
| Downloaded models | noBackupFilesDir/dea/models/ |
Application Support/dea/models/ |
IndexedDB database deapnetwork.device-core |
Flutter and React Native store the same values as Android and iOS, in the same places; Flutter
keeps downloaded models under the modelDirectory you pass. The SDK sets no cookies. Captured input
is held in memory only.
For app store disclosures¶
Google Play's Data safety form and Apple's App Privacy details ask what data leaves the device. These are the facts they ask about, for a production app; how you answer each form is your decision.
| Data | Leaves the device? | When |
|---|---|---|
| Touches, scrolling, device motion, key classes and their timing | No: the scoring engine reads them on the device and keeps none of them | — |
| Text, screen content, contacts, location, advertising ID, device identifiers | Never read | — |
| The public half of the device key | Yes, to DEA | When your app calls attest() |
| The Google Play Integrity or Apple App Attest token | Yes, to DEA | When your app calls attest() on Android or iOS |
| Device-integrity codes (root, jailbreak, hooking framework, debugger, emulator indicators) | Yes, to DEA | When your app calls attest() on Android or iOS |
A signed proof: your appId, the score, the number of scored actions, the model version, the ad session id DEA issued, the ad event and the ad unit |
Yes, to DEA | Only through Ads |
| The model update check | A plain request that carries no data about the app, the user or the device | Each time the SDK starts |
On iOS the SDK ships no privacy manifest (PrivacyInfo.xcprivacy): your app's own manifest
declares the required-reason APIs the SDK calls, listed in the
iOS guide.
Permissions¶
| Platform | What the SDK needs |
|---|---|
| Android | INTERNET, merged from the SDK's manifest. No runtime permission prompt. The SDK depends on Google's Play Integrity library |
| iOS | No permission prompt and no Info.plist entry. Attest needs the App Attest capability. The SDK ships no privacy manifest; see the iOS guide for what your app declares |
| Web | A secure origin (HTTPS or localhost). On iOS and iPadOS browsers, the motion permission prompt, shown on the user's first tap; it appears even before the user has consented when consent is required. No other prompt |
Logging¶
The published packages log nothing in production builds, and the SDK never sends logs anywhere.
On Android, debug = true prints one line per captured object to Logcat: keep it off in release
builds.