Skip to content

iOS: save the recovery phrase to Passwords, and restore from it - #476

Merged
jvsena42 merged 4 commits into
mainfrom
feat/ios-password-manager
Oct 9, 2026
Merged

jvsena42 merged 4 commits into
mainfrom
feat/ios-password-manager

Conversation

@jvsena42

@jvsena42 jvsena42 commented Oct 8, 2026 •

Copy link
Copy Markdown
Owner

Closes #472. Stacked on #475.

Do not merge until jvsena42/loopky.github.io#23 is deployed and this has been run on a device. See "Not verified".

What the spike found

  • SecAddSharedWebCredential still compiles against the current SDK and works: on a simulator it raises the system alert "Would you like to save this password in your iCloud Keychain…".
  • After saving, ASAuthorizationPasswordRequest raises the "Sign In" sheet naming the credential by the account's full pubky.
  • So the "permanent no" in IosPasswordManagerPresence was wrong for a domain-scoped credential. canSave() is now true.

What changed

  • PasswordManagerSheet.swift: save and read, no Kotlin binding, same split as SpeechListener.
  • Loopky.entitlements: webcredentials:loopky.app.
  • Backup menu card, the save button on the phrase screen, and the saved-phrase confirm step, all of which existed only on Android.
  • Restore menu's third card and the phrase screen's secondary button, matching Password manager: restore from it, and key the credential by pubky #475.
  • Thirteen strings in all eleven localizations. Twelve are ported from Android. backup_method_password_manager_detail is new copy naming Apple's Passwords app, because the Android text names Google Password Manager.

The shared ViewModels are unchanged.

Verification

  • xcodebuildmcp simulator build succeeds; ./gradlew lintSwift checkStringPlurals pass.
  • iPhone 17e simulator, signed in: backup menu shows the card; the save button appears after reveal; tapping it raises the save alert; "Save Password" is followed by the "Sign In" sheet for the right pubky.
  • iPad mini simulator, signed out: restore menu shows three cards; the manager card raises the read on entry, nothing is saved there, and the screen shows restore_phrase_manager_empty with the field editable.

Not verified

  • Accepting the "Sign In" sheet. It ignores synthetic input (snapshot-ui does not list it; AXe taps do nothing), so the verified state, the tick on the backup menu, the confirm step and a restore from a saved entry were not driven. It takes one tap by hand in the Simulator.
  • Anything on a device. The simulator saved while the live AASA has no webcredentials entry, so it does not enforce the association. A device does. Until the site PR is live and Apple's CDN has it, a device save should fail with backup_phrase_manager_failed.
  • Third-party managers (1Password, Bitwarden). The save goes to iCloud Keychain; whether the read sheet lists other providers is unknown. The card's copy says "Apple's Passwords app" for that reason.
  • A personal (free) team cannot sign Associated Domains at all; Config.xcconfig already says how to blank the entitlement.

journeys/28 has the device steps and journeys/README.md records the above.

🤖 Generated with Claude Code

@jvsena42
jvsena42 added this pull request to stack #477 October 8, 2026 23:45
@jvsena42 jvsena42 changed the title feat/ios password manager iOS: save the recovery phrase to Passwords, and restore from it Oct 8, 2026

@jvsena42 jvsena42 left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two findings, both needing a device or a hand on the Simulator to settle. The thirteen catalog keys exist in all eleven localizations and none carries a format specifier.

Comment thread iosApp/iosApp/Views/BackupPhraseScreen.swift
Comment thread iosApp/Configuration/Loopky.entitlements
@jvsena42
jvsena42 force-pushed the feat/ios-password-manager branch from 2ec251f to afaf126 Compare October 9, 2026 00:11
Base automatically changed from feat/password-manager-restore to main October 9, 2026 00:16
jvsena42 and others added 4 commits October 8, 2026 21:16
iOS withheld the password-manager backup on the reasoning that no API
writes an arbitrary secret into the Passwords app. That holds for an
arbitrary secret and not for a password belonging to a domain that names
the app, which loopky.app now can.

PasswordManagerSheet saves a loopky.app shared web credential under the
account's pubky and reads it back through the system's saved-password
sheet. The backup menu, phrase screen and confirm step gain what Android
has, and the restore menu gains the third card. The shared ViewModels are
unchanged: the Swift side answers the same effects.

The entitlement gains webcredentials:loopky.app. The site must list the
app under webcredentials before this works on a device; a simulator does
not enforce it.

Refs #472

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Refs #472

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
On iOS the save is two system prompts, and a signed-in user has a reason
to dismiss a sheet titled "Sign In". The read-back then returned nil and
the screen said nothing was saved while the entry sat in Passwords; a
retry saved again over it. Android has the same shape with its picker.

A failed read-back after a successful save is now its own state, with its
own line, and the next tap raises the check alone.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@jvsena42
jvsena42 force-pushed the feat/ios-password-manager branch from afaf126 to 002a2e6 Compare October 9, 2026 00:16
@jvsena42
jvsena42 marked this pull request as ready for review October 9, 2026 00:17
@jvsena42
jvsena42 merged commit b37edc8 into main Oct 9, 2026
11 checks passed
@jvsena42
jvsena42 deleted the feat/ios-password-manager branch October 9, 2026 00:23
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.

iOS: re-check password-manager backup now that loopky.app can carry webcredentials

1 participant