Prioritize user privacy and data security in your app. Discuss best practices for data handling, user consent, and security measures to protect user information.

Posts under General subtopic

Post

Replies

Boosts

Views

Activity

Call log
I read online that there is no way to extract the call log from an iPhone. I want to develop an app to help people remember to call their mom, and if they did, the "nagging" would disappear automatically. I'm looking for any workaround to know when a user called someone, without having them log it manually.
1
0
458
Dec ’25
iPhone + Safari + Passwords violates WebAuthn spec when pubKeyCredParams doesn't contain ES256
WebAuthn Level 3 § 6.3.2 Step 2 states the authenticator must : Check if at least one of the specified combinations of PublicKeyCredentialType and cryptographic parameters in credTypesAndPubKeyAlgs is supported. If not, return an error code equivalent to "NotSupportedError" and terminate the operation. On my iPhone 15 Pro Max running iOS 18.5, Safari + Passwords does not exhibit this behavior; instead an error is not reported and an ES256 credential is created when an RP passes a non-empty sequence that does not contain {"type":"public-key","alg":-7} (e.g., [{"type":"public-key","alg":-8}]). When I use Chromium 138.0.7204.92 on my laptop running Arch Linux in conjunction with the Passwords app (connected via the "hybrid" protocol), a credential is not created and instead an error is reported per the spec.
3
0
540
Jul ’25
DeviceCheck Framework Crash: DCAnalytics nil Dictionary Insertion in Production
We're experiencing crashes in our production iOS app related to Apple's DeviceCheck framework. The crash occurs in DCAnalytics internal performance tracking, affecting some specific versions of iOS 18 (18.4.1, 18.5.0). Crash Signature CoreFoundation: -[__NSDictionaryM setObject:forKeyedSubscript:] + 460 DeviceCheck: -[DCAnalytics sendPerformanceForCategory:eventType:] + 236 Observed Patterns Scenario 1 - Token Generation: Crashed: com.appQueue EXC_BAD_ACCESS KERN_INVALID_ADDRESS 0x0000000000000010 DeviceCheck: -[DCDevice generateTokenWithCompletionHandler:] Thread: Background dispatch queue Scenario 2 - Support Check: Crashed: com.apple.main-thread EXC_BAD_ACCESS KERN_INVALID_ADDRESS 0x0000000000000008 DeviceCheck: -[DCDevice _isSupportedReturningError:] DeviceCheck: -[DCDevice isSupported] Thread: Main thread Root Cause Analysis The DCAnalytics component within DeviceCheck attempts to insert a nil value into an NSMutableDictionary when recording performance metrics, indicating missing nil validation before dictionary operations. Reproduction Context Crashes occur during standard DeviceCheck API usage: Calling DCDevice.isSupported property Calling DCDevice.generateToken(completionHandler:) (triggered by Firebase App Check SDK) Both operations invoke internal analytics that fail with nil insertion attempts. Concurrency Considerations We've implemented sequential access guards around DeviceCheck token generation to prevent race conditions, yet crashes persist. This suggests the issue likely originates within the DeviceCheck framework's internal implementation rather than concurrent access from our application code. Note: Scenario 2 occurs through Firebase SDK's App Check integration, which internally uses DeviceCheck for attestation. Request Can Apple engineering confirm if this is a known issue with DeviceCheck's analytics subsystem? Is there a recommended workaround to disable DCAnalytics or ensure thread-safe DeviceCheck API usage? Any guidance on preventing these crashes would be appreciated.
0
2
256
Nov ’25
Validating Signature Of XPC Process
Quinn, you've often suggested that to validate the other side of an XPC connection, we should use the audit token. But that's not available from the XPC object, whereas the PID is. So everyone uses the PID. While looking for something completely unrelated, I found this in the SecCode.h file OSStatus SecCodeCreateWithXPCMessage(xpc_object_t message, SecCSFlags flags, SecCodeRef * __nonnull CF_RETURNS_RETAINED target); Would this be the preferred way to do this now? At least from 11.0 and up. Like I said, I was looking for something completely unrelated and found this and don't have the cycles right now to try it. But it looks promising from the description and I wanted to check in with you about it in case you can say yes or no before I get a chance to test it. Thanks
8
0
8.3k
Aug ’25
Binary executable requires Accessibility Permissions in Tahoe
I have a binary executable which needs to be given Accessibility Permissions so it can inject keypresses and mouse moves. This was always possible up to macOS 15 - when the first keypress arrived the Accessibility Permissions window would open and allow me to add the executable. However this no longer works in macOS 26: the window still opens, I navigate to the executable file and select it but it doesn't appear in the list. No error message appears. I'm guessing that this may be due to some tightening of security in Tahoe but I need to figure out what to change with my executable to allow it to work.
5
2
1k
Dec ’25
Invalid Persona Issue
Has anyone here encountered this? It's driving me crazy. It appears on launch. App Sandbox is enabled. The proper entitlement is selected (com.apple.security.files.user-selected.read-write) I believe this is causing an issue with app functionality for users on different machines. There is zero documentation across the internet on this problem. I am on macOS 26 beta. This error appears in both Xcode and Xcode-beta. Please help! Thank you, Logan
3
0
528
Jul ’25
Persistent Tokens for Keychain Unlock in Platform SSO
While working with Platform SSO on macOS, I’m trying to better understand how the system handles cases where a user’s local account password becomes unsynchronized with their Identity Provider (IdP) password—for example, when the device is offline during a password change. My assumption is that macOS may store some form of persistent token during the Platform SSO user registration process (such as a certificate or similar credential), and that this token could allow the system to unlock the user’s login keychain even if the local password no longer matches the IdP password. I’m hoping to get clarification on the following: Does macOS actually use a persistent token to unlock the login keychain when the local account password is out of sync with the IdP password? If so, how is that mechanism designed to work? If such a capability exists, is it something developers can leverage to enable a true passwordless authentication experience at the login window and lock screen (i.e., avoiding the need for a local password fallback)? I’m trying to confirm what macOS officially supports so I can understand whether passwordless login is achievable using the persistent-token approach. Thanks in advance for any clarification.
1
3
327
Dec ’25
Using provision profile to access assessments triggers a keychain popup
Hello! I do know apple does not support electron, but I do not think this is an electron related issue, rather something I am doing wrong. I'd be curious to find out why the keychain login is happenning after my app has been signed with the bundleid, entitlements, and provision profile. Before using the provision profile I did not have this issue, but it is needed for assessments feature. I'm trying to ship an Electron / macOS desktop app that must run inside Automatic Assessment Configuration. The build signs and notarizes successfully, and assessment mode itself starts on Apple-arm64 machines, but every single launch shows the system dialog that asks to allow access to the "login" keychain. The dialog appears on totally fresh user accounts, so it's not tied to anything I store there. It has happened ever since I have added the provision profile to the electron builder to finally test assessment out. entitlements.inherit.plist keys <key>com.apple.security.cs.allow-jit</key> <true/> <key>com.apple.security.cs.allow-unsigned-executable-memory</key> <true/> entitlements.plist keys: <key>com.apple.security.cs.allow-jit</key> <true/> <key>com.apple.security.cs.allow-unsigned-executable-memory</key> <true/> <key>com.apple.developer.automatic-assessment-configuration</key> <true/> I'm honestly not sure whether the keychain is expected, but I have tried a lot of entitlement combinations to get rid of It. Electron builder is doing the signing, and we manually use the notary tool to notarize but probably irrelevant. mac: { notarize: false, target: 'dir', entitlements: 'buildResources/entitlements.mac.plist', provisioningProfile: 'buildResources/xyu.provisionprofile', entitlementsInherit: 'buildResources/entitlements.mac.inherit.plist', Any lead is welcome!
2
0
151
Jun ’25
Unexpected errSecInteractionNotAllowed (-25308) When Reading Keychain Item with kSecAttrAccessibleAfterFirstUnlock in Background
Hi everyone, I’m encountering an unexpected Keychain behavior in a production environment and would like to confirm whether this is expected or if I’m missing something. In my app, I store a deviceId in the Keychain based on the classic KeychainItemWrapper implementation. I extended it by explicitly setting: kSecAttrAccessible = kSecAttrAccessibleAfterFirstUnlock My understanding is that kSecAttrAccessibleAfterFirstUnlock should allow Keychain access while the app is running in the background, as long as the device has been unlocked at least once after reboot. However, after the app went live, I observed that when the app performs background execution (e.g., triggered by background tasks / silent push), Keychain read attempts intermittently fail with: errSecInteractionNotAllowed (-25308) This seems inconsistent with the documented behavior of kSecAttrAccessibleAfterFirstUnlock. Additional context: The issue never occurs in foreground. The issue does not appear on development devices. User devices are not freshly rebooted when this happens. The Keychain item is created successfully; only background reads fail. Setting the accessibility to kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly produces the same result. Questions: Under what circumstances can kSecAttrAccessibleAfterFirstUnlock still cause a -25308 error? Is there any known restriction when accessing Keychain while the app is running in background execution contexts? Could certain system states (Low Power Mode, Background App Refresh conditions, device lock state, etc.) cause Keychain reads to be blocked unexpectedly? Any insights or similar experiences would be greatly appreciated. Thank you!
3
0
719
Dec ’25
What is the code signing trust level?
In some crashlog files, there are additional pieces of information related to codesigning. I can understand what most of themcorresponds to (ID, TeamID, Flags, Validation Category). But there is one I have some doubt about: Trust Level. As far as I can tell (or at least what Google and other search engines say), this is an unsigned 32 bit integer that defines the trust level with -1 being untrusted, 0, being basically an Apple executable and other potential bigger values corresponding to App Store binaries, Developer ID signature, etc. Yet, I'm not able to find a corresponding detailed documentation about this on Apple's developer website. I also had a look at the LightweightCodeRequirements "include" file and there does not seem to be such a field available. [Q] Is there any official documentation listing the different values for this trust level value and providing a clear description of what it corresponds to?
4
0
367
Jul ’25
Why won't my AutoFill Credential Provider show up in the context menu of a generic textfield?
I noticed, that even though my AutoFill Credential Provider Extension works with Safari for both Passwords and Passkeys, it doesn't work in context menus inside arbitrary textfields, meanwhile the same is true for the Apple Passwords app. This is a great hit to AutoFill productivity, as my extension is unable to fill textfields by just going to the context menu and clicking AutoFill > Passwords.. Is this a feature only available to Apple via private APIs, or is this something I can interface with? I checked and the Passwords app does use some undocumented but non-private entitlements: [Key] com.apple.authentication-services.access-credential-identities [Value] [Bool] true I also checked the responsible executable for some hints (AutoFillPanelService) however found nothing that would lead me to believe this is a public extension point. Another idea I had was trying to use a macOS Service for this, however Services in the "General" category won't show up in any context menu, only in the Application's Main Menu.
0
1
154
Dec ’25
How to reset user preference for crypto token kit access
When an app is trying to access identities put in the keychain by cryptotokenkit extension, the user gets asked a permission pop-up which reads 'Token Access Request" would like access a token provided by: " with 2 options 'Don't allow' and 'OK' I accidently clicked "Don't allow" and now can't access identities put in crypto token kit. How can I reset the preference?
11
0
1.6k
2w
ASPasswordCredential Returns a Blank Password with Apple Password App
Using the simplified sign-in with tvOS and a third party password manager, I receive a complete ASPasswordCredential, and I can easily log into my app. When I do the same thing but with Apple's password manager as the source, I receive an ASPasswordCredential that includes the email address, but the password is an empty string. I have tried deleting the credentials from Apple Passwords and regenerating them with a new login to the app's website. I have tried restarting my iPhone. Is this the expected behavior? How should I be getting a password from Apple's Password app with an ASAuthorizationPasswordRequest?
2
0
334
Aug ’25
Mark the iOS app content not to be backed up when doing unencrypted backup in iTunes
Hi,is there an option to mark the file or folder or item stored in user defaults ... not to be backed up when doing unencrypted backup in iTunes?We are developing iOS app that contains sensitive data. But even if we enable Data Protection for the iOS app it can be backed up on mac unencrypted using iTunes. Is there a way to allow backing up content only if the backup is encrypted?
2
0
1.8k
Oct ’25
App ID Prefix Change and Keychain Access
DTS regularly receives questions about how to preserve keychain items across an App ID change, and so I thought I’d post a comprehensive answer here for the benefit of all. If you have any questions or comments, please start a new thread here on the forums. Put it in the Privacy & Security > General subtopic and tag it with Security. Share and Enjoy — Quinn “The Eskimo!” @ Developer Technical Support @ Apple let myEmail = "eskimo" + "1" + "@" + "apple.com" App ID Prefix Change and Keychain Access The list of keychain access groups your app can access is determined by three entitlements. For the details, see Sharing Access to Keychain Items Among a Collection of Apps. If your app changes its App ID prefix, this list changes and you’re likely to lose access to existing keychain items. This situation crops up under two circumstances: When you migrate your app from using a unique App ID prefix to using your Team ID as its App ID prefix. When you transfer your app to another team. In both cases you have to plan carefully for this change. If you only learn about the problem after you’ve made the change, consider undoing the change to give you time to come up with a plan before continuing. Note On macOS, the information in this post only applies to the data protection keychain. For more information about the subtleties of the keychain on macOS, see On Mac Keychains. For more about App ID prefix changes, see Technote 2311 Managing Multiple App ID Prefixes and QA1726 Resolving the Potential Loss of Keychain Access warning. Migrate From a Unique App ID Prefix to Your Team ID Historically each app was assigned its own App ID prefix. This is no longer the case. Best practice is for apps to use their Team ID as their App ID prefix. This enables multiple neat features, including keychain item sharing and pasteboard sharing. If you have an app that uses a unique App ID prefix, consider migrating it to use your Team ID. This is a good thing in general, as long as you manage the migration process carefully. Your app’s keychain access group list is built from three entitlements: keychain-access-groups — For more on this, see Keychain Access Groups Entitlement. application-identifier (com.apple.application-identifier on macOS) com.apple.security.application-groups — For more on this, see App Groups Entitlement. Keycahin access groups from the third bullet are call app group identified keychain access groups, or AGI keychain access groups for short. IMPORTANT A macOS app can only use an AGI keychain access group if all of its entitlement claims are validated by a provisioning profile. See App Groups: macOS vs iOS: Working Towards Harmony for more about this concept. Keychain access groups from the first two bullets depend on the App ID prefix. If that changes, you lose access to any keychain items in those groups. WARNING Think carefully before using the keychain to store secrets that are the only way to access irreplaceable user data. While the keychain is very reliable, there are situations where a keychain item can be lost and it’s bad if it takes the user’s data with it. In some cases losing access to keychain items is not a big deal. For example, if your app uses the keychain to manage a single login credential, losing that is likely to be acceptable. The user can recover by logging in again. In other cases losing access to keychain items is unacceptable. For example, your app might manage access to dozens of different servers, each with unique login credentials. Your users will be grumpy if you require them to log in to all those servers again. In such situations you must carefully plan your migration. The key thing to understand is that an app group is tied to your team, not your App ID prefix, and thus your app retains access to AGI keychain access groups across an App ID prefix change. This suggests the following approach: Release a version of your app that moves keychain items from other keychain access groups to an AGI keychain access group. Give your users time to update to this new version, run it, and so move their keychain items. When you’re confident that the bulk of your users have done this, change your App ID prefix. The approach has one obvious caveat: It’s hard to judge how long to wait at step 2. Transfer Your App to Another Team Historically there was no supported way to maintain access to keychain items across an app transfer. That’s no longer the case, but you must still plan the transfer carefully. The overall approach is: Identify an app group ID to transfer. This could be an existing app group ID, but in many cases you’ll want to register a new app group ID solely for this purpose. Use the old team (the transferor) to release a version of your app that moves keychain items from other keychain access groups to the AGI keychain access group for this app group ID. Give your users time to update to this new version, run it, and so move their keychain items. When you’re confident that the bulk of your users have done this, initiate the app transfer. Once that’s complete, transfer the app group ID you selected in step 1. See App Store Connect Help > Transfer an app > Overview of app transfer > Apps using App Groups. Publish an update to your app from the new team (the transferee). When a user installs this version, it will have access to your app group, and hence your keychain items. WARNING Once you transfer the app group, the old team won’t be able to publish a new version of any app that uses this app group. That makes step 1 in the process critical. If you have an existing app group that’s used solely by the app being transferred — for example, an app group that you use to share state between the app and its app extensions — then choosing that app group ID makes sense. On the other hand, choosing the ID of an app group that’s share between this app and some unrelated app, one that’s not being transferred, would be bad, because any updates to that other app will lose access to the app group. There are some other significant caveats: The process doesn’t work for Mac apps because Mac apps that have ever used an app group can’t be transferred. See App Store Connect Help > Transfer an app > App transfer criteria. If and when that changes, you’ll need to choose an iOS-style app group ID for your AGI keychain access group. For more about the difference between iOS- and macOS-style app group IDs, see App Groups: macOS vs iOS: Working Towards Harmony. The current transfer process of app groups exposes a small window where some other team can ‘steal’ your app group ID. We have a bug on file to improve that process (r. 171616887). The process works best when transferring between two teams that are both under the control of the same entity. If that’s not the case, take steps to ensure that the old team transfers the app group in step 5. When you submit the app from the new team (step 6), App Store Connect will warn you about a potential loss of keychain access. That warning is talking about keychain items in normal keychain access groups. Items in an AGI keychain access group will still be accessible as long as you transfer the app group. Alternative Approaches for App Transfer In addition to the technique described in the previous section, there are a some alternative approaches you should at consider: Do nothing Do not transfer your app Get creative Do Nothing In this case the user loses all the secrets that your app stored in the keychain. This may be acceptable for certain apps. For example, if your app uses the keychain to manage a single login credential, losing that is likely to be acceptable. The user can recover by logging in again. Do Not Transfer Another option is to not transfer your app. Instead, ship a new version of the app from the new team and have the old app recommend that the user upgrade. There are a number of advantages to this approach. The first is that there’s absolutely no risk of losing any user data. The two apps are completely independent. The second advantage is that the user can install both apps on their device at the same time. This opens up a variety of potential migration paths. For example, you might ship an update to the old app with an export feature that saves the user’s state, including their secrets, to a suitably encrypted file, and then match that with an import facility on the new app. Finally, this approach offers flexible timing. The user can complete their migration at their leisure. However, there are a bunch of clouds to go with these silver linings: Your users might never migrate to the new app. If this is a paid app, or an app with in-app purchase, the user will have to buy things again. You lose the original app’s history, ratings, reviews, and so on. Get Creative Finally, you could attempt something creative. For example, you might: Publish a new version of the app that supports exporting the user’s state, including the secrets. Tell your users to do this, with a deadline. Transfer the app and then, when the deadline expires, publish the new version with an import feature. Frankly, this isn’t very practical. The problem is with step 2: There’s no good way to get all your users to do the export, and if they don’t do it before the deadline there’s no way to do it after. Test Before You Ship Once you have a new version of your app, with the new App ID prefix, it’s time to test. To run a day-to-day test: On a test device, install the existing version of the app from the App Store. Use the app to generate keychain items as a normal user would. For example, if you store login credentials in the keychain, use the app to save such a credential. In Xcode, run the new version of your app. Check that the keychain items you created in step 2 still work. After you upload this new version to App Store Connect, use TestFlight to run an internal test: On a test device, install the existing version of the app from the App Store. Use the app to generate keychain items as a normal user. For example, if you store login credentials in the keychain, use the app to save such a credential. Use TestFlight to update the app to your new version. Check that the keychain items you created in step 2 still work. Do this before you release the app to your beta testers and then again before releasing it to customers. WARNING These TestFlight test are your last chance to ensure that everything works. If you detect an error at this stage, you still have a chance to fix it. Revision History 2026-04-07 Added the Test Before You Ship section. 2026-03-31 Rewrote the Transfer Your App to Another Team section to describe a new approach for preserving access to keychain items across app transfers. Moved the previous discussion into a new Alternative Approaches for App Transfer section. Clarified that a macOS program can now use an app group as a keychain access group as long as its entitlements are validated. Made numerous editorial changes. 2022-05-17 First posted.
0
0
8.8k
Apr ’26
ASWebAuthenticationSession crash after window closes on macOS
I'm trying to use ASWebAuthenticationSession on macOS but there is a weird crash and I have no idea what to do. It looks like there is a main thread check in a framework code that I have no control over. Any help would be appreciated. Thank you in advance. The stack of crashed thread has no symbols, even for supposedly my code in OAuthClient.authenticate. macOS 15.4.1 (24E263) Xcode Version 16.3 (16E140) Thread 11: EXC_BREAKPOINT (code=1, subcode=0x10039bb04) Thread 12 Queue : com.apple.NSXPCConnection.m-user.com.apple.SafariLaunchAgent (serial) #0 0x0000000100b17b04 in _dispatch_assert_queue_fail () #1 0x0000000100b52834 in dispatch_assert_queue$V2.cold.1 () #2 0x0000000100b17a88 in dispatch_assert_queue () #3 0x000000027db5f3e8 in swift_task_isCurrentExecutorWithFlagsImpl () #4 0x00000001022c7754 in closure #1 in closure #1 in OAuthClient.authenticate() () #5 0x00000001022d0c98 in thunk for @escaping @callee_guaranteed (@in_guaranteed URL?, @guaranteed Error?) -> () () #6 0x00000001c7215a34 in __102-[ASWebAuthenticationSession initWithURL:callback:usingEphemeralSession:jitEnabled:completionHandler:]_block_invoke () #7 0x00000001c72163d0 in -[ASWebAuthenticationSession _endSessionWithCallbackURL:error:] () #8 0x00000001c7215fc0 in __43-[ASWebAuthenticationSession _startDryRun:]_block_invoke_2 () #9 0x0000000194e315f4 in __invoking___ () #10 0x0000000194e31484 in -[NSInvocation invoke] () #11 0x00000001960fd644 in __NSXPCCONNECTION_IS_CALLING_OUT_TO_REPLY_BLOCK__ () #12 0x00000001960fbe40 in -[NSXPCConnection _decodeAndInvokeReplyBlockWithEvent:sequence:replyInfo:] () #13 0x00000001960fb798 in __88-[NSXPCConnection _sendInvocation:orArguments:count:methodSignature:selector:withProxy:]_block_invoke_3 () #14 0x0000000194a6ef18 in _xpc_connection_reply_callout () #15 0x0000000194a6ee08 in _xpc_connection_call_reply_async () #16 0x0000000100b3130c in _dispatch_client_callout3_a () #17 0x0000000100b362f8 in _dispatch_mach_msg_async_reply_invoke () #18 0x0000000100b1d3a8 in _dispatch_lane_serial_drain () #19 0x0000000100b1e46c in _dispatch_lane_invoke () #20 0x0000000100b2bfbc in _dispatch_root_queue_drain_deferred_wlh () #21 0x0000000100b2b414 in _dispatch_workloop_worker_thread () #22 0x0000000100c0379c in _pthread_wqthread () My code: @MainActor func authenticate() async throws { let authURL = api.authorizationURL( scopes: scopes, state: state, redirectURI: redirectURI ) let authorizationCodeURL: URL = try await withUnsafeThrowingContinuation { c in let session = ASWebAuthenticationSession(url: authURL, callback: .customScheme(redirectScheme)) { url, error in guard let url = url else { c.resume(throwing: error ?? Error.unknownError("Failed to get authorization code")) return } c.resume(returning: url) } session.presentationContextProvider = presentationContextProvider session.start() } let authorizationCode = try codeFromAuthorizationURL(authorizationCodeURL) (storedAccessToken, storedRefreshToken) = try await getTokens(authorizationCode: authorizationCode) } Here is disassembly of the crashed function. libdispatch.dylib`_dispatch_assert_queue_fail: 0x10067fa8c <+0>: pacibsp 0x10067fa90 <+4>: sub sp, sp, #0x50 0x10067fa94 <+8>: stp x20, x19, [sp, #0x30] 0x10067fa98 <+12>: stp x29, x30, [sp, #0x40] 0x10067fa9c <+16>: add x29, sp, #0x40 0x10067faa0 <+20>: adrp x8, 71 0x10067faa4 <+24>: add x8, x8, #0x951 ; "not " 0x10067faa8 <+28>: adrp x9, 70 0x10067faac <+32>: add x9, x9, #0x16b ; "" 0x10067fab0 <+36>: stur xzr, [x29, #-0x18] 0x10067fab4 <+40>: cmp w1, #0x0 0x10067fab8 <+44>: csel x8, x9, x8, ne 0x10067fabc <+48>: ldr x10, [x0, #0x48] 0x10067fac0 <+52>: cmp x10, #0x0 0x10067fac4 <+56>: csel x9, x9, x10, eq 0x10067fac8 <+60>: stp x9, x0, [sp, #0x10] 0x10067facc <+64>: adrp x9, 71 0x10067fad0 <+68>: add x9, x9, #0x920 ; "BUG IN CLIENT OF LIBDISPATCH: Assertion failed: " 0x10067fad4 <+72>: stp x9, x8, [sp] 0x10067fad8 <+76>: adrp x1, 71 0x10067fadc <+80>: add x1, x1, #0x8eb ; "%sBlock was %sexpected to execute on queue [%s (%p)]" 0x10067fae0 <+84>: sub x0, x29, #0x18 0x10067fae4 <+88>: bl 0x1006c258c ; symbol stub for: asprintf 0x10067fae8 <+92>: ldur x19, [x29, #-0x18] 0x10067faec <+96>: str x19, [sp] 0x10067faf0 <+100>: adrp x0, 71 0x10067faf4 <+104>: add x0, x0, #0x956 ; "%s" 0x10067faf8 <+108>: bl 0x1006b7b64 ; _dispatch_log 0x10067fafc <+112>: adrp x8, 108 0x10067fb00 <+116>: str x19, [x8, #0x2a8] -> 0x10067fb04 <+120>: brk #0x1
1
0
171
May ’25
DCError.invalidInput on generateAssertion() - Affecting Small Subset of Users
Issue Summary I'm encountering a DCError.invalidInput error when calling DCAppAttestService.shared.generateAssertion() in my App Attest implementation. This issue affects only a small subset of users - the majority of users can successfully complete both attestation and assertion flows without any issues. According to Apple Engineer feedback, there might be a small implementation issue in my code. Key Observations Success Rate: ~95% of users complete the flow successfully Failure Pattern: The remaining ~5% consistently fail at assertion generation Key Length: Logs show key length of 44 characters for both successful and failing cases Consistency: Users who experience the error tend to experience it consistently Platform: Issue observed across different iOS versions and device types Environment iOS App Attest implementation Using DCAppAttestService for both attestation and assertion Custom relying party server communication Issue affects ~5% of users consistently Key Implementation Details 1. Attestation Flow (Working) The attestation process works correctly: // Generate key and attest (successful for all users) self.attestService.generateKey { keyId, keyIdError in guard keyIdError == nil, let keyId = keyId else { return completionHandler(.failure(.dcError(keyIdError as! DCError))) } // Note: keyId length is consistently 44 characters for both successful and failing users // Attest key with Apple servers self.attestKey(keyId, clientData: clientData) { result in // ... verification with RP server // Key is successfully stored for ALL users (including those who later fail at assertion) } } 2. Assertion Flow (Failing for ~5% of Users with invalidInput) The assertion generation fails for a consistent subset of users: // Get assertion data from RP server self.assertRelyingParty.getAssertionData(kid, with: data) { result in switch result { case .success(let receivedData): let session = receivedData.session let clientData = receivedData.clientData let hash = clientData.toSHA256() // SHA256 hash of client data // THIS CALL FAILS WITH invalidInput for ~5% of users // Same keyId (44 chars) that worked for attestation self.attestService.generateAssertion(kid, clientDataHash: hash) { assertion, err in guard err == nil, let assertion = assertion else { // Error: DCError.invalidInput if let err = err as? DCError, err.code == .invalidKey { return reattestAndAssert(.invalidKey, completionHandler) } else { return completionHandler(.failure(.dcError(err as! DCError))) } } // ... verification logic } } } 3. Client Data Structure Client data JSON structure (identical for successful and failing users): // For attestation (works for all users) let clientData = ["challenge": receivedData.challenge] // For assertion (fails for ~5% of users with same structure) var clientData = ["challenge": receivedData.challenge] if let data = data { // Additional data for assertion clientData["account"] = data["account"] clientData["amount"] = data["amount"] } 4. SHA256 Hash Implementation extension Data { public func toSHA256() -> Data { return Data(SHA256.hash(data: self)) } } 5. Key Storage Implementation Using UserDefaults for key storage (works consistently for all users): private let keyStorageTag = "app-attest-keyid" func setKey(_ keyId: String) -> Result<(), KeyStorageError> { UserDefaults.standard.set(keyId, forKey: keyStorageTag) return .success(()) } func getKey() -> Result<String?, KeyStorageError> { let keyId = UserDefaults.standard.string(forKey: keyStorageTag) return .success(keyId) } Questions User-Specific Factors: Since this affects only ~5% of users consistently, could there be device-specific, iOS version-specific, or account-specific factors that cause invalidInput? Key State Validation: Is there any way to validate the state of an attested key before calling generateAssertion()? The key length (44 chars) appears normal for both successful and failing cases. Keychain vs UserDefaults: Could the issue be related to using UserDefaults instead of Keychain for key storage? Though this works for 95% of users. Race Conditions: Could there be subtle race conditions or timing issues that only affect certain users/devices? Error Recovery: Is there a recommended way to handle this error? Should we attempt re-attestation for these users? Additional Context & Debugging Attempts Consistent Failure: Users who experience this error typically experience it on every attempt Key Validation: Both successful and failing users have identical key formats (44 character strings) Device Diversity: Issue observed across different device models and iOS versions Server Logs: Our server successfully provides challenges and processes attestation for all users Re-attestation: Forcing re-attestation sometimes resolves the issue temporarily, but it often recurs The fact that 95% of users succeed with identical code suggests there might be some environmental or device-specific factor that we're not accounting for. Any insights into what could cause invalidInput for a subset of users would be invaluable.
2
0
534
Jun ’25
Call log
I read online that there is no way to extract the call log from an iPhone. I want to develop an app to help people remember to call their mom, and if they did, the "nagging" would disappear automatically. I'm looking for any workaround to know when a user called someone, without having them log it manually.
Replies
1
Boosts
0
Views
458
Activity
Dec ’25
iPhone + Safari + Passwords violates WebAuthn spec when pubKeyCredParams doesn't contain ES256
WebAuthn Level 3 § 6.3.2 Step 2 states the authenticator must : Check if at least one of the specified combinations of PublicKeyCredentialType and cryptographic parameters in credTypesAndPubKeyAlgs is supported. If not, return an error code equivalent to "NotSupportedError" and terminate the operation. On my iPhone 15 Pro Max running iOS 18.5, Safari + Passwords does not exhibit this behavior; instead an error is not reported and an ES256 credential is created when an RP passes a non-empty sequence that does not contain {"type":"public-key","alg":-7} (e.g., [{"type":"public-key","alg":-8}]). When I use Chromium 138.0.7204.92 on my laptop running Arch Linux in conjunction with the Passwords app (connected via the "hybrid" protocol), a credential is not created and instead an error is reported per the spec.
Replies
3
Boosts
0
Views
540
Activity
Jul ’25
DeviceCheck Framework Crash: DCAnalytics nil Dictionary Insertion in Production
We're experiencing crashes in our production iOS app related to Apple's DeviceCheck framework. The crash occurs in DCAnalytics internal performance tracking, affecting some specific versions of iOS 18 (18.4.1, 18.5.0). Crash Signature CoreFoundation: -[__NSDictionaryM setObject:forKeyedSubscript:] + 460 DeviceCheck: -[DCAnalytics sendPerformanceForCategory:eventType:] + 236 Observed Patterns Scenario 1 - Token Generation: Crashed: com.appQueue EXC_BAD_ACCESS KERN_INVALID_ADDRESS 0x0000000000000010 DeviceCheck: -[DCDevice generateTokenWithCompletionHandler:] Thread: Background dispatch queue Scenario 2 - Support Check: Crashed: com.apple.main-thread EXC_BAD_ACCESS KERN_INVALID_ADDRESS 0x0000000000000008 DeviceCheck: -[DCDevice _isSupportedReturningError:] DeviceCheck: -[DCDevice isSupported] Thread: Main thread Root Cause Analysis The DCAnalytics component within DeviceCheck attempts to insert a nil value into an NSMutableDictionary when recording performance metrics, indicating missing nil validation before dictionary operations. Reproduction Context Crashes occur during standard DeviceCheck API usage: Calling DCDevice.isSupported property Calling DCDevice.generateToken(completionHandler:) (triggered by Firebase App Check SDK) Both operations invoke internal analytics that fail with nil insertion attempts. Concurrency Considerations We've implemented sequential access guards around DeviceCheck token generation to prevent race conditions, yet crashes persist. This suggests the issue likely originates within the DeviceCheck framework's internal implementation rather than concurrent access from our application code. Note: Scenario 2 occurs through Firebase SDK's App Check integration, which internally uses DeviceCheck for attestation. Request Can Apple engineering confirm if this is a known issue with DeviceCheck's analytics subsystem? Is there a recommended workaround to disable DCAnalytics or ensure thread-safe DeviceCheck API usage? Any guidance on preventing these crashes would be appreciated.
Replies
0
Boosts
2
Views
256
Activity
Nov ’25
Validating Signature Of XPC Process
Quinn, you've often suggested that to validate the other side of an XPC connection, we should use the audit token. But that's not available from the XPC object, whereas the PID is. So everyone uses the PID. While looking for something completely unrelated, I found this in the SecCode.h file OSStatus SecCodeCreateWithXPCMessage(xpc_object_t message, SecCSFlags flags, SecCodeRef * __nonnull CF_RETURNS_RETAINED target); Would this be the preferred way to do this now? At least from 11.0 and up. Like I said, I was looking for something completely unrelated and found this and don't have the cycles right now to try it. But it looks promising from the description and I wanted to check in with you about it in case you can say yes or no before I get a chance to test it. Thanks
Replies
8
Boosts
0
Views
8.3k
Activity
Aug ’25
Binary executable requires Accessibility Permissions in Tahoe
I have a binary executable which needs to be given Accessibility Permissions so it can inject keypresses and mouse moves. This was always possible up to macOS 15 - when the first keypress arrived the Accessibility Permissions window would open and allow me to add the executable. However this no longer works in macOS 26: the window still opens, I navigate to the executable file and select it but it doesn't appear in the list. No error message appears. I'm guessing that this may be due to some tightening of security in Tahoe but I need to figure out what to change with my executable to allow it to work.
Replies
5
Boosts
2
Views
1k
Activity
Dec ’25
Invalid Persona Issue
Has anyone here encountered this? It's driving me crazy. It appears on launch. App Sandbox is enabled. The proper entitlement is selected (com.apple.security.files.user-selected.read-write) I believe this is causing an issue with app functionality for users on different machines. There is zero documentation across the internet on this problem. I am on macOS 26 beta. This error appears in both Xcode and Xcode-beta. Please help! Thank you, Logan
Replies
3
Boosts
0
Views
528
Activity
Jul ’25
Persistent Tokens for Keychain Unlock in Platform SSO
While working with Platform SSO on macOS, I’m trying to better understand how the system handles cases where a user’s local account password becomes unsynchronized with their Identity Provider (IdP) password—for example, when the device is offline during a password change. My assumption is that macOS may store some form of persistent token during the Platform SSO user registration process (such as a certificate or similar credential), and that this token could allow the system to unlock the user’s login keychain even if the local password no longer matches the IdP password. I’m hoping to get clarification on the following: Does macOS actually use a persistent token to unlock the login keychain when the local account password is out of sync with the IdP password? If so, how is that mechanism designed to work? If such a capability exists, is it something developers can leverage to enable a true passwordless authentication experience at the login window and lock screen (i.e., avoiding the need for a local password fallback)? I’m trying to confirm what macOS officially supports so I can understand whether passwordless login is achievable using the persistent-token approach. Thanks in advance for any clarification.
Replies
1
Boosts
3
Views
327
Activity
Dec ’25
Using provision profile to access assessments triggers a keychain popup
Hello! I do know apple does not support electron, but I do not think this is an electron related issue, rather something I am doing wrong. I'd be curious to find out why the keychain login is happenning after my app has been signed with the bundleid, entitlements, and provision profile. Before using the provision profile I did not have this issue, but it is needed for assessments feature. I'm trying to ship an Electron / macOS desktop app that must run inside Automatic Assessment Configuration. The build signs and notarizes successfully, and assessment mode itself starts on Apple-arm64 machines, but every single launch shows the system dialog that asks to allow access to the "login" keychain. The dialog appears on totally fresh user accounts, so it's not tied to anything I store there. It has happened ever since I have added the provision profile to the electron builder to finally test assessment out. entitlements.inherit.plist keys &lt;key&gt;com.apple.security.cs.allow-jit&lt;/key&gt; &lt;true/&gt; &lt;key&gt;com.apple.security.cs.allow-unsigned-executable-memory&lt;/key&gt; &lt;true/&gt; entitlements.plist keys: &lt;key&gt;com.apple.security.cs.allow-jit&lt;/key&gt; &lt;true/&gt; &lt;key&gt;com.apple.security.cs.allow-unsigned-executable-memory&lt;/key&gt; &lt;true/&gt; &lt;key&gt;com.apple.developer.automatic-assessment-configuration&lt;/key&gt; &lt;true/&gt; I'm honestly not sure whether the keychain is expected, but I have tried a lot of entitlement combinations to get rid of It. Electron builder is doing the signing, and we manually use the notary tool to notarize but probably irrelevant. mac: { notarize: false, target: 'dir', entitlements: 'buildResources/entitlements.mac.plist', provisioningProfile: 'buildResources/xyu.provisionprofile', entitlementsInherit: 'buildResources/entitlements.mac.inherit.plist', Any lead is welcome!
Replies
2
Boosts
0
Views
151
Activity
Jun ’25
Unexpected errSecInteractionNotAllowed (-25308) When Reading Keychain Item with kSecAttrAccessibleAfterFirstUnlock in Background
Hi everyone, I’m encountering an unexpected Keychain behavior in a production environment and would like to confirm whether this is expected or if I’m missing something. In my app, I store a deviceId in the Keychain based on the classic KeychainItemWrapper implementation. I extended it by explicitly setting: kSecAttrAccessible = kSecAttrAccessibleAfterFirstUnlock My understanding is that kSecAttrAccessibleAfterFirstUnlock should allow Keychain access while the app is running in the background, as long as the device has been unlocked at least once after reboot. However, after the app went live, I observed that when the app performs background execution (e.g., triggered by background tasks / silent push), Keychain read attempts intermittently fail with: errSecInteractionNotAllowed (-25308) This seems inconsistent with the documented behavior of kSecAttrAccessibleAfterFirstUnlock. Additional context: The issue never occurs in foreground. The issue does not appear on development devices. User devices are not freshly rebooted when this happens. The Keychain item is created successfully; only background reads fail. Setting the accessibility to kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly produces the same result. Questions: Under what circumstances can kSecAttrAccessibleAfterFirstUnlock still cause a -25308 error? Is there any known restriction when accessing Keychain while the app is running in background execution contexts? Could certain system states (Low Power Mode, Background App Refresh conditions, device lock state, etc.) cause Keychain reads to be blocked unexpectedly? Any insights or similar experiences would be greatly appreciated. Thank you!
Replies
3
Boosts
0
Views
719
Activity
Dec ’25
What is the code signing trust level?
In some crashlog files, there are additional pieces of information related to codesigning. I can understand what most of themcorresponds to (ID, TeamID, Flags, Validation Category). But there is one I have some doubt about: Trust Level. As far as I can tell (or at least what Google and other search engines say), this is an unsigned 32 bit integer that defines the trust level with -1 being untrusted, 0, being basically an Apple executable and other potential bigger values corresponding to App Store binaries, Developer ID signature, etc. Yet, I'm not able to find a corresponding detailed documentation about this on Apple's developer website. I also had a look at the LightweightCodeRequirements "include" file and there does not seem to be such a field available. [Q] Is there any official documentation listing the different values for this trust level value and providing a clear description of what it corresponds to?
Replies
4
Boosts
0
Views
367
Activity
Jul ’25
Why won't my AutoFill Credential Provider show up in the context menu of a generic textfield?
I noticed, that even though my AutoFill Credential Provider Extension works with Safari for both Passwords and Passkeys, it doesn't work in context menus inside arbitrary textfields, meanwhile the same is true for the Apple Passwords app. This is a great hit to AutoFill productivity, as my extension is unable to fill textfields by just going to the context menu and clicking AutoFill > Passwords.. Is this a feature only available to Apple via private APIs, or is this something I can interface with? I checked and the Passwords app does use some undocumented but non-private entitlements: [Key] com.apple.authentication-services.access-credential-identities [Value] [Bool] true I also checked the responsible executable for some hints (AutoFillPanelService) however found nothing that would lead me to believe this is a public extension point. Another idea I had was trying to use a macOS Service for this, however Services in the "General" category won't show up in any context menu, only in the Application's Main Menu.
Replies
0
Boosts
1
Views
154
Activity
Dec ’25
How to reset user preference for crypto token kit access
When an app is trying to access identities put in the keychain by cryptotokenkit extension, the user gets asked a permission pop-up which reads 'Token Access Request" would like access a token provided by: " with 2 options 'Don't allow' and 'OK' I accidently clicked "Don't allow" and now can't access identities put in crypto token kit. How can I reset the preference?
Replies
11
Boosts
0
Views
1.6k
Activity
2w
ASPasswordCredential Returns a Blank Password with Apple Password App
Using the simplified sign-in with tvOS and a third party password manager, I receive a complete ASPasswordCredential, and I can easily log into my app. When I do the same thing but with Apple's password manager as the source, I receive an ASPasswordCredential that includes the email address, but the password is an empty string. I have tried deleting the credentials from Apple Passwords and regenerating them with a new login to the app's website. I have tried restarting my iPhone. Is this the expected behavior? How should I be getting a password from Apple's Password app with an ASAuthorizationPasswordRequest?
Replies
2
Boosts
0
Views
334
Activity
Aug ’25
Mark the iOS app content not to be backed up when doing unencrypted backup in iTunes
Hi,is there an option to mark the file or folder or item stored in user defaults ... not to be backed up when doing unencrypted backup in iTunes?We are developing iOS app that contains sensitive data. But even if we enable Data Protection for the iOS app it can be backed up on mac unencrypted using iTunes. Is there a way to allow backing up content only if the backup is encrypted?
Replies
2
Boosts
0
Views
1.8k
Activity
Oct ’25
App ID Prefix Change and Keychain Access
DTS regularly receives questions about how to preserve keychain items across an App ID change, and so I thought I’d post a comprehensive answer here for the benefit of all. If you have any questions or comments, please start a new thread here on the forums. Put it in the Privacy & Security > General subtopic and tag it with Security. Share and Enjoy — Quinn “The Eskimo!” @ Developer Technical Support @ Apple let myEmail = "eskimo" + "1" + "@" + "apple.com" App ID Prefix Change and Keychain Access The list of keychain access groups your app can access is determined by three entitlements. For the details, see Sharing Access to Keychain Items Among a Collection of Apps. If your app changes its App ID prefix, this list changes and you’re likely to lose access to existing keychain items. This situation crops up under two circumstances: When you migrate your app from using a unique App ID prefix to using your Team ID as its App ID prefix. When you transfer your app to another team. In both cases you have to plan carefully for this change. If you only learn about the problem after you’ve made the change, consider undoing the change to give you time to come up with a plan before continuing. Note On macOS, the information in this post only applies to the data protection keychain. For more information about the subtleties of the keychain on macOS, see On Mac Keychains. For more about App ID prefix changes, see Technote 2311 Managing Multiple App ID Prefixes and QA1726 Resolving the Potential Loss of Keychain Access warning. Migrate From a Unique App ID Prefix to Your Team ID Historically each app was assigned its own App ID prefix. This is no longer the case. Best practice is for apps to use their Team ID as their App ID prefix. This enables multiple neat features, including keychain item sharing and pasteboard sharing. If you have an app that uses a unique App ID prefix, consider migrating it to use your Team ID. This is a good thing in general, as long as you manage the migration process carefully. Your app’s keychain access group list is built from three entitlements: keychain-access-groups — For more on this, see Keychain Access Groups Entitlement. application-identifier (com.apple.application-identifier on macOS) com.apple.security.application-groups — For more on this, see App Groups Entitlement. Keycahin access groups from the third bullet are call app group identified keychain access groups, or AGI keychain access groups for short. IMPORTANT A macOS app can only use an AGI keychain access group if all of its entitlement claims are validated by a provisioning profile. See App Groups: macOS vs iOS: Working Towards Harmony for more about this concept. Keychain access groups from the first two bullets depend on the App ID prefix. If that changes, you lose access to any keychain items in those groups. WARNING Think carefully before using the keychain to store secrets that are the only way to access irreplaceable user data. While the keychain is very reliable, there are situations where a keychain item can be lost and it’s bad if it takes the user’s data with it. In some cases losing access to keychain items is not a big deal. For example, if your app uses the keychain to manage a single login credential, losing that is likely to be acceptable. The user can recover by logging in again. In other cases losing access to keychain items is unacceptable. For example, your app might manage access to dozens of different servers, each with unique login credentials. Your users will be grumpy if you require them to log in to all those servers again. In such situations you must carefully plan your migration. The key thing to understand is that an app group is tied to your team, not your App ID prefix, and thus your app retains access to AGI keychain access groups across an App ID prefix change. This suggests the following approach: Release a version of your app that moves keychain items from other keychain access groups to an AGI keychain access group. Give your users time to update to this new version, run it, and so move their keychain items. When you’re confident that the bulk of your users have done this, change your App ID prefix. The approach has one obvious caveat: It’s hard to judge how long to wait at step 2. Transfer Your App to Another Team Historically there was no supported way to maintain access to keychain items across an app transfer. That’s no longer the case, but you must still plan the transfer carefully. The overall approach is: Identify an app group ID to transfer. This could be an existing app group ID, but in many cases you’ll want to register a new app group ID solely for this purpose. Use the old team (the transferor) to release a version of your app that moves keychain items from other keychain access groups to the AGI keychain access group for this app group ID. Give your users time to update to this new version, run it, and so move their keychain items. When you’re confident that the bulk of your users have done this, initiate the app transfer. Once that’s complete, transfer the app group ID you selected in step 1. See App Store Connect Help > Transfer an app > Overview of app transfer > Apps using App Groups. Publish an update to your app from the new team (the transferee). When a user installs this version, it will have access to your app group, and hence your keychain items. WARNING Once you transfer the app group, the old team won’t be able to publish a new version of any app that uses this app group. That makes step 1 in the process critical. If you have an existing app group that’s used solely by the app being transferred — for example, an app group that you use to share state between the app and its app extensions — then choosing that app group ID makes sense. On the other hand, choosing the ID of an app group that’s share between this app and some unrelated app, one that’s not being transferred, would be bad, because any updates to that other app will lose access to the app group. There are some other significant caveats: The process doesn’t work for Mac apps because Mac apps that have ever used an app group can’t be transferred. See App Store Connect Help > Transfer an app > App transfer criteria. If and when that changes, you’ll need to choose an iOS-style app group ID for your AGI keychain access group. For more about the difference between iOS- and macOS-style app group IDs, see App Groups: macOS vs iOS: Working Towards Harmony. The current transfer process of app groups exposes a small window where some other team can ‘steal’ your app group ID. We have a bug on file to improve that process (r. 171616887). The process works best when transferring between two teams that are both under the control of the same entity. If that’s not the case, take steps to ensure that the old team transfers the app group in step 5. When you submit the app from the new team (step 6), App Store Connect will warn you about a potential loss of keychain access. That warning is talking about keychain items in normal keychain access groups. Items in an AGI keychain access group will still be accessible as long as you transfer the app group. Alternative Approaches for App Transfer In addition to the technique described in the previous section, there are a some alternative approaches you should at consider: Do nothing Do not transfer your app Get creative Do Nothing In this case the user loses all the secrets that your app stored in the keychain. This may be acceptable for certain apps. For example, if your app uses the keychain to manage a single login credential, losing that is likely to be acceptable. The user can recover by logging in again. Do Not Transfer Another option is to not transfer your app. Instead, ship a new version of the app from the new team and have the old app recommend that the user upgrade. There are a number of advantages to this approach. The first is that there’s absolutely no risk of losing any user data. The two apps are completely independent. The second advantage is that the user can install both apps on their device at the same time. This opens up a variety of potential migration paths. For example, you might ship an update to the old app with an export feature that saves the user’s state, including their secrets, to a suitably encrypted file, and then match that with an import facility on the new app. Finally, this approach offers flexible timing. The user can complete their migration at their leisure. However, there are a bunch of clouds to go with these silver linings: Your users might never migrate to the new app. If this is a paid app, or an app with in-app purchase, the user will have to buy things again. You lose the original app’s history, ratings, reviews, and so on. Get Creative Finally, you could attempt something creative. For example, you might: Publish a new version of the app that supports exporting the user’s state, including the secrets. Tell your users to do this, with a deadline. Transfer the app and then, when the deadline expires, publish the new version with an import feature. Frankly, this isn’t very practical. The problem is with step 2: There’s no good way to get all your users to do the export, and if they don’t do it before the deadline there’s no way to do it after. Test Before You Ship Once you have a new version of your app, with the new App ID prefix, it’s time to test. To run a day-to-day test: On a test device, install the existing version of the app from the App Store. Use the app to generate keychain items as a normal user would. For example, if you store login credentials in the keychain, use the app to save such a credential. In Xcode, run the new version of your app. Check that the keychain items you created in step 2 still work. After you upload this new version to App Store Connect, use TestFlight to run an internal test: On a test device, install the existing version of the app from the App Store. Use the app to generate keychain items as a normal user. For example, if you store login credentials in the keychain, use the app to save such a credential. Use TestFlight to update the app to your new version. Check that the keychain items you created in step 2 still work. Do this before you release the app to your beta testers and then again before releasing it to customers. WARNING These TestFlight test are your last chance to ensure that everything works. If you detect an error at this stage, you still have a chance to fix it. Revision History 2026-04-07 Added the Test Before You Ship section. 2026-03-31 Rewrote the Transfer Your App to Another Team section to describe a new approach for preserving access to keychain items across app transfers. Moved the previous discussion into a new Alternative Approaches for App Transfer section. Clarified that a macOS program can now use an app group as a keychain access group as long as its entitlements are validated. Made numerous editorial changes. 2022-05-17 First posted.
Replies
0
Boosts
0
Views
8.8k
Activity
Apr ’26
Is there any public API apple provides to detect Lockdown Mode in iOS 16?
Hi, I was testing the lockdown mode in iOS 16 and would like to know whether we can detect the lockdown mode status using any public API that Apple provides. I really appreciate any help you can provide.
Replies
8
Boosts
0
Views
2.8k
Activity
Jun ’25
Sharing ScreenTime data to a custom server
With the ScreenTime API Apple talks a lot about their focus on privacy and the data not leaving the device. Does that mean there would be a problem with an app where the users ScreenTime data is shared to a custom backend? Could this potentially cause an app to be rejected from the AppStore?
Replies
3
Boosts
2
Views
671
Activity
1h
ASWebAuthenticationSession crash after window closes on macOS
I'm trying to use ASWebAuthenticationSession on macOS but there is a weird crash and I have no idea what to do. It looks like there is a main thread check in a framework code that I have no control over. Any help would be appreciated. Thank you in advance. The stack of crashed thread has no symbols, even for supposedly my code in OAuthClient.authenticate. macOS 15.4.1 (24E263) Xcode Version 16.3 (16E140) Thread 11: EXC_BREAKPOINT (code=1, subcode=0x10039bb04) Thread 12 Queue : com.apple.NSXPCConnection.m-user.com.apple.SafariLaunchAgent (serial) #0 0x0000000100b17b04 in _dispatch_assert_queue_fail () #1 0x0000000100b52834 in dispatch_assert_queue$V2.cold.1 () #2 0x0000000100b17a88 in dispatch_assert_queue () #3 0x000000027db5f3e8 in swift_task_isCurrentExecutorWithFlagsImpl () #4 0x00000001022c7754 in closure #1 in closure #1 in OAuthClient.authenticate() () #5 0x00000001022d0c98 in thunk for @escaping @callee_guaranteed (@in_guaranteed URL?, @guaranteed Error?) -&gt; () () #6 0x00000001c7215a34 in __102-[ASWebAuthenticationSession initWithURL:callback:usingEphemeralSession:jitEnabled:completionHandler:]_block_invoke () #7 0x00000001c72163d0 in -[ASWebAuthenticationSession _endSessionWithCallbackURL:error:] () #8 0x00000001c7215fc0 in __43-[ASWebAuthenticationSession _startDryRun:]_block_invoke_2 () #9 0x0000000194e315f4 in __invoking___ () #10 0x0000000194e31484 in -[NSInvocation invoke] () #11 0x00000001960fd644 in __NSXPCCONNECTION_IS_CALLING_OUT_TO_REPLY_BLOCK__ () #12 0x00000001960fbe40 in -[NSXPCConnection _decodeAndInvokeReplyBlockWithEvent:sequence:replyInfo:] () #13 0x00000001960fb798 in __88-[NSXPCConnection _sendInvocation:orArguments:count:methodSignature:selector:withProxy:]_block_invoke_3 () #14 0x0000000194a6ef18 in _xpc_connection_reply_callout () #15 0x0000000194a6ee08 in _xpc_connection_call_reply_async () #16 0x0000000100b3130c in _dispatch_client_callout3_a () #17 0x0000000100b362f8 in _dispatch_mach_msg_async_reply_invoke () #18 0x0000000100b1d3a8 in _dispatch_lane_serial_drain () #19 0x0000000100b1e46c in _dispatch_lane_invoke () #20 0x0000000100b2bfbc in _dispatch_root_queue_drain_deferred_wlh () #21 0x0000000100b2b414 in _dispatch_workloop_worker_thread () #22 0x0000000100c0379c in _pthread_wqthread () My code: @MainActor func authenticate() async throws { let authURL = api.authorizationURL( scopes: scopes, state: state, redirectURI: redirectURI ) let authorizationCodeURL: URL = try await withUnsafeThrowingContinuation { c in let session = ASWebAuthenticationSession(url: authURL, callback: .customScheme(redirectScheme)) { url, error in guard let url = url else { c.resume(throwing: error ?? Error.unknownError("Failed to get authorization code")) return } c.resume(returning: url) } session.presentationContextProvider = presentationContextProvider session.start() } let authorizationCode = try codeFromAuthorizationURL(authorizationCodeURL) (storedAccessToken, storedRefreshToken) = try await getTokens(authorizationCode: authorizationCode) } Here is disassembly of the crashed function. libdispatch.dylib`_dispatch_assert_queue_fail: 0x10067fa8c &lt;+0&gt;: pacibsp 0x10067fa90 &lt;+4&gt;: sub sp, sp, #0x50 0x10067fa94 &lt;+8&gt;: stp x20, x19, [sp, #0x30] 0x10067fa98 &lt;+12&gt;: stp x29, x30, [sp, #0x40] 0x10067fa9c &lt;+16&gt;: add x29, sp, #0x40 0x10067faa0 &lt;+20&gt;: adrp x8, 71 0x10067faa4 &lt;+24&gt;: add x8, x8, #0x951 ; "not " 0x10067faa8 &lt;+28&gt;: adrp x9, 70 0x10067faac &lt;+32&gt;: add x9, x9, #0x16b ; "" 0x10067fab0 &lt;+36&gt;: stur xzr, [x29, #-0x18] 0x10067fab4 &lt;+40&gt;: cmp w1, #0x0 0x10067fab8 &lt;+44&gt;: csel x8, x9, x8, ne 0x10067fabc &lt;+48&gt;: ldr x10, [x0, #0x48] 0x10067fac0 &lt;+52&gt;: cmp x10, #0x0 0x10067fac4 &lt;+56&gt;: csel x9, x9, x10, eq 0x10067fac8 &lt;+60&gt;: stp x9, x0, [sp, #0x10] 0x10067facc &lt;+64&gt;: adrp x9, 71 0x10067fad0 &lt;+68&gt;: add x9, x9, #0x920 ; "BUG IN CLIENT OF LIBDISPATCH: Assertion failed: " 0x10067fad4 &lt;+72&gt;: stp x9, x8, [sp] 0x10067fad8 &lt;+76&gt;: adrp x1, 71 0x10067fadc &lt;+80&gt;: add x1, x1, #0x8eb ; "%sBlock was %sexpected to execute on queue [%s (%p)]" 0x10067fae0 &lt;+84&gt;: sub x0, x29, #0x18 0x10067fae4 &lt;+88&gt;: bl 0x1006c258c ; symbol stub for: asprintf 0x10067fae8 &lt;+92&gt;: ldur x19, [x29, #-0x18] 0x10067faec &lt;+96&gt;: str x19, [sp] 0x10067faf0 &lt;+100&gt;: adrp x0, 71 0x10067faf4 &lt;+104&gt;: add x0, x0, #0x956 ; "%s" 0x10067faf8 &lt;+108&gt;: bl 0x1006b7b64 ; _dispatch_log 0x10067fafc &lt;+112&gt;: adrp x8, 108 0x10067fb00 &lt;+116&gt;: str x19, [x8, #0x2a8] -&gt; 0x10067fb04 &lt;+120&gt;: brk #0x1
Replies
1
Boosts
0
Views
171
Activity
May ’25
DCError.invalidInput on generateAssertion() - Affecting Small Subset of Users
Issue Summary I'm encountering a DCError.invalidInput error when calling DCAppAttestService.shared.generateAssertion() in my App Attest implementation. This issue affects only a small subset of users - the majority of users can successfully complete both attestation and assertion flows without any issues. According to Apple Engineer feedback, there might be a small implementation issue in my code. Key Observations Success Rate: ~95% of users complete the flow successfully Failure Pattern: The remaining ~5% consistently fail at assertion generation Key Length: Logs show key length of 44 characters for both successful and failing cases Consistency: Users who experience the error tend to experience it consistently Platform: Issue observed across different iOS versions and device types Environment iOS App Attest implementation Using DCAppAttestService for both attestation and assertion Custom relying party server communication Issue affects ~5% of users consistently Key Implementation Details 1. Attestation Flow (Working) The attestation process works correctly: // Generate key and attest (successful for all users) self.attestService.generateKey { keyId, keyIdError in guard keyIdError == nil, let keyId = keyId else { return completionHandler(.failure(.dcError(keyIdError as! DCError))) } // Note: keyId length is consistently 44 characters for both successful and failing users // Attest key with Apple servers self.attestKey(keyId, clientData: clientData) { result in // ... verification with RP server // Key is successfully stored for ALL users (including those who later fail at assertion) } } 2. Assertion Flow (Failing for ~5% of Users with invalidInput) The assertion generation fails for a consistent subset of users: // Get assertion data from RP server self.assertRelyingParty.getAssertionData(kid, with: data) { result in switch result { case .success(let receivedData): let session = receivedData.session let clientData = receivedData.clientData let hash = clientData.toSHA256() // SHA256 hash of client data // THIS CALL FAILS WITH invalidInput for ~5% of users // Same keyId (44 chars) that worked for attestation self.attestService.generateAssertion(kid, clientDataHash: hash) { assertion, err in guard err == nil, let assertion = assertion else { // Error: DCError.invalidInput if let err = err as? DCError, err.code == .invalidKey { return reattestAndAssert(.invalidKey, completionHandler) } else { return completionHandler(.failure(.dcError(err as! DCError))) } } // ... verification logic } } } 3. Client Data Structure Client data JSON structure (identical for successful and failing users): // For attestation (works for all users) let clientData = ["challenge": receivedData.challenge] // For assertion (fails for ~5% of users with same structure) var clientData = ["challenge": receivedData.challenge] if let data = data { // Additional data for assertion clientData["account"] = data["account"] clientData["amount"] = data["amount"] } 4. SHA256 Hash Implementation extension Data { public func toSHA256() -> Data { return Data(SHA256.hash(data: self)) } } 5. Key Storage Implementation Using UserDefaults for key storage (works consistently for all users): private let keyStorageTag = "app-attest-keyid" func setKey(_ keyId: String) -> Result<(), KeyStorageError> { UserDefaults.standard.set(keyId, forKey: keyStorageTag) return .success(()) } func getKey() -> Result<String?, KeyStorageError> { let keyId = UserDefaults.standard.string(forKey: keyStorageTag) return .success(keyId) } Questions User-Specific Factors: Since this affects only ~5% of users consistently, could there be device-specific, iOS version-specific, or account-specific factors that cause invalidInput? Key State Validation: Is there any way to validate the state of an attested key before calling generateAssertion()? The key length (44 chars) appears normal for both successful and failing cases. Keychain vs UserDefaults: Could the issue be related to using UserDefaults instead of Keychain for key storage? Though this works for 95% of users. Race Conditions: Could there be subtle race conditions or timing issues that only affect certain users/devices? Error Recovery: Is there a recommended way to handle this error? Should we attempt re-attestation for these users? Additional Context & Debugging Attempts Consistent Failure: Users who experience this error typically experience it on every attempt Key Validation: Both successful and failing users have identical key formats (44 character strings) Device Diversity: Issue observed across different device models and iOS versions Server Logs: Our server successfully provides challenges and processes attestation for all users Re-attestation: Forcing re-attestation sometimes resolves the issue temporarily, but it often recurs The fact that 95% of users succeed with identical code suggests there might be some environmental or device-specific factor that we're not accounting for. Any insights into what could cause invalidInput for a subset of users would be invaluable.
Replies
2
Boosts
0
Views
534
Activity
Jun ’25