What is collected
| Surface | Captured | Not captured |
|---|---|---|
| Scroll | direction, velocity, acceleration, jitter | what was scrolled |
| Tap | timing, count, pressure (when available) | what was tapped (no view ids, no labels) |
| Swipe | direction, timing | content swiped |
| Typing | inter-key intervals, burst length, cadence | keystrokes, IME state, text content, language |
| App switch | timing of foreground change | app names, package ids (collected internally for session bookkeeping but not emitted in events) |
| Notification | timing, InterruptionAction (ignored / opened / answered / dismissed) | notification title, body, app source, user response content |
| Call | timing, InterruptionAction | caller id, contact name, audio |
| Clipboard | ClipboardAction (copy / paste / cut), ClipboardContext (text-field / system) | clipboard contents |
| Motion | 50 Hz triaxial accelerometer (m/s²) when emitRawMotionSamples or enableMotionLite enabled | gyro / magnetometer / GPS / barometer / camera / mic |
What is never captured
The following classes are not collected by any code path:- Text content (typed, displayed, or in clipboard).
- Audio (mic).
- Images (camera, screenshots).
- Location (GPS, network location, geofencing).
- Contacts.
- Calendar entries.
- Browser history.
- Network requests originating from the app (the SDK does not call out to the network at all — see “Outbound traffic” below).
Outbound traffic
The SDK itself makes no outbound network calls. There is no HTTP client in the synheart-behavior source. Cloud delivery, when desired, happens throughsynheart-core → the Synheart runtime’s ingest connector, which:
- Gates on
BehaviorandcloudUploadconsent. - Hashes
subject_id; the raw value never leaves the device. - Signs requests with the device’s hardware key (see Synheart Auth).
Platform permissions
| Permission | Required for | Scope |
|---|---|---|
| Notification listener (Android) | notification events with InterruptionAction | The SDK uses NotificationListenerService which observes notification posts. It records timing + action only; the listener never reads notification text. |
| Phone state / call log (Android) | call events | Timing and ignored/answered enum only; no caller id stored or emitted. |
| Accelerometer (sensor) | Motion-lite + raw motion samples | Standard sensor access; no special platform prompt on iOS/Android. |
| Accessibility service (NOT used) | — | The SDK does not request Accessibility on Android. Some apps use Accessibility for keystroke logging; this SDK does not. |
| HealthKit (iOS) | (none) | Behavior SDK does not touch HealthKit; that’s synheart-wear’s domain. |
SynheartBehavior.checkNotificationPermission() / requestNotificationPermission() and the call-permission equivalents are Android-only; iOS does not have a comparable user-facing permission for these surfaces, and the SDK collects only what iOS exposes through public APIs.
Adversary model
| Adversary | Concern | Mitigation |
|---|---|---|
| Malicious app on same device | Reading SDK-collected data via shared storage | The SDK does not write events to disk. Aggregates flow only through in-memory streams to the host app. |
| Compromised host process | Host can read everything in its address space | Out of scope: the SDK runs inside the host. Trust boundary is at the OS, not within the process. |
| Network adversary | Intercept telemetry | The SDK makes no network calls. When the host forwards events through the Synheart runtime, transport is TLS + device-signed proof. |
| Server-side observer | Reconstruct user identity from behavioral patterns | subject_id is hashed; no app names or content reach the cloud. Mitigations are at the cloud-policy layer. |
| Curious developer | Use the SDK in ways the user didn’t expect | Consent gates at three layers: SDK config (consentBehavior), runtime (Behavior consent), and platform OS permission grants. |
Implementation invariants
When auditing the SDK against this threat model, the following are non-negotiable code invariants:- No string captured from input fields.
BehaviorEventType.typingevents carry only timing fields in theirmetricsmap. - No clipboard contents.
ClipboardActionandClipboardContextenums encode the action/location, not the payload. - No notification body or title.
InterruptionActionenum is the only notification-derived field on events. - No outbound HTTP from the SDK. No HTTP clients imported in any of the four SDK packages.
- No background data persistence by the SDK. Events flow through streams; aggregates are computed in-memory and surface as
BehaviorSessionSummary. Hosts decide whether to persist.
Consent gating layers
Logging policy
The SDK logs atinfo / warn levels in production. Logs include:
- Session lifecycle (
session_start,session_end, durations). - Permission state changes.
- Inference latency (motion-lite).
- Event-level payloads (no event-by-event logs).
- User identifiers (raw
userId/deviceIdare never written to logs unless the host injects them). - Motion sample bytes.
- Inference inputs.
Related
- Behavior Overview — config flags including the
consentBehaviorflag. - Consent System — runtime gate enforcement.
- Synheart Auth — request signing for cloud-bound traffic.