Skip to content

Android: encrypted device keys and confirmed public-key enrollment - #6

Draft
Mafei wants to merge 3 commits into
candidate/android-mobile-product-20261008from
candidate/android-mobile-key-enrollment-20261008
Draft

Mafei wants to merge 3 commits into
candidate/android-mobile-product-20261008from
candidate/android-mobile-key-enrollment-20261008

Conversation

@Mafei

@Mafei Mafei commented Oct 8, 2026 •

Copy link
Copy Markdown
Owner

A ready, host-verified Android connection can now opt into generating a local Ed25519 key, then separately inspect and confirm installing its public key for one SSH target. Private material remains native, wrapped with a per-key Android Keystore AES-GCM key in noBackupFilesDir. The UI offers public-key copying, last observed status, multiple keys for rotation, key-only login, and separately confirmed local deletion.

Installation uses an isolated exec channel. It validates the non-root Linux account, safe HOME, descriptor-relative no-follow paths, owners, permissions, access/default ACLs, file/link types, local filesystem, existing bytes and preflight identity. It appends once under an advisory lock, preserves existing authorized_keys bytes/options/permissions, and deduplicates restricted matching keys. Unsafe or unsupported environments offer public copy for an administrator. Lost installation replies remain uncertain; no automatic rollback or replay.

A fresh independent pinned transport verifies only public-key authentication, with no password fallback and no PTY/shell. Additional authentication is distinguished; successful authentication does not certify terminal or forced-command policy. Current terminal/password access remains available. Local deletion closes connections using the deleted key and cancels related recovery; server entries require explicit revocation.

Base is sealed product SHA 85dd17a2bd611ef414227440389881f531084a8d (draft PR #5). Candidate SHA is 5ebd250a499f6dff52f4713f84ebcbece09b81c7, source tree ce3d7ba2ee3e14f2644890a54f06407b1d007d49. Only mobile files and the Android workflow changed. The original device-tested ded417ba852295f3ad76bcca4e6e557d1288ca12, sealed product branch and Linux PR #3 branch remain unchanged.

Exact-head CI run 37839679489, attempt 3, completed successfully at 2026-10-08T21:30:45Z. All nine Android API31–37 phone/tablet configurations pass: 29/configuration, 261 total, zero skips. Each includes 10 native instrumentation cases, 10 actual WebView cases, 4 native tmux cases and 5 actual WebView tmux cases. Existing host pins, tmux list/collision/missing-session/read-only/takeover policies, keyboard/touch, optional password storage, lifecycle, foreground retention and notification Stop All remain required. Checks also pass: 66 browser cases, 6 key-enrollment cases on standard Linux, 10 Rust cases, 12 real application Kotlin/JVM/JNI SSH/tmux cases and 29 JVM unit tests. The ARM64 Linux core runs the Rust and real JNI suites on a verified aarch64 host.

All nine delivery receipts bind this clean commit/tree, common payload 597f4ff4e19206af2ea7ec24f6eedd7d0199e0550cb95d59be7dd7161d235865, and ARM64 library 49ff6fae6dbc9998ab0b5ab34a5a14b5acfaa1be12c3c367ec68aa01e5b5b05c. Packaging checks confirm the intended permissions/service policy, public test certificate, JNI exports, production AOT/CSP assets and 16 KiB ELF/ZIP alignment.

These ZIPs contain APKs, source/runtime/delivery reports and seven actual adb screencap PNGs per configuration. Capture dimensions, UTC timestamps, byte lengths and SHA256 are in android-runtime-report.json. Phone target-confirmation screenshot: 2400×1080, 2026-10-08T20:40:33.456Z, SHA256 3f0d39a35acadeb53a4d5bd04c5da15f012458d702d7e269891b9567d580b7c2. API36 tablet target-confirmation screenshot: 1600×2560, 2026-10-08T21:25:56.390Z, SHA256 b98586d2c01c412c86464a389636f24d699f964632b351a5792bd940b5830b1e. GitHub artifacts expire 2026-10-22. Cloud-local download returned URLError, so these images have not received local pixel inspection or Library upload.

Earlier failures remain diagnostic evidence. c86ea9d exposed a nullable Kotlin device-key ID, now explicitly rejected before native storage access; one API37 SDK archive read failed before app execution. Corrected-head attempt 1 stopped on an API37 first-contact clipboard-overlay guard before key enrollment and cancelled checks after a Linux dependency-install stall. API37 tablet and checks passed on same-head attempt 2. API36 tablet stopped on a system Launcher ANR before app launch in attempts 1 and 2, then passed boot and all runtime/delivery tests on same-head attempt 3. No source edits, readiness/focus/ANR bypasses, timeout increases or relaxed acceptance counts were used for those retries. No failed/skipped runtime is a passed delivery receipt.

Tests use synthetic accounts, generated keys, temporary homes and loopback servers only. The local sandbox remaps system directory owners and rejects ACL writes; positive installer tests pass on standard Linux CI without relaxing safety checks. Private Ed25519 material is software-generated and Keystore-wrapped; short-lived JVM strings at the existing authentication boundary cannot be forcibly wiped. Android runtime evidence uses x86_64 emulators: ARM64 packaging/Linux JNI do not establish Android ARM64 execution, OPPO fold/unfold, user IME, Wi-Fi/cellular handover or 16 KiB runtime acceptance. Foreground retention cannot guarantee survival after system process termination. Debug certificate continuity, in-place upgrade and credential migration remain unverified. No real credentials, real servers, phone installs, persistent grants, merge or release.

Design, implementation boundaries and primary references: mobile/key-enrollment.md. The first batch remains sealed in draft PR #5, with its separate successful CI and preserved API36 phone APK.

AI disclosure: fully vibe coded by an AI coding agent. Draft for review and physical-device acceptance.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants