Skip to content

feat: reuse Pubky Ring identities - #643

Draft
Jasonvdb wants to merge 5 commits into
masterfrom
codex/shared-pubky-ring
Draft

feat: reuse Pubky Ring identities#643
Jasonvdb wants to merge 5 commits into
masterfrom
codex/shared-pubky-ring

Conversation

@Jasonvdb

@Jasonvdb Jasonvdb commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Important

Dependencies and merge/release order

  1. Publish the final legacy Pubky Ring v1.17 sunset build.
  2. Merge the Bitkit parent UI stacks before their consumers: Bitkit iOS #636, and Bitkit Android #1084 followed by #1097.
  3. Complete the cross-repository release gates: provision the iOS shared Keychain group/profiles and confirm the Android Play-installed signing-certificate model.
  4. Merge and release Pubky Ring #342.
  5. Rebase and merge the consumer PRs, this PR and Bitkit Android #1109, onto their merged parents, then release them after Ring.

This branch is stacked on #636; the Android parent chain does not block this branch. At runtime, this PR and Ring #342 are counterparts: Ring-to-Bitkit requires Ring to ship first, while Ring's reverse “Use from Bitkit” flow becomes available after this consumer ships its Bitkit-owned shared record. This PR must remain draft until the Apple capability/profiles and signed two-app device tests are complete.

Part of #571

Description

This PR:

  1. Discovers source-owned Pubky Ring identities in a shared, non-synchronizing Keychain group and presents them in the redesigned Profile choice screen.
  2. Lets the user explicitly connect one Ring profile while retrieving its secret only just in time; Bitkit persists an app-private source reference and session, never the borrowed private key.
  3. Publishes Bitkit-owned Pubky identities for Ring without moving or deleting Bitkit's canonical private Keychain entry.
  4. Revalidates borrowed identities on launch, foreground, and authenticated operations, disconnecting locally when Ring or the source identity disappears.
  5. Serializes identity lifecycle changes and fails closed on source conflicts, malformed records, key mismatches, missing entitlements, and partial cleanup.

The shared protocol is versioned and uses a canonical 52-character bare Pubky plus a 64-character lowercase secret-key encoding. Shared records use WhenUnlockedThisDeviceOnly and are not synchronized through iCloud.

Migration is deliberately non-destructive: the existing app-private Keychain item remains canonical indefinitely, and the shared item is a replaceable access mirror. Reconciliation writes and reads back the current mirror before pruning stale Bitkit-owned mirrors. Explicit destructive flows remove and verify the mirror before touching private state; a shared deletion failure stops the private deletion.

The Pubky Ring URL scheme is only an availability hint. The shared Keychain entitlement, strict payload validation, and derived-public-key match are the trust boundary. A source-authenticated liveness handshake remains a follow-up hardening item.

Apple configuration is not available yet, which is safe for implementation and review: missing entitlement errors defer mirroring instead of migrating or deleting the private source. Shipping requires creating the shared Keychain group in App Store Connect, attaching it to both App IDs, regenerating provisioning profiles, and completing signed physical-device interoperability tests.

Linked Issues/Tasks

Screenshot / Video

An independent six-screen audit accounts for every supplied reference. The new Profile choice screen matches its reference with 97% certainty. The audit found and corrected a pre-existing FOUND CONTACTS copy/layout mismatch in Import Overview; its final native render is within 0–2 px of the measured reference. The other four screens remain unchanged parent implementations with matching static copy and structure. OS chrome and dynamic identity/avatar content are excluded.

QA Notes

Manual Tests

  • 1. Existing signed Pubky Ring install with profiles → Bitkit → Profile: each Ring profile appears beside Create Profile with the Figma layout.
  • 2. Profile → select a Ring profile: Bitkit connects that exact identity and continues to contact import without persisting its private key.
  • 3. Existing active or recoverable Bitkit profile → relaunch/update: no Ring profile silently replaces it, and the Bitkit-owned identity becomes available to Ring.
  • 4. Connected Ring profile → terminate and relaunch Bitkit: the session restores only while the same Ring identity remains available.
  • 5. Connected Ring profile → remove the identity from Ring or uninstall Ring → foreground Bitkit: Bitkit disconnects the borrowed identity locally.
  • 6. Existing pre-sharing Bitkit identity → update: the private Keychain source remains intact and the shared mirror is created only after validation.
  • 7. Delete profile or wipe wallet with a Bitkit-owned identity: the shared mirror disappears before private identity state is removed.
  • 8. regression: Borrowed Ring profile → approve Pubky Auth: approval retrieves and verifies the source key just in time.
  • 9. Build without the App Store Connect shared-Keychain capability: the app remains usable and leaves the private source untouched.

Automated Checks

  • SharedPubkyIdentityTests.swift: 22 tests cover wire validation, source ownership, credential matching, crash-safe adoption/cleanup, serialization, migration ordering, borrowed-secret persistence, and canonical pubkys beginning with pubky.
  • PubkyProfileManagerTests.swift: 38 focused profile/session tests pass, including restore and destructive migration failure cases.
  • Fresh local simulator run: all 60 selected tests pass with zero failures.
  • SwiftFormat lint, translation validation, plist/project validation, and git diff --check pass.
  • Fixture-free signed simulator build passes after the six-screen correction pass. Signed physical two-app validation remains blocked on App Store Connect capability and provisioning access.

@ovitrif
ovitrif force-pushed the codex/pubky-paykit-figma-alignment branch from d769ad1 to cc972d7 Compare July 27, 2026 15:54
Base automatically changed from codex/pubky-paykit-figma-alignment to master July 27, 2026 17:40
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