Releases: AfanasievN/react-native-device-risk-signals
Release list
v0.8.1 — correctness and privacy-manifest fixes
v0.8.1 - correctness and privacy-manifest fixes
A patch release fixing two defects introduced with the v0.8.0 signal batch. No new signals, no API
additions, and no change to how collection is configured.
Fixed
Unreadable /proc sources no longer report as "clean" (Android)
magiskAbstractSocketFound, magicMountModulesFound, fridaThreadNamesFound,
fridaInjectorPipeFound, fridaListenerPortFound and suOnPath are derived from reads that SELinux
routinely denies to third-party apps on stock devices — /proc/net/unix, /proc/net/tcp(6),
/proc/self/fd, /proc/self/task, and executing which. In v0.8.0 a denied read was collapsed to
false, so a locked-down (or genuinely compromised but unreadable) device was reported as clean.
These fields are now omitted when their source cannot be read, preserving the SDK's
missing-versus-false contract: "could not read" is a different observation from "read it and found
nothing". Backends must treat an absent field as unknown and must not default it to false.
iOS Lockdown Mode removed - Apple Required-Reason API
lockdownModeEnabled (added in v0.8.0) read the undocumented NSUserDefaults key
LDMGlobalEnabled. NSUserDefaults belongs to an Apple Required-Reason API category, while this
module ships a PrivacyInfo.xcprivacy that deliberately declares an empty
NSPrivacyAccessedAPITypes. Keeping the field would have made the privacy manifest untrue or forced
a CA92.1 declaration, breaking the "declares no Required-Reason API" guarantee that integrators
rely on.
The field is removed from the public contract, the probe catalog, and the iOS provider. This is a
source-compatible removal of an optional field: TypeScript consumers reading it get undefined
(it was optional), and no other field changed.
Compatibility and privacy
- No new signals, dependencies, permissions, JNI/NDK, persistent identifiers, network requests, or
Apple Required-Reason API declarations. The privacy manifest remains empty by design. - Backends should re-check any rule that treated the six Android fields above as booleans - they can
now be absent on perfectly ordinary devices.
Upgrade
npm install react-native-device-risk-signals@0.8.1For iOS applications, refresh CocoaPods after updating:
cd ios && bundle exec pod installAnyone on 0.8.0 should upgrade: the omit-instead-of-false fix changes signal semantics in a way that
affects scoring, and the Lockdown Mode removal clears an App Store review risk.
v0.8.0 — native-library-informed integrity signals
v0.8.0 - native-library-informed integrity signals
This backward-compatible feature release adds raw Magisk-hide, Frida, emulator, and iOS
reverse-engineering observations to os_integrity (and one to device_security_posture), sourced
from native open-source security libraries and reimplemented in pure Kotlin / Objective-C. The SDK
continues to return raw evidence only: no score, no verdict, no network calls, no persistent id.
Highlights
Magisk-hide-resistant tells (Android)
magiskAbstractSocketFound—/proc/net/unixcontains an abstract socket (name starting with
@) that is 32+ chars and free of/,., or spaces, matching Magisk's randomized control socket.magicMountModulesFound— a file mapped from/system,/vendor,/product, or/system_ext
shares the device number of the/datamount, i.e. a Magisk "magic mount" bind-mount. This is
observable from the app process even when the module path/name is hidden.
Broader Frida evidence (Android)
fridaThreadNamesFound— Frida worker threads (gum-js-loop,pool-frida,frida-gum) seen in
/proc/self/task/*/comm.fridaInjectorPipeFound— a/proc/self/fdentry whose target contains Frida'slinjectorpipe.fridaListenerPortFound— a LISTEN socket on 27042/27043 in/proc/net/tcp(6), catching
frida-server before any client connects.fridaHandshakeReject(onos_integrity_frida_scan) — the D-Bus/FridaAUTHhandshake on port
27042 answersREJECT, confirming genuine frida-server rather than any other service on that port.
Wider emulator coverage (Android)
More Andy/Nox/VirtualBox/x86 artifact files, a BlueStacks shared-folder path, and /proc/tty/drivers
folded into the goldfish CPU-token scan; more Magisk artifact paths.
iOS reverse-engineering and posture
parentPidUnexpected—getppid() != 1(not launchd), a debugger/debugserver-spawned tell.jailbreakBypassDetected— the "Shadow" anti-anti-jailbreak tweak is loaded (ShadowRuleset).mainExecutableEncrypted— the main Mach-O'sLC_ENCRYPTION_INFOcryptid;falseon a device
binary indicates it was decrypted/cracked (repackaging/piracy tell).openReverseEngineeringPorts— open loopback ports among 27042 (Frida), 4444 (Needle), 22
(OpenSSH), 44 (checkra1n).lockdownModeEnabled(ondevice_security_posture, iOS 16+) — Lockdown Mode state.
Backend contract guidance
- Every new field is optional and attacker-influenced; preserve missing versus
false. - The new Android fields are Android-only; the new iOS fields are iOS-only.
mainExecutableEncryptedisfalsefor development/simulator builds by design — interpret it only
for production distributions.- No existing field is removed or renamed.
Verification
- Root Jest suite passed; TypeScript, TurboModule contract, package, and GitHub Pages verification
passed. - Pure-Kotlin unit tests cover the new Magisk-socket, Frida-listener, magic-mount device cross-check,
and Frida-thread-name parsers.
The implementation adds no npm runtime, Gradle runtime, CocoaPods, or bundled binary dependencies;
no JNI/NDK, network requests, persistent identifiers, QUERY_ALL_PACKAGES, runtime permission
prompts, or Apple Required-Reason API declarations were added.
Deferred
An isolated-process re-check (the strongest Magisk DenyList/Shamiko bypass) and the pointer-heavy iOS
hook/breakpoint/Mach-O-hash checks are intentionally not in this release; they require dedicated
design and on-device verification.
Upgrade
npm install react-native-device-risk-signals@0.8.0For iOS applications, refresh CocoaPods after updating:
cd ios && bundle exec pod installNo existing field is removed or renamed; existing integrations retain their previous behavior.
v0.6.0 - install provenance and transaction-time Android observations
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:
installingPackageNameon supported Android versions, matching the installer of record;initiatingPackageNameandinitiatingPackageSigningCertificateSha256on Android 11+;installPackageSourceon Android 13+ asunspecified,store,local_file,
downloaded_file, orother;updateOwnerPackageNameon Android 14+;isSystemAppandisUpdatedSystemAppfrom the host package'sApplicationInfoflags.
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;isScreenCapturedaliases 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_OBSCUREDand
MotionEvent.FLAG_WINDOW_IS_PARTIALLY_OBSCUREDobservations; - the monotonic observation-window start, observed
ACTION_DOWNcount, 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
*ElapsedMsvalues as AndroidSystemClock.elapsedRealtimetimestamps, 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 toinstallingPackageNameonly 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-runpassed 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.0For iOS applications, refresh CocoaPods after updating:
cd ios && bundle exec pod installNo existing field is removed or renamed. Applications that do not enable transaction_safety
retain the previous runtime behavior.
v0.5.1 — easier evaluation and community feedback
v0.5.1 — easier evaluation and community feedback
This patch release improves how React Native teams discover, evaluate, and contribute to the
package. It does not change the public signal API, event schema, or default probe behavior.
Highlights
A clearer evaluation path
- The documentation site is now the canonical npm and GitHub homepage.
- The README leads with the library's product boundary and differentiators instead of maintainer
services: zero runtime dependencies, no vendor backend, no persistent device identifier, and no
client-side risk score. - Evaluation links now lead directly to installation, the signal catalog, integration Q&A, adoption
stories, and sanitized physical-device reporting. - The documentation landing page adds explicit GitHub and community actions while keeping local
collection and the Signal Bench screenshot as the primary evidence.
Honest physical-device compatibility
The new compatibility matrix distinguishes three levels:
- automated build verification;
- a reproducible community report from physical hardware;
- a result reproduced by a maintainer on comparable hardware.
Simulator compilation is not presented as physical-device validation. The initial matrix remains
empty until real sanitized reports are contributed.
Better contributor entry points
- A dedicated device form captures package, React Native, platform, OS, device class, build type,
and probe outcomes while warning contributors not to publish sensitive event data. - A dedicated raw-signal proposal form requires platform API provenance, privacy impact, omission
semantics, and confirmation that the proposal is not a score, verdict, identifier, or vendor call. - Contributor documentation links to scoped starter issues and GitHub Discussions.
Android lint compatibility
The Android network provider now structures permission-gated reads so Android lint can prove that
ACCESS_NETWORK_STATE is checked before protected APIs are called. The package still declares no
permission, and missing host permission still causes affected optional values to be omitted.
Compatibility and privacy
- Compatible with React Native 0.76+ and the New Architecture.
- No public TypeScript or native signal contract changes.
- No npm runtime, Gradle runtime, CocoaPods, or bundled native-binary dependencies added.
- No Android permissions, permission prompts, network requests, adoption telemetry, persistent
identifiers,QUERY_ALL_PACKAGES, or Apple Required-Reason API declarations added.
Upgrade
npm install react-native-device-risk-signals@0.5.1For iOS applications, refresh CocoaPods after updating the package:
cd ios && bundle exec pod installNo configuration or data-contract migration is required.
See the complete changelog,
device compatibility matrix,
and documentation.
v0.5.0 — Richer raw device context, clearer semantics
v0.5.0 — richer raw device context, clearer semantics
This release adds 23 new raw observations implemented with Android and Apple system APIs. The SDK
still performs no network request and returns no score, trust verdict, or blocking decision.
Highlights
Detailed Android battery, power, and NFC context
batteryHealth,batteryVoltageMv,batteryTechnology, andbatteryPresentexpose the values
available from the system battery broadcast.batteryLowreports Android's own low-battery classification;powerSourcedistinguishes battery,
AC, USB, wireless, and dock power where the platform provides it.- Android 14+ may report
batteryCycleCount, while Android 9+ may report
chargeTimeRemainingMs. Unsupported values and platform sentinels are omitted. nfcAvailableandnfcEnabledreport feature/adapter state without scanning a tag, opening an NFC
flow, requesting a permission, or displaying a prompt.
Active-network context without network traffic
When the host application already declares ACCESS_NETWORK_STATE, Android may now return:
networkTransportTypesdnsServerAddressesisPrivateDnsActiveandprivateDnsServerNameactiveNetworkMtuisInternetValidatedhasCaptivePortal
These observations come from the active link's system metadata. Collection performs no DNS lookup,
socket connection, IP-reputation request, or vendor call. Missing permission and failed reads omit
the affected values. An offline result is returned only after a successful observation found no
active network.
Build, provisioning, and display topology
- Android
androidBuild.buildTimeMsexposes publicBuild.TIME; it is a platform-build timestamp,
not an app installation timestamp. - iOS
embeddedProvisioningProfilePresentreports only whether the host bundle contains
embedded.mobileprovision; the profile is not parsed. - Android adds
displayCountandpresentationDisplayCount. - iOS adds
connectedScreenCountandmirroredScreenCount; the connected count includes the main
screen.
More honest unavailable-state behavior
- iOS
isScreenMirrorednow checksUIScreen.mirroredScreen. A second display used for extended
content is not automatically classified as mirroring. - Android no longer manufactures
usbDebuggingEnabled: falsefrom a setting ordinary modern apps
cannot read reliably. The compatibility field is omitted. getTaskAllowEntitlementis reserved as an optional field but not populated: the current public
iPhoneOS SDK headers do not expose a supported entitlement lookup API. The package does not
hand-declare unsupported symbols or replace an unavailable read withfalse.
Compatibility and privacy
- Backward-compatible additive API for React Native 0.76+ with the New Architecture enabled.
- Every new field is optional and preserves the distinction between unavailable and an observed
negative value. - No npm, Gradle, CocoaPods, or bundled native-binary dependencies were added.
- No new Android permissions, permission prompts, network requests, persistent identifiers,
QUERY_ALL_PACKAGES, or Apple Required-Reason API declarations were added. - Focused TypeScript and Kotlin regressions cover field/catalog parity, platform omissions,
connectivity policy, battery enum/sentinel handling, dependency boundaries, and privacy manifests.
Upgrade
npm install react-native-device-risk-signals@0.5.0For iOS applications, refresh CocoaPods after updating the package:
cd ios && bundle exec pod installNo configuration migration is required. Hosts that already grant ACCESS_NETWORK_STATE can receive
the new Android link observations; the SDK itself still declares no permission.
See the complete changelog
and Data Dictionary
for field-level detail.
v0.4.0 — More explainable raw device signals
v0.4.0 — more explainable raw device signals
This release adds compact, independently implemented observations using only Android and Apple
system APIs. The SDK still returns raw evidence only: applications remain responsible for
interpretation, transport, retention, and policy.
Highlights
Better location-source context
locationServicesEnabledseparates the system-wide service state from app authorization on both
platforms.- iOS 15+ can report
isSimulatedBySoftwareandisProducedByAccessorywhen a cached location and
CLLocationSourceInformationare available. - Missing cached locations and older iOS versions omit source fields; they are never reported as
clean observations. mockLocationAppsFoundremains in the optional public type for compatibility but is intentionally
not populated because complete discovery would require broad app enumeration.
More granular integrity evidence
- Android adds
isDebuggerWaiting, the exact matcheddangerousSystemProperties, and
loadedHookClassNamesfor loadable Xposed/Substrate/LSPosed classes. - Class lookup disables initialization, so the probe does not execute third-party initializers.
- Raw artifact coverage now includes selected KernelSU, APatch, resetprop, modern rootless
jailbreak, Dopamine, palera1n, TrollStore, ElleKit, and Frida paths, images, and environment names. - Findings remain explainable paths,
key=valuepairs, class names, or mapped images. The SDK does
not turn them into a root/jailbreak score or trust verdict.
Resource and execution context
- Android and iOS add
lowPowerModeEnabledandprocessResidentMemoryBytes. - Android adds
isLowRamDevice,runtimeMaxMemoryBytes, and
isInstalledOnExternalStoragefor the host app. - iOS adds
isIosAppOnMacandisMacCatalystAppexecution-environment flags. - Failed
/proc, Mach task, system-property, or platform-service reads omit optional values rather
than substituting zero orfalse.
Compatibility and privacy
- Backward-compatible additive API for React Native 0.76+ with the New Architecture enabled.
- No npm, Gradle, CocoaPods, or bundled native-binary dependencies were added.
- No new permissions, permission prompts, network requests, persistent identifiers,
QUERY_ALL_PACKAGES, installed-app/process inventory, or Apple Required-Reason APIs were added. - The Probe Catalog, Data Dictionary, README, public TypeScript contract, and both native
implementations describe the same optional fields and platform gating.
Upgrade
npm install react-native-device-risk-signals@0.4.0For iOS applications, refresh CocoaPods after updating the package:
cd ios && bundle exec pod installNo configuration migration is required. Consumers should treat every newly added field as optional
and preserve the distinction between “unavailable” and an observed negative value.
See the complete changelog and
Data Dictionary for field-level detail.
v0.3.0 — Explainable emulator and runtime signals
Highlights
Version 0.3.0 makes device observations more explainable and gives teams better raw inputs for their own risk models—without adding an SDK-side score, verdict, network transport, persistent identifier, or permission prompt.
Better emulator and device-farm evidence
- Expanded Android markers for Genymotion, BlueStacks, Nox, MEmu, LDPlayer, Andy, Droid4X, and KoPlayer.
- Added Firebase Test Lab, Android test-harness, iOS simulator-environment, and XCTest markers.
- Added structured evidence arrays and
emulatorChecksPerformed, so applications can understand why a marker was observed instead of relying only on an opaque boolean.
New explainable computation signals
- Added
deriveObservationMetrics(event)for ratios, consistency checks, and probe outcome counts computed from an already-collected event. - Added
runtime_timingobservations across the JavaScript event loop, React Native bridge, and native runtime. - Added
numeric_consistencyobservations for deterministic integer and floating-point calculations across JavaScript and native runtimes. - Extended
gpu_benchmarkwith median, p95, median absolute deviation, coefficient of variation, and warm-up slope.
runtime_timing, numeric_consistency, and gpu_benchmark remain disabled by default. Enable them only for calibrated cohorts after representative physical-device testing.
Integrity and posture coverage
- Expanded application provenance with Android SDK/signing and iOS receipt/build observations.
- Strengthened OS-integrity evidence for tracing, test keys, suspicious mounts, Zygisk, executable mappings, and environment markers.
- Added
device_security_posture, the default-offtransaction_safetyprobe, andderiveConsistencySignals().
Quality and documentation
- Verified parity across all 19 TurboModule methods in TypeScript, Kotlin, and Objective-C++.
- Added Android unit coverage for emulator classification and computation helpers.
- Updated the Probe Catalog, Data Dictionary, benchmark guide, README examples, and GitHub Pages documentation.
Upgrade
npm install react-native-device-risk-signals@0.3.0This is an additive minor release with no intentional breaking API changes. Review the new optional fields if your backend strictly validates the event schema.
Full changelog: v0.2.0...v0.3.0
v0.2.0
Breaking changes
- Removed the built-in transport API (
collectAndSend,TransportConfig, wire envelope, andsendFields). The host app now owns all network delivery. - Raised the supported React Native floor to 0.76 and documented the package as New Architecture-only.
Added
- Machine-readable Probe Catalog and strict configuration validation.
- Data Dictionary, privacy characteristics, and reproducible JS orchestration benchmark.
- React Native compatibility CI for 0.76.9, 0.81.6, and 0.86.0.
- Native Android/iOS builds, TurboModule contract verification, and CodeQL for TypeScript, Kotlin, Objective-C, and C++.
- Contributor guidance in
AGENTS.mdfor adding new probes safely.
Fixed
- Probe timeout timers are cleared after completion.
- Synchronous probe failures are isolated like rejected promises.
- The demo reports end-to-end collection duration.
- Session IDs use native CSPRNG-backed UUIDs.
Migration
Replace collectAndSend() with collect(), then send the returned result through your application's existing API client or transport layer.
See the full changelog.
v0.1.1 — Automated trusted publishing
Changes
- Added npm version and CI status badges to the README.
- Enabled automated npm publishing through GitHub Actions Trusted Publishing.
Install
npm install react-native-device-risk-signals@0.1.1v0.1.0 — Initial public release
Highlights
- Collect raw device, hardware, integrity, network, locale, application, and runtime observations on Android and iOS.
- Receive an independent
success,skipped,timeout, orerroroutcome for every probe. - Keep collection local by default and configure an optional HTTPS transport when your application is ready to send events.
- Control probes through configuration, field projection, timeouts, and a subtractive consent gate.
- Explore the complete response using the included light-theme Signal Bench demo application.
Install
npm install react-native-device-risk-signalsFor iOS applications, install CocoaPods dependencies after adding the package:
npx pod-installStatus
This is the first public release. The API and collected fields may evolve before 1.0.0; review every enabled probe, permission, disclosure, and retention rule before production use.
See the README for the complete response example, platform notes, and configuration reference.