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

All subtopics
Posts under Privacy & Security topic

Post

Replies

Boosts

Views

Activity

DeviceCheck.generateToken, Error: com.apple.devicecheck.error 0
Dear Apple Developer Support Team, We are experiencing a recurring issue with the DeviceCheck API where the following error is being returned: com.apple.devicecheck.error 0 Upon analyzing our logs, we have noticed that this error occurs significantly more often when users are connected to Wi-Fi networks, compared to mobile networks. This leads us to suspect that there might be a relationship between Wi-Fi configuration and the DeviceCheck service’s ability to generate or validate tokens. We would like to know: Is this error code (0) known to be caused by specific types of network behavior or misconfigurations on Wi-Fi networks (e.g., DNS filtering, firewall restrictions, proxy servers)? Are there any recommended best practices for ensuring reliable DeviceCheck API communication over Wi-Fi networks? Additionally, could you please clarify what general conditions could trigger this com.apple.devicecheck.error 0? The lack of specific documentation makes debugging this issue difficult from our side. Any guidance or internal documentation on this error code and its potential causes would be greatly appreciated. IDE: Xcode 16.3 Looking forward to your support. Best regards,
2
0
135
May ’25
Discrepancy in Sign in with Apple Notification Type: account-deleted vs account-delete
Hi everyone, I am currently implementing Server-to-Server Notifications for Sign in with Apple. I’ve encountered a discrepancy between the official documentation and the actual payload I received, and I would like to clarify which one is correct. The Situation: I triggered an account deletion event via privacy.apple.com to test the notification flow. When my server received the notification, the type field in the JSON payload was account-deleted (past tense). The Issue: According to the official Apple documentation, the event type is listed as account-delete (present tense). Here is the discrepancy I am observing: Documentation: account-delete Actual Payload: account-deleted My Question: Is the documentation outdated, or is this a known inconsistency? Should I handle both strings (account-delete and account-deleted) in my backend logic to be safe, or is account-deleted the new standard? Any insights or confirmation from those who have implemented this would be greatly appreciated. Thanks!
2
0
298
2w
Full disk access for CLI app
It seems it is not possible to give a CLI app (non .app bundle) full disk access in macOS 26.1. This seems like a bug and if not that is a breaking change. Anybody seeing the same problem? Our application needs full disk access for a service running as a LaunchDaemon. The binary is located in a /Library subfolder.
2
1
676
Nov ’25
Mac Issue with Developer ID certificate and Sign in with Apple capability
Hello I have a problem with provisionprofile file. I have created Identifier with Sign in with Apple capability turned on, created Profile with Developer ID selected and now I try to export archive with generated Developer ID provision file but it says "Profile doesn't support Sign in with Apple" Also interesting thing that default provisions like macOS App Development Mac App Store Connect don't show such error when I try to export archive Maybe this problem is only related to Developer ID provision and Direct Distribution doesn't support Sign in with Apple, but I havent found proves about this idea
2
1
493
Oct ’25
Keep getting: invalid_client
I keep getting invalid_client, here is a test login: https://www.bella-booking.ch/_get_incl/test_apple_login.cfm Any help appreciated. NOTE: Everey other error, like wrong reroute or wrong client id, a different error will be sent frpm apple, after I checked all and crosschecked with jwt.io, it keep getting invalid_client. Any clue? If the response is correct, the token should be displayed on the page. Thx
2
0
450
Jul ’25
Swift program to send Push Notifications
Is there a step by step program on Sending Push notifications? I seem to be stuck at load private key. I get this error. SecKeyCreateWithData failed with error: Error Domain=NSOSStatusErrorDomain Code=-50 "EC private key creation from data failed" It is a new p8 file. I tried different format. I read some articles that say that there is a bug I think. I don't know for sure because it was written in jibberish. 90% of the code is dealing with these stupid keys. This should be 1 function setting the pipe and then I can use the pipe. This is ridiculous. If anybody has any ideas. The code is a mess because I tried so many different ideas. Push Notification.txt
2
0
505
Jan ’25
Information on macOS tracking/updating of CRLs
With Let's Encrypt having completely dropped support for OCSP recently [1], I wanted to ask if macOS has a means of keeping up to date with their CRLs and if so, roughly how often this occurs? I first observed an issue where a revoked-certificate test site, "revoked.badssl.com" (cert signed by Let's Encrypt), was not getting blocked on any browser, when a revocation policy was set up using the SecPolicyCreateRevocation API, in tandem with the kSecRevocationUseAnyAvailableMethod and kSecRevocationPreferCRL flags. After further investigation, I noticed that even on a fresh install of macOS, Safari does not block this test website, while Chrome and Firefox (usually) do, due to its revoked certificate. Chrome and Firefox both have their own means of dealing with CRLs, while I assume Safari uses the system Keychain and APIs. I checked cert info for the site here [2]. It was issued on 2025-07-01 20:00 and revoked an hour later. [1] https://letsencrypt.org/2024/12/05/ending-ocsp/ [2] https://www.ssllabs.com/ssltest/analyze.html?d=revoked.badssl.com
2
0
411
Sep ’25
Protecting XPC service when called from Authorisation Plugin
I have Authorisation Plugin which talks using XPC to my Launch Daemon to perform privileged actions. I want to protect my XPC service narrowing it to be called from known trusted clients. Now since I want authorisation plugin code which is from apple to call my service, I cannot use my own team id or app group here. I am currently banking on following properties of client connection. Apple Team ID : EQHXZ8M8AV Bundle ID starting with com.apple. Client signature verified By Apple. This is what I have come up with. func isClientTrusted(connection: NSXPCConnection) -> Bool { let clientPID = connection.processIdentifier logInfo("🔍 Checking XPC Client - PID: \(clientPID)") var secCode: SecCode? var secStaticCode: SecStaticCode? let attributes = [kSecGuestAttributePid: clientPID] as NSDictionary let status = SecCodeCopyGuestWithAttributes(nil, attributes, [], &secCode) guard status == errSecSuccess, let code = secCode else { logInfo("Failed to get SecCode for PID \(clientPID)") return false } let staticStatus = SecCodeCopyStaticCode(code, [], &secStaticCode) guard staticStatus == errSecSuccess, let staticCode = secStaticCode else { logInfo("Failed to get SecStaticCode") return false } var signingInfo: CFDictionary? let signingStatus = SecCodeCopySigningInformation(staticCode, SecCSFlags(rawValue: kSecCSSigningInformation), &signingInfo) guard signingStatus == errSecSuccess, let info = signingInfo as? [String: Any] else { logInfo("Failed to retrieve signing info") return false } // Extract and Verify Team ID if let teamID = info["teamid"] as? String { logInfo("XPC Client Team ID: \(teamID)") if teamID != "EQHXZ8M8AV" { // Apple's official Team ID logInfo("Client is NOT signed by Apple") return false } } else { logInfo("Failed to retrieve Team ID") return false } // Verify Bundle ID Starts with "com.apple." if let bundleID = info["identifier"] as? String { logInfo("XPC Client Bundle ID: \(bundleID)") if !bundleID.hasPrefix("com.apple.") { logInfo("Client is NOT an Apple system process") return false } } else { logInfo("Failed to retrieve Bundle Identifier") return false } // Verify Apple Code Signature Trust var trustRequirement: SecRequirement? let trustStatus = SecRequirementCreateWithString("anchor apple" as CFString, [], &trustRequirement) guard trustStatus == errSecSuccess, let trust = trustRequirement else { logInfo("Failed to create trust requirement") return false } let verifyStatus = SecStaticCodeCheckValidity(staticCode, [], trust) if verifyStatus != errSecSuccess { logInfo("Client's signature is NOT trusted by Apple") return false } logInfo("Client is fully verified as Apple-trusted") return true } Q: Just wanted community feedback, is this correct approach?
2
0
172
Mar ’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
114
Jun ’25
Migration of "Sign with Apple" users
Hello, We’ve resumed the migration process after a break. Since my colleague is no longer with us, I had to go through the steps again myself. As before, we’re trying to migrate "Sign In with Apple" users from tenant TENANT_A with client_id=CLIENT_ID_A to tenant TENANT_B with client_id=CLIENT_ID_B I followed the procedure described here: [Apple Developer Documentation](https://developer.apple.com/documentation/technotes/tn3159-migrating-sign-in-with-apple-users-for-an-app-transfer – Migrating Sign In with Apple Users, essentially repeating what my coworker previously attempted in coordination with your employee Stephanie. Here’s a summary of the steps and the issue we’re facing: STEP 1 - get authcode for TEAM A curl --location 'https://appleid.apple.com/auth/token' --header 'Content-Type: application/x-www-form-urlencoded' --data-urlencode 'grant_type=client_credentials' --data-urlencode 'scope=user.migration' --data-urlencode 'client_id=pl.CLIEND_ID_A' --data-urlencode 'client_secret=<TEAM_A_SECRET>' I receive response: { "access_token": "<ACCESS_TOKEN_TEAM_A>", "token_type": "Bearer", "expires_in": 3600 } STEP 2 - get authcode for TEAB B curl --location 'https://appleid.apple.com/auth/token' --header 'Content-Type: application/x-www-form-urlencoded' --data-urlencode 'grant_type=client_credentials' --data-urlencode 'scope=user.migration' --data-urlencode 'client_id=CLIENT_ID_B' --data-urlencode 'client_secret=<TEAB_B_SECRET>' I receive response: { "access_token":"<ACCESS_TOKEN_TEAB_B>", "token_type": "Bearer", "expires_in": 3600 } STEP 3 - get transfer_sub from TEAM A curl --location 'https://appleid.apple.com/auth/usermigrationinfo' --header 'Authorization: Bearer <ACCESS_TOKEN_TEAM_A>' --header 'Content-Type: application/x-www-form-urlencoded' --data-urlencode 'client_id=CLIENT_ID_A' --data-urlencode 'client_secret=<TEAM_A_SECRET>' --data-urlencode 'sub=USER_SUB_FROM_TEAM_A' --data-urlencode 'target=TENANT_B' I receive response: { "transfer_sub": "USER_SUB_FROM_TEAM_B" } STEP 4 - Team B exchanges transfer identifers curl --location 'https://appleid.apple.com/auth/usermigrationinfo' --header 'Authorization: Bearer <ACCESS_TOKEN_TEAM_B' --header 'Content-Type: application/x-www-form-urlencoded' --data-urlencode 'client_id=CLIENT_ID_B' --data-urlencode 'client_secret=<TEAM_B_SECRET>' I receive response: { "error": "invalid_request" } We’ve created a new client_id under tenant B and want to migrate users there. However, we skipped the step described in Step 3 of the documentation(https://developer.apple.com/documentation/technotes/tn3159-migrating-sign-in-with-apple-users-for-an-app-transfer#3-Team-A-initiates-app-transfer-to-Team-B), which involves initiating an app transfer. The reason is that this client_id is used solely for web authentication, not for a mobile app, so we don’t have an app to transfer. Based on our analysis and your documentation, it seems this flow only works if the client_id matches across both tenants, which can only be achieved through an app transfer, something we cannot proceed with. Apple previously insisted that we migrate these users, but as shown above, we’re stuck. Is there any alternative flow available, or can you assist us in completing this migration?
2
0
215
Sep ’25
Title: Intermittent Keychain Data Loss on App Relaunch in iOS Beta 2
Hi everyone, I'm experiencing an intermittent issue with Keychain data loss on the latest iOS Beta 2. In about 7% of cases, users report that previously saved Keychain items are missing when the app is relaunched — either after a cold start or simply after being killed and reopened. Here are the key observations: The issue occurs sporadically, mostly once per affected user, but in 3 cases it has happened 4 times. No explicit deletion is triggered from the app. No system logs or error messages from Apple indicate any Keychain-related actions. The app attempts to access Keychain items, but they are no longer available. This behavior is inconsistent with previous iOS versions and is not reproducible in development environments. This raises concerns about: Whether this is a bug in the beta or an intentional change in Keychain behavior. Whether this could affect production apps when the final iOS version is released. The lack of any warning or documentation from Apple regarding this behavior. Has anyone else encountered similar issues? Any insights, workarounds, or official clarification would be greatly appreciated. Thanks!
2
0
123
Sep ’25
Request for manual on interpreting Security Authorization Plugin authentication failure codes
Using the SDK, I've printed out some log messages when I enter the wrong password: 2025-08-20 15:58:14.086 Db SecurityAgentHelper-arm64[818:1efd] [com.example.apple-samplecode.LoggingAuthPlugin:mechanism] invoke 2025-08-20 15:58:14.086 Db SecurityAgentHelper-arm64[818:1efd] [com.example.apple-samplecode.LoggingAuthPlugin:mechanism] general: 2025-08-20 15:58:14.086 Db SecurityAgentHelper-arm64[818:1efd] [com.example.apple-samplecode.LoggingAuthPlugin:mechanism] progname: 'SecurityAgentHelper-arm64' 2025-08-20 15:58:14.086 Db SecurityAgentHelper-arm64[818:1efd] [com.example.apple-samplecode.LoggingAuthPlugin:mechanism] OS version: 'Version 15.5 (Build 24F74)' 2025-08-20 15:58:14.086 Db SecurityAgentHelper-arm64[818:1efd] [com.example.apple-samplecode.LoggingAuthPlugin:mechanism] pid: '818' 2025-08-20 15:58:14.086 Db SecurityAgentHelper-arm64[818:1efd] [com.example.apple-samplecode.LoggingAuthPlugin:mechanism] ppid: '1' 2025-08-20 15:58:14.086 Db SecurityAgentHelper-arm64[818:1efd] [com.example.apple-samplecode.LoggingAuthPlugin:mechanism] euid: '92' 2025-08-20 15:58:14.086 Db SecurityAgentHelper-arm64[818:1efd] [com.example.apple-samplecode.LoggingAuthPlugin:mechanism] uid: '92' 2025-08-20 15:58:14.087 Db SecurityAgentHelper-arm64[818:1efd] [com.example.apple-samplecode.LoggingAuthPlugin:mechanism] session: 0x186e9 2025-08-20 15:58:14.087 Db SecurityAgentHelper-arm64[818:1efd] [com.example.apple-samplecode.LoggingAuthPlugin:mechanism] attributes: 2025-08-20 15:58:14.087 Db SecurityAgentHelper-arm64[818:1efd] [com.example.apple-samplecode.LoggingAuthPlugin:mechanism] is root: f 2025-08-20 15:58:14.087 Db SecurityAgentHelper-arm64[818:1efd] [com.example.apple-samplecode.LoggingAuthPlugin:mechanism] has graphics: t 2025-08-20 15:58:14.087 Db SecurityAgentHelper-arm64[818:1efd] [com.example.apple-samplecode.LoggingAuthPlugin:mechanism] has TTY: t 2025-08-20 15:58:14.087 Db SecurityAgentHelper-arm64[818:1efd] [com.example.apple-samplecode.LoggingAuthPlugin:mechanism] is remote: f 2025-08-20 15:58:14.087 Db SecurityAgentHelper-arm64[818:1efd] [com.example.apple-samplecode.LoggingAuthPlugin:mechanism] auth session: 0x0 2025-08-20 15:58:14.087 Db SecurityAgentHelper-arm64[818:1efd] [com.example.apple-samplecode.LoggingAuthPlugin:mechanism] context: 2025-08-20 15:58:14.088 Db SecurityAgentHelper-arm64[818:1efd] [com.example.apple-samplecode.LoggingAuthPlugin:mechanism] authentication-failure: --S -14090 2025-08-20 15:58:14.088 Db SecurityAgentHelper-arm64[818:1efd] [com.example.apple-samplecode.LoggingAuthPlugin:mechanism] pam_result: X-S 9 2025-08-20 15:58:14.089 Db SecurityAgentHelper-arm64[818:1efd] [com.example.apple-samplecode.LoggingAuthPlugin:mechanism] hints: 2025-08-20 15:58:14.089 Db SecurityAgentHelper-arm64[818:1efd] [com.example.apple-samplecode.LoggingAuthPlugin:mechanism] authorize-right: "system.login.console" 2025-08-20 15:58:14.090 Db SecurityAgentHelper-arm64[818:1efd] [com.example.apple-samplecode.LoggingAuthPlugin:mechanism] client-path: "/System/Library/CoreServices/loginwindow.app" 2025-08-20 15:58:14.090 Db SecurityAgentHelper-arm64[818:1efd] [com.example.apple-samplecode.LoggingAuthPlugin:mechanism] client-pid: 807 2025-08-20 15:58:14.090 Db SecurityAgentHelper-arm64[818:1efd] [com.example.apple-samplecode.LoggingAuthPlugin:mechanism] client-type: 'LDNB' 2025-08-20 15:58:14.090 Db SecurityAgentHelper-arm64[818:1efd] [com.example.apple-samplecode.LoggingAuthPlugin:mechanism] client-uid: 0 2025-08-20 15:58:14.090 Db SecurityAgentHelper-arm64[818:1efd] [com.example.apple-samplecode.LoggingAuthPlugin:mechanism] creator-audit-token: 2025-08-20 15:58:14.090 Db SecurityAgentHelper-arm64[818:1efd] [com.example.apple-samplecode.LoggingAuthPlugin:mechanism] ff ff ff ff 00 00 00 00 00 00 00 00 00 00 00 00 ................ 2025-08-20 15:58:14.090 Db SecurityAgentHelper-arm64[818:1efd] [com.example.apple-samplecode.LoggingAuthPlugin:mechanism] 00 00 00 00 27 03 00 00 e9 86 01 00 68 08 00 00 ....'.......h... 2025-08-20 15:58:14.090 Db SecurityAgentHelper-arm64[818:1efd] [com.example.apple-samplecode.LoggingAuthPlugin:mechanism] creator-pid: 807 2025-08-20 15:58:14.090 Db SecurityAgentHelper-arm64[818:1efd] [com.example.apple-samplecode.LoggingAuthPlugin:mechanism] flags: 259 2025-08-20 15:58:14.090 Db SecurityAgentHelper-arm64[818:1efd] [com.example.apple-samplecode.LoggingAuthPlugin:mechanism] reason: 0 2025-08-20 15:58:14.090 Db SecurityAgentHelper-arm64[818:1efd] [com.example.apple-samplecode.LoggingAuthPlugin:mechanism] tries: 1 2025-08-20 15:58:14.090 Db SecurityAgentHelper-arm64[818:1efd] [com.example.apple-samplecode.LoggingAuthPlugin:mechanism] immutable hints: 2025-08-20 15:58:14.090 Db SecurityAgentHelper-arm64[818:1efd] [com.example.apple-samplecode.LoggingAuthPlugin:mechanism] client-apple-signed: true 2025-08-20 15:58:14.090 Db SecurityAgentHelper-arm64[818:1efd] [com.example.apple-samplecode.LoggingAuthPlugin:mechanism] client-firstparty-signed: true 2025-08-20 15:58:14.090 Db SecurityAgentHelper-arm64[818:1efd] [com.example.apple-samplecode.LoggingAuthPlugin:mechanism] creator-apple-signed: true 2025-08-20 15:58:14.090 Db SecurityAgentHelper-arm64[818:1efd] [com.example.apple-samplecode.LoggingAuthPlugin:mechanism] creator-firstparty-signed: true 2025-08-20 15:58:14.091 Db SecurityAgentHelper-arm64[818:1efd] [com.example.apple-samplecode.LoggingAuthPlugin:mechanism] arguments: 2025-08-20 15:58:14.091 Db SecurityAgentHelper-arm64[818:1efd] [com.example.apple-samplecode.LoggingAuthPlugin:mechanism] none 2025-08-20 15:58:14.108 Db SecurityAgentHelper-arm64[818:1efd] [com.example.apple-samplecode.LoggingAuthPlugin:mechanism] LAContext: LAContext[4:8:112] 2025-08-20 15:58:14.119 Db SecurityAgentHelper-arm64[818:1efd] [com.example.apple-samplecode.LoggingAuthPlugin:mechanism] token identities: 0 2025-08-20 15:58:14.120 Db SecurityAgentHelper-arm64[818:1efd] [com.example.apple-samplecode.LoggingAuthPlugin:mechanism] token watcher: <TKTokenWatcher: 0x11410ee70> Specifically, is there a manual/link somewhere that can allow me to interpret: authentication-failure: --S -14090 and pam_result: X-S 9
2
0
313
Aug ’25
Unable to enable "Sign In with Apple" on Service ID – 501 PATCH Unsupported Request
Hello, I’m trying to set up Sign In with Apple for my Firebase Authentication integration. Steps I followed: Created a Service ID in Apple Developer, e.g. com.example.myapp.signin. Tried to enable Sign In with Apple and configure the Web Authentication Configuration. Web Domain: myapp.firebaseapp.com Return URL: https://myapp.firebaseapp.com/__/auth/handler When I click Save, I get the following error in the browser console and a blank response page: Unsupported Request PATCH to http://developer.apple.com/services-account/v1/bundleIds/XXXXXXXX not supported. Reference #... What I have verified so far: My Apple Developer Program membership is active (paid). My App ID (e.g. com.example.myapp) exists in Identifiers. The App ID has Sign In with Apple capability checked. I need to link the Service ID with this App ID for Firebase web-based auth. Goal: Complete setup of Apple as a sign-in provider in Firebase Authentication. To do this, Apple requires me to add the Firebase return URL above, but the Developer Portal prevents saving with the 501 error. Has anyone else run into this, and is there a workaround (e.g. enabling via Xcode, App Store Connect, or other methods)? Is this a known bug with the Apple Developer Portal? Here is the screenshot of the error: And Response part: Thanks in advance!
2
0
435
Aug ’25
Issue with "NSUserTrackingUsageDescription" Blocking App Update Submission
Hi everyone, I’m currently facing an issue while trying to submit an update for my app to the App Store. The review process is blocking the update due to a "Privacy - Data Use and Sharing" warning, stating that our app requests "tracking purchase history for tracking purposes." However, we have already removed this functionality and deleted the NSUserTrackingUsageDescription key from our latest build. Despite this, the warning persists, and we are unable to proceed with the update. I have already contacted Apple Support, but in the meantime, I wanted to ask the community: Has anyone else encountered this issue, and if so, how did you resolve it? Is there a way to force a refresh of privacy-related settings in App Store Connect? Are there any additional steps we need to take to completely remove this tracking flag from our app submission? Any insights or guidance would be greatly appreciated! Thanks in advance for your help.
2
1
594
Feb ’25
Why does my app lose Screen Recording permission after updating (adhoc signature)?
Hi everyone, I have a macOS application that uses Screen Recording permission. I build my app with an adhoc signature (not with a Developer ID certificate). For example, in version 1.0.0, I grant Screen Recording permission to the app. Later, I build a new version (1.1.0) and update by dragging the new app into the Applications folder to overwrite the previous one. However, when I launch the updated app, it asks for Screen Recording permission again, even though I have already granted it for the previous version. I don’t fully understand how TCC (Transparency, Consent, and Control) determines when permissions need to be re-granted. Can anyone explain how TCC manages permissions for updated builds, especially with adhoc signatures? Is there any way to retain permissions between updates, or any best practices to avoid having users re-authorize permissions after every update?
2
0
268
Aug ’25
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
269
Aug ’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
227
Jun ’25