Device-integrity detection for Android. On-device detectors grade the environment — hardware attestation, verified boot, hook frameworks, root, emulators, APK tampering — and report findings as opaque INTEL_XXXX codes inside a signed, encrypted token. Your backend opens it and decides.
📚 Full documentation — Android integration, backend verification, keys & licences, the decoded signal catalogue, and the verification spec.
Three principles, no exceptions:
- Detection only — nothing is killed or blocked on-device; enforcement lives where the attacker isn't.
- Hardware-bound sessions — attestation runs once per login, keyed to your session id; the attested key signs every later scan.
- Opaque on the wire — tokens carry codes, not explanations. Probe mechanisms never leave the device.
Every port grades the same rooted-device capture identically. CI runs all seven suites in parallel on every push.
| Language | Path | Install | Test |
|---|---|---|---|
| Kotlin (reference) | verifier-kotlin/ |
Maven Central: tech.thessemaj:verifier-kotlin:3.0.0 |
./gradlew :verifier-kotlin:test |
| Python | verifier-python/ |
pip install -e verifier-python |
pytest verifier-python/tests |
| TypeScript | verifier-node/ |
npm install ./verifier-node |
npm test |
| Go | verifier-go/ |
vendored module | go test ./... |
| PHP | verifier-php/ |
Composer path repo | php tests/run_tests.php |
| Ruby | verifier-ruby/ |
gemspec | minitest suite |
| Rust | verifier-rust/ |
vendored crate | cargo test |
Two pip tools back the backend story:
deviceintelligence-licence— mint yourserver.keylicence asset and backend key:di-licence generate com.example.app out/. See Keys & licences.deviceintelligence-lab— test fixtures without a device: mint attestation chains, issue verdict tokens, spoof devices by keyword. See the lab docs.
Android (the Gradle plugin adds the runtime AAR, hashes your APK, re-signs):
plugins { id("tech.thessemaj.deviceintelligence") version "3.0.0" }Backend (any language — this is the whole integration):
val result = ScanVerifier().verifyScan(token, sessionId, serverPrivateKey)
when (result.decision) {
Decision.TRUSTWORTHY -> allow()
Decision.COMPROMISED -> stepUp(result.blockingSignals)
Decision.REJECT -> deny()
}Keys, provisioning and the full flow: the docs.
DeviceIntelligence — Copyright (c) 2026 Joseph James (github.com/iamjosephmj)
Licensed under the MIT License.