forked from synonymdev/bitkit-ios
-
Notifications
You must be signed in to change notification settings - Fork 0
fix: iOS Paykit/Pubky audit - complete security and architecture fixes #8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
BitcoinErrorLog
merged 18 commits into
paykit-integration-complete
from
fix/ios-paykit-phase1-thread-safety
Dec 31, 2025
Merged
fix: iOS Paykit/Pubky audit - complete security and architecture fixes #8
BitcoinErrorLog
merged 18 commits into
paykit-integration-complete
from
fix/ios-paykit-phase1-thread-safety
Dec 31, 2025
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Added prominent link to the comprehensive Bitkit + Paykit Integration Master Guide at the top of the README for production developers.
- Ed25519 master keys now owned exclusively by Pubky Ring - Bitkit only stores: public key, device ID, epoch, cached X25519 keypairs - Updated NoisePaymentService to use cached X25519 keypair - Updated PubkyRingIntegration to retrieve cached keys only BREAKING: Bitkit can no longer generate or derive keys locally. All key operations must go through Pubky Ring.
- Handle mode=secure_handoff callback from Ring - Fetch handoff payload from homeserver via PubkySDKService - Parse SecureHandoffPayload JSON structure - No secrets in callback URL - more secure against logging - Backward compatible with legacy mode
- PushRelayService stores tokens server-side, never publicly - Deprecate DirectoryService.publishPushNotificationEndpoint() - Deprecate DirectoryService.discoverPushNotificationEndpoint() - Includes registration, unregistration, and wake notification APIs - Rate limiting and signature authentication support
- HomeserverPubkey: z32 pubkey identifying a homeserver - HomeserverURL: resolved HTTPS URL for API requests - SessionSecret: secure wrapper for session credentials - OwnerPubkey: z32 pubkey identifying a user - HomeserverResolver: centralized URL resolution Prevents confusion between pubkeys and URLs in storage code.
- Use HomeserverURL and OwnerPubkey types in DirectoryService - Update PubkyStorageAdapter to accept HomeserverURL - Convert to String using .value property when needed
- Maintains cache of pubkey→URL resolutions with 1-hour TTL - Known homeservers map loaded on init - Supports custom mappings via addMapping() - Override support for testing/development - Prepares for future DNS-based resolution
- Delete handoff file from homeserver after successful retrieval - Minimizes attack window for encrypted payload - Uses background task to avoid blocking setup result
- Added requestSignature method to PubkyRingBridge - Added signature-result callback handler - Updated PushRelayService to use real Ed25519 signing - Removed placeholder signature implementation
- Added getOrRefreshKeypair method with auto-recovery - Automatically requests from Ring when cache is empty - Added getCurrentKeypairOrRefresh convenience method - Improves reliability when cache is cleared
- Added checkKeyRotation method to NoisePaymentService - Added setCurrentEpoch method to KeyManager - Supports manual rotation from epoch 0 to epoch 1 - Prepares for time-based automatic rotation
- F7: Add missing 'await' to signMessage call in PushRelayService - Remove unused useSecureHandoff parameter (Ring always uses secure handoff) - Update comments to accurately describe secure handoff behavior
- Deleted PushNotificationService.swift (unimplemented stub code) - PushRelayService is the active implementation for push notifications
Phase 1 of iOS Paykit/Pubky audit fixes: - PubkyRingBridge: Add NSLock with thread-safe cache helpers - SpendingLimitManager: Wrap all FFI methods with queue.sync - NoiseKeyCache: Use barrier sync for atomic read-check-write - DirectoryService: Replace force unwraps with guard let - PaykitManager: Remove force unwraps in executor registration
Phase 2 of iOS Paykit/Pubky audit fixes: - Add PaykitDeepLinkValidator for secure deep link validation - Validates scheme, host, required parameters - Enforces length limits and character constraints - Integrated into MainNavView.onOpenURL handler - Migrate PaykitReceiptStore from UserDefaults to Keychain - Receipts contain payment amounts and peer pubkeys - Now uses PaykitKeychainStorage for encrypted storage
Phase 3 of iOS Paykit/Pubky audit fixes: - Add AutoPayEvaluatorService for background-safe auto-pay evaluation - Non-MainActor service for use in BGTaskScheduler handlers - evaluateForBackground() treats biometric as needsApproval - Documented biometric policy for background payments - Add exponential backoff retry logic to SubscriptionBackgroundService - 3 retries with 5s initial delay, doubling each retry - Maximum delay capped at 60 seconds - Update AutoPayViewModel to delegate to evaluator service
Phase 4-5 of iOS Paykit/Pubky audit fixes: - Add PaykitNetworkConfig for shared URLSession configuration - Consistent timeouts (30s request, 60s resource) - HTTP/2 support and proper headers - URL caching disabled for sensitive payment data - Update PubkyStorageAdapter to use shared session - Update README with Thread Safety & Security section - Document thread-safe services and mechanisms - Document secure storage patterns - Document deep link validation usage - Document biometric policy for background payments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary
Complete iOS Paykit/Pubky SDK audit fixes (Phases 1-5 + Loose Ends) based on learnings from the Android integration audit.
Changes
Phase 1: Thread Safety & Force Unwrap Elimination
Thread Safety
sessionCacheandkeypairCachefrom race conditionsqueue.syncto ensure thread-safe access to the Rust FFI managergetKey()Force Unwrap Elimination
!) with properguard letpatterns when resolving homeserver URLsPhase 2: Security Improvements
Deep Link Validation
MainNavView.onOpenURLhandlerhost=payment-requestfor bothpaykit://andbitkit://schemesSecure Receipt Storage
PaykitKeychainStoragefor encrypted storage at restPhase 3: Background Service Improvements
AutoPay Evaluator Service
BGTaskSchedulerhandlersevaluateForBackground()treats biometric requirements as needs-approvalRetry Logic
autoPayStoragefield (dead code)ViewModel Integration
AutoPayEvaluatorServicefor evaluationPhase 4: Infrastructure
Shared Network Configuration
Phase 5: Documentation
Loose Ends Addressed
paykit://andbitkit://now requirehost=payment-requestautoPayStoragefrom SubscriptionBackgroundServiceTesting
Related
This is the iOS equivalent of the comprehensive audit fixes applied to the Android codebase.