1Key v1.1.0 - Android Autofill, sync on unlock, and a top-to-bottom UI refresh
Same posture as v1.0.0: no account, no server, no INTERNET permission, no telemetry. 1Key v1.1.0 turns the app into a
system-integrated autofill provider, adds opt-in encrypted sync to a folder you pick, and refreshes the entire UI on a neutral
palette tuned for both light and dark modes.
In-place upgrade from v1.0.0. Your vault, biometric setup, PIN, saved 2FA codes, and backups are preserved.
Highlights
- Android Autofill - 1Key registers as an AutofillService. Fields in other apps and websites can be filled directly from the
OS picker. Search the vault in place, unlock with biometric or PIN from inside the picker, and cross-host confirm before
filling. AutofillCaptureBuffer is atomic so a capture-then-fill flow never loses an update. (Listed as "parked" in v1.0.0 -
shipping in v1.1.0.) - Sync on Master-Password Unlock (opt-in) - on every successful master-password unlock, 1Key writes a fresh encrypted backup
to a SAF folder you pick. No key persistence, no background daemon, no master-password-derived material kept. Biometric and
PIN unlocks deliberately skip sync because they do not give the app the master password (PRIVACY.md:49). - Theme picker - Follow system / Light / Dark. New installs default to Follow system. The app reacts to live OS dark-mode
flips without a restart. - Visual refresh - neutral palette in both themes, flat credential rows with category-derived icons, 56dp
top app bars pinned to the same chrome tier as the bottom nav, 2FA rows wrapped in Recycle-Bin-style cards, favourite heart
badge on the credential icon. - High-refresh-rate scrolling - upgraded to Compose 1.9 and Compose BOM 2025.08.00 so lists run at the device's native refresh
rate. - Faster cold start - root detection moved off the main thread, Application.onCreate slimmed, splash background pinned to the
body color so there is no white flash on rotation or warm restart.
Security and privacy posture
Unchanged from v1.0.0: Argon2id master-key derivation (m=64 MiB, t=3, p=1), AES-256-GCM with HKDF-SHA256 subkey separation and
per-field AAD bound to row + column, vault key wrapped by Android Keystore, verifier and PIN hash in
EncryptedSharedPreferences, no INTERNET permission, FLAG_SECURE by default. Threat model:
https://roufsyed.github.io/1Key/whitepaper.html
Reinforced in v1.1.0:
- VaultLockHook installed by the shared in-memory snapshot. On every VaultKeyHolder.lock() the hook fires synchronously, drops
the decrypted list reference, cancels the in-flight decryption job, and runs all of this before key bytes are zeroed. - Lock-aware composables (dialogs, sheets, dropdowns, text fields) ping the inactivity timer. Raw Dialog usage outside the
lock-aware wrappers is blocked by the UnsafeUnlockableSurface lint rule. - Lock screen pinned to portrait while mounted.
- Clipboard routed through SecureClipboardManager with 30s auto-clear; OS-menu copy of revealed passwords blocked.
What else changed
Features
- Categories with per-credential cleanup on delete; chip-based category picker in credential edit
- Multi-select delete in credential lists and Favourites; multi-select favourite toggle from the selection action bar
- Recently Accessed sort option across all credential lists
- Per-credential previous-access time bumped on view and copy; foreign last-used timestamps round-trip through accessed_at
- Settings search with deep-link routing and matched-row highlighting
- Auto-fill missing import titles from URL behind a preview toggle
- Foreign-tool JSON keys translated and custom-field labels prettified on import
- Foreign timestamps normalised to Unix milliseconds across CSV/JSON imports
UI / UX
- Neutral palette in both themes; light surfaceContainer family pinned to cool greys (no purple baseline
tint) - Flat divider-separated credential lists; row icon derived from the first tag
- Favourite heart badge at the bottom-right of the credential row icon
- 2FA list rows as card-style Surfaces matching the Recycle Bin layout
- 56dp top app bars pinned to surfaceContainer; top bar collapses on scroll (toggleable)
- Settings split into category sub-screens (General / Security / Autofill / Backup / Sync / FAQ / Privacy Policy)
- Lock screen revamp with unlock success animation; friendly "Wrong password" error replaces raw OpenSSL strings
- Confirm dialogs before destructive actions (delete category, disable recycle bin, delete vault, discard unsaved 2FA/OCR
state) - IME-aware layouts on every input screen so the submit button stays above the keyboard
- Themed Add-credential bottom sheet with category picker; per-credential-type form layouts
- In-app FAQ and Privacy Policy synced with the current security model and Sync addendum
Fixes
- White flash on rotation and warm restart removed (themed windowBackground, splash background, TaskDescription)
- Toggle-flash on Settings cold launch fixed across every user-configured state
- All crypto-heavy work and Argon2id KDF moved off the main thread; credential decryption off the main thread (list scroll
jitter gone) - RootDetector.check() moved off the main thread (no more getprop subprocess spawns blocking the first frame)
- TagRepository deferred from Application.onCreate
- Decrypted-list StateFlows cooled when no screen is subscribed
- PIN unlock accepting any 6-digit input fixed (security)
- Lock-vs-decrypt race that left credential lists empty fixed
- 2FA delete now unlinks the code from its credential instead of deleting the entry
- BiometricPrompt automatically dismissed when too-many-failures lockout fires; auto-biometric trigger gated on window focus
- Idle-lock timer suppressed during SAF picker and camera/OCR flows
- QR scanner crash fixed (Firelog classes kept in APK, INTERNET stripped via manifest override)
- TopAppBar system-bar icons now respond to the in-app theme toggle
- Double status-bar inset causing excess top space fixed across all screens
- Backup magic-header read fixed when InputStream returns short
- Tag LIKE filters anchored on JSON quote boundaries (no more substring matches)
- Onboarding form state persisted across rotation; stale errors and missing-file handling fixed
- runCatchingResult no longer swallows CancellationException