RuScope is a small privacy-focused Android System WebView browser beta. It has no analytics, accounts, ads, trackers, crash reporting, or background services. It requests INTERNET; Android 13+ also asks for notification permission only when you confirm a download, to show download progress and completion.
The Network Security Configuration uses system roots globally and adds the bundled Russian Trusted Root CA only to the Android ru single-label domain configuration with subdomains enabled. The app also has an explicit hostname policy: ru, example.ru, and subdomains match; evil.ru.com, ru.example.com, IP literals, and normalized non-.ru hosts do not. Hostname verification remains WebView/Chromium’s responsibility. onReceivedSslError always calls cancel(); there is no TLS-error override.
Publicly trusted pages—including .ru sites using a normal public CA—load through System WebView's Chromium network stack. If that normal verification rejects a main-frame .ru connection, RuScope cancels it and retries once through an app-local transport that combines system roots with the bundled Russian root. That transport is never selected for a non-.ru hostname or IP literal. Confirmed downloads first use in-app Cronet for public roots; only a failed .ru download can use the same scoped Russian-root fallback. The Russian-root download fallback does not follow redirects outside HTTPS .ru; users may need to open such final URLs normally. Download requests do not forward WebView cookies.
The bundled root was downloaded through the Android link published by Gosuslugi, and its subject is C=RU, O=The Ministry of Digital Development and Communications, CN=Russian Trusted Root CA. SHA-256: D2:6D:2D:02:31:B7:C3:9F:92:CC:73:85:12:BA:54:10:35:19:E4:40:5D:68:B5:BD:70:3E:97:88:CA:8E:CF:31. The build fails if the bundled certificate differs.
The retained CT snapshot is from https://browser-resources.s3.yandex.net/ctlog/ctlog.json, timestamp 2026-08-12T22:00:21Z; it is bundled and never fetched at runtime. Experimental app-local policy wiring is retained, but it does not integrate with Chromium WebView. SCT validation, once implemented end-to-end, will prove a signed promise from a log, not independent monitoring of the log’s Merkle tree.
Russian CT enforcement is not implemented in this beta. On first launch, RuScope presents a disclosure before loading the home page: Strict and Compatible intentionally stop navigation with the native error screen rather than falsely asserting a CT result. Select Off explicitly to browse without RuScope CT validation; Off is never selected implicitly, and the certificate sheet and settings call this unsafe state out. The app must not be represented as a CT-enforcing release.
Default behavior is HTTPS-only, Safe Browsing enabled, no mixed content, no file/content access, no popups, JavaScript only for modern sites, DOM storage enabled, and third-party cookies disabled. HTTPS-only is not a runtime override in this beta; cleartext traffic is disabled by Android network security configuration. Safety settings persist locally for CT mode, the first-launch disclosure acknowledgement, Safe Browsing bypass, and third-party cookies, which remain configurable. Safe Browsing returns to safety by default; a bypass is possible only after enabling the override and confirming on the interstitial. Downloads require explicit confirmation, are saved through MediaStore into Downloads, and show a progress/completion notification when the user grants notification permission. Certificate details identify the observed leaf issuer and whether the evidence came from System WebView validation or the app-local scoped fallback. WebView exposes the leaf certificate via getCertificate() after main-frame commit, not the complete successful chain; for scoped .ru pages RuScope records the transport's leaf certificate instead.
RuScope accepts HTTPS links shared by other apps through Android's ACTION_VIEW entry point. It validates each incoming link before WebView navigation, preserves its path, query, and fragment, and opens standard HTTPS ports directly. Valid HTTPS links using another port require explicit confirmation showing only the host and port. HTTP, non-web schemes, malformed addresses, embedded sign-in information, invalid ports, MIME payloads, and unsupported actions are rejected locally. RuScope does not accept share payloads or custom schemes, launch another handler, log or persist incoming URLs, or bypass the first-launch CT disclosure.
Russian issuer recognition is based on the observed leaf issuer, not a verified complete certificate chain. It accepts only the Ministry DN combined with either Russian Trusted Root CA or the real Russian Trusted Sub CA. The latter was observed on AlfaBank's public TLS leaf on 2026-08-21; WebView does not expose the complete successful chain.
Install JDK 17 and Android SDK 37.0. Set RUSCOPE_KEYSTORE, RUSCOPE_STORE_PASSWORD, RUSCOPE_KEY_ALIAS, and RUSCOPE_KEY_PASSWORD, then run gradle test lint assembleRelease. Inspect the result with apksigner verify --verbose --print-certs app/build/outputs/apk/release/app-release.apk. Releases from v1.0.0-beta.3 are signed by a locally generated RSA key; signer SHA-256: 6C:5D:65:3D:10:21:7A:07:46:1E:DA:C5:F1:B6:F9:2F:0F:A5:B2:94:6B:7B:59:06:84:4F:97:BB:85:CA:B8:AA. Earlier beta.1/beta.2 builds used a different key and will not update in place; reinstall once. The keystore and password are outside the source archive.
The release APK audit shows INTERNET, the user-requested POST_NOTIFICATIONS download-progress permission, and normal ACCESS_NETWORK_STATE, which Cronet requires to observe network changes. It has no app services or analytics/tracker SDKs. Cronet contributes one non-exported internal Google API activity; AndroidX contributes a non-exported startup provider and a DUMP-permission profile-install receiver. Those are dependency plumbing, not an account feature, telemetry, or a background service.
No professional security audit has been performed.