Mobile Verifier
Cryptographically verifiable data provenance, on a phone
The Oversight mobile verifier is the companion app for the desktop CLI. It opens a sealed
file, scans a QR code, or accepts a hash, and tells the recipient whether the manifest
signature is valid, whether the inclusion proof in the public Sigstore Rekor log checks
out, and what the manifest says about who issued the document and to whom. The verification
core is the same Rust workspace that powers the desktop CLI, embedded into the Flutter app
via flutter_rust_bridge.
A manifest that opens on a laptop opens the same way on a phone, with the same answer.
The repository is at oversight-protocol/oversight-mobile. Apache 2.0, same as the protocol.
Status
| Platform | Channel | Status |
|---|---|---|
| iOS | TestFlight (internal) | Live v0.1.11 |
| Android | Internal track / debug APK | Live v0.1.11 |
| iOS | App Store (external) | Pending after internal beta passes external review |
| Android | Google Play | Pending after internal beta |
| Android (no Google) | F-Droid | Planned |
| Anyone | GitHub Releases (.apk + reproducible build manifest) |
Planned |
The internal beta is closed (single-tester) while the project shakes out platform-specific
issues. External TestFlight invitations open after the iOS 26 SDK migration settles and the
export-compliance metadata is clean. The detailed write-up of how the build pipeline got
there, including the Apple-side gotcha that hides every TestFlight build until the
ITSAppUsesNonExemptEncryption key is set, is at
Mobile beta is live.
What it does
The mobile verifier accepts an Oversight artifact in three forms. A QR code that encodes
the manifest fingerprint, a typed or pasted hash, or an actual .oversight
bundle opened from the device's file picker. From any of those inputs it parses the
manifest, verifies the issuer's Ed25519 signature, fetches the corresponding inclusion
proof from the Sigstore Rekor public transparency log, and checks the proof against the
log's signed tree head. The output is a binary verdict (valid or invalid) plus the
manifest fields a recipient cares about: who issued the document, to whom, when, with
what algorithm suite, and what watermarks and beacons it carries.
Three things the app does not do. There is no account system, so there is nothing to log in to and nothing the project knows about who is verifying what. There is no telemetry or analytics SDK, so verification activity stays on the device. There is no Oversight server in the verification path; the only network call the app makes is to the public Rekor log operated by Sigstore, which any third party can also query. The cryptography happens on the device, against a public append-only log that anyone can audit.
What it is not
The mobile verifier is verification only. Sealing documents from a phone is a v2 feature that depends on hardware-backed keys (Secure Enclave on iOS, StrongBox on Android) and is not in the v1 scope. If a sender wants to seal from a mobile context today, the desktop CLI is the supported path and the mobile verifier is what their recipient uses on the other end.
The app is not free of platform middlemen. Apple controls the App Store, Google controls
Play, and any update through those channels passes through their review and signing
processes. That is a structural property of mobile distribution and not something the
project can talk its way out of. The mitigations are F-Droid for Android and a direct
.apk on GitHub Releases with a reproducible-build manifest, both planned.
The app is not a claim of perfect security. No mobile application is. What it is, is an open verifier whose source is published, whose verification core is the same code that runs on the desktop, and whose dependencies are auditable. If something is wrong, it is wrong in public.
Architecture
The UI layer is Flutter (Dart), single codebase across both platforms. The verification
core is the existing oversight-rust workspace, embedded via
flutter_rust_bridge and called from Dart through a generated FFI shim. There
is no second implementation of Rekor proof verification, no second implementation of
manifest signature checks, and no second copy of the canonical algorithm suites. Whatever
passes the desktop conformance tests passes the mobile build, because both compile from
the same Rust source. The most likely failure mode for a mobile verifier is to drift out
of sync with the canonical implementation; that class of bug is structurally impossible
with this architecture.
The iOS pipeline runs entirely on GitHub-hosted macOS runners (macos-26,
Xcode 26, iOS 26 SDK). The project does not require an Apple workstation to ship.
Signing certificates live in encrypted Actions secrets, and every build operation declares
every input explicitly so the workflow is reproducible from the source repository.
Android builds run both locally and on CI; release AABs are signed with an upload keystore
held outside the repository.
Reproducible builds and the trust model
Mobile distribution forces a question that desktop distribution can mostly avoid: how does
a recipient know the binary they install is the binary the source says it is? The honest
answer for stores is that they do not, beyond trusting Apple and Google. The trustless
answer is reproducible builds. The plan is to ship a build manifest with every tagged
release on GitHub: clone the repo, check out the tag, run one command, and confirm the
resulting binary is byte-identical to what is on F-Droid or in the GitHub Releases
.apk attachment. If the hashes match, the published binary contains exactly
the code the repository contains, with no additional surprises.
Reproducible builds are not yet live. Until they are, the most defensible fallback is the
source itself: every release is tagged, every tag has a matching CI run, and every CI run
uploads its artifacts. The workflows live under
.github/workflows/
and are auditable by anyone.
Get the beta
The fastest way to track the project is to watch the repository. Tagged releases land there first, with attached build artifacts and notes. External TestFlight invitations open after the iOS 26 SDK migration settles. Android internal-track access and a debug APK are available on request through GitHub once the second-tester slot opens.
Build documentation for anyone who wants to compile the app from source today lives at
docs/BUILD.md.
Both the iOS and Android pipelines are documented end-to-end, including the toolchain
versions and the cross-compile targets. The 32-bit Android targets (armv7, i686) require
the desktop CLI's Rust core at v0.4.8 or later, since that release ships the
MAX_CIPHERTEXT_BYTES portability fix the mobile build depends on.