Skip to content

v0.6.0 - install provenance and transaction-time Android observations

Choose a tag to compare

@AfanasievN AfanasievN released this 22 Jul 14:43
· 29 commits to main since this release

This backward-compatible feature release adds inspectable Android install-source context and direct
transaction-time screen/touch observations. The SDK continues to return raw evidence only: it does
not calculate a score, emit a trusted/untrusted verdict, contact Google Play, or upload data.

Highlights

Richer own-package install provenance

The application probe preserves installerPackage for compatibility and adds:

  • installingPackageName on supported Android versions, matching the installer of record;
  • initiatingPackageName and initiatingPackageSigningCertificateSha256 on Android 11+;
  • installPackageSource on Android 13+ as unspecified, store, local_file,
    downloaded_file, or other;
  • updateOwnerPackageName on Android 14+;
  • isSystemApp and isUpdatedSystemApp from the host package's ApplicationInfo flags.

Every read is limited to the host application's own package. Installer values remain
attacker-influenced local observations and must not be treated as Google Play recognition,
licensing, or device-integrity verdicts. Unavailable values are omitted.

originatingPackageName is deliberately not exposed because ordinary applications cannot receive
it without the privileged INSTALL_PACKAGES permission.

Direct transaction-time UI observations

The disabled-by-default transaction_safety probe now supports:

  • Android 15+ isVisibleInScreenRecording; isScreenCaptured aliases this state on Android for
    cross-platform compatibility;
  • Android 14+ screenshot callback availability, whether a screenshot was observed after the
    observation window began, and its latest monotonic timestamp;
  • direct MotionEvent.FLAG_WINDOW_IS_OBSCURED and
    MotionEvent.FLAG_WINDOW_IS_PARTIALLY_OBSCURED observations;
  • the monotonic observation-window start, observed ACTION_DOWN count, and latest obscured-touch
    timestamps.

Observation starts lazily only when transaction_safety is actually collected. A protected flow
should collect once when its UI opens, then collect again immediately before the protected action:

const transactionConfig = {
  probes: {transaction_safety: {enabled: true, timeoutMs: 900}},
};

await deviceIntel.collect({config: transactionConfig});
// User reviews and confirms the protected action.
const actionContext = await deviceIntel.collect({config: transactionConfig});

Before a real ACTION_DOWN is observed, obscured-touch booleans are omitted rather than reported as
false. Screenshot fields are omitted unless the callback was successfully registered. Android 15
recording state is omitted on older systems or when unavailable.

Host-controlled capture permissions

The package's Android manifest still declares no permissions. Applications that intentionally use
capture observations can opt in through their own manifest:

<uses-permission android:name="android.permission.DETECT_SCREEN_CAPTURE" />
<uses-permission android:name="android.permission.DETECT_SCREEN_RECORDING" />

These are install-time detection permissions and the SDK never opens a permission prompt. Android
shows its standard user notice when the screenshot callback detects a capture. Declare only the
permission required by the application's documented protected flow.

Backend contract guidance

  • Treat every new field as optional and attacker-influenced.
  • Preserve missing versus false: they describe different observation states.
  • Treat *ElapsedMs values as Android SystemClock.elapsedRealtime timestamps, not Unix epoch time.
  • Use install-source and UI observations as explainable context alongside authenticated server data
    and platform attestation, never as a single-signal block.
  • Continue accepting installerPackage; migrate to installingPackageName only when convenient.

The complete selectable field inventory is available in the hosted
Signal Catalog and its
machine-readable JSON.

Verification

  • Root Jest suite: 105 tests passed.
  • TypeScript, TurboModule contract, package, and GitHub Pages verification passed.
  • Android native unit tests, example debug assembly, and Android lint passed.
  • Example Jest, ESLint, and TypeScript checks passed.
  • npm pack --dry-run passed and includes the new native sources and declarations.

The implementation adds no npm runtime, Gradle runtime, CocoaPods, or bundled binary dependencies;
no network requests, persistent identifiers, QUERY_ALL_PACKAGES, runtime permission prompts, or
Apple Required-Reason API declarations were added.

Upgrade

npm install react-native-device-risk-signals@0.6.0

For iOS applications, refresh CocoaPods after updating:

cd ios && bundle exec pod install

No existing field is removed or renamed. Applications that do not enable transaction_safety
retain the previous runtime behavior.