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

CryptoKitError
Hi, I am using CryptoKit in my app. I am getting an error sometimes with some users. I log the description to Firebase but I am not sure what is it exactly about.  CryptoKit.CryptoKitError error 2  CryptoKit.CryptoKitError error 3 I receive both of these errors. I also save debug prints to a log file and let users share them with me. Logs are line-by-line encrypted but after getting these errors in the app also decryption of log files doesn't work and it throws these errors too. I couldn't reproduce the same error by myself, and I can't reach the user's logs so I am a little blind about what triggers this. It would be helpful to understand what these errors mean. Thanks
3
0
1.6k
May ’25
Access Unix Socket from App Sandbox
Hello, I want to access the Docker socket API from inside the macOS App Sandbox. The method queries the API using curl with --unix-socket. However, the Sandbox blocks the request, as shown by the log: curl(22299) deny(1) network-outbound /Users/user/.docker/run/docker.sock Outgoing network traffic is generally allowed, but access to the Docker Unix socket is denied. Here’s the code I’m using: private func executeDockerAPI() -> String { let process = Process() let pipe = Pipe() process.executableURL = URL(fileURLWithPath: "/usr/bin/curl") process.arguments = [ "--unix-socket", "/Users/user/.docker/run/docker.sock", "http://127.0.0.1/containers/json" ] process.standardOutput = pipe process.standardError = pipe do { try process.run() process.waitUntilExit() let data = pipe.fileHandleForReading.readDataToEndOfFile() if let output = String(data: data, encoding: .utf8) { return output } else { return "Error while decoding" } } catch { return "Error running command: \(error.localizedDescription)" } } Is there any entitlement or sandbox configuration I’m missing to allow access to /Users/user/.docker/run/docker.sock from inside the sandbox?
8
0
374
Jul ’25
macOS App Keychain errSecAuthFailed after long run, restart fixes
I'm writing an app on macOS that stores passwords in the Keychain and later retrieves them using SecItemCopyMatching(). This works fine 90% of the time. However, occasionally, the call to SecItemCopyMatching() fails with errSecAuthFailed (-25293). When this occurs, simply restarting the app resolves the issue; otherwise, it will consistently fail with errSecAuthFailed. What I suspect is that the Keychain access permission has a time limitation for a process. This issue always seems to arise when I keep my app running for an extended period.
3
0
141
Apr ’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
386
Jun ’25
ASWebAuthenticationSession + https iOS <17.4
Hi everyone, I am trying to use ASWebAuthenticationSession to authorize user using OAuth2. Service Webcredentials is set. /.well-known/apple-app-site-association file is set. When using API for iOS > 17.4 using new init with callback: .https(...) everything works as expected, however i cannot make .init(url: ,callbackURLScheme: ....) to work. How can i intercept callback using iOS <17.4? Do I really need to use universal links? callbackURL = https://mydomain.com/auth/callback
1
0
511
Apr ’25
TKTokenSession not used
Hi, I'm working on developing my own CryptoTokenKit (CTK) extension to enable codesign with HSM-backed keys. Here's what I’ve done so far: The container app sets up the tokenConfiguration with TKTokenKeychainCertificate and TKTokenKeychainKey. The extension registers successfully and is visible via pluginkit when launching the container app. The virtual smartcard appears when running security list-smartcards. The certificate, key, and identity are all visible using security export-smartcard -i [card]. However, nothing appears in the Keychain. After adding logging and reviewing output in the Console, I’ve observed the following behavior when running codesign: My TKTokenSession is instantiated correctly, using my custom TKToken implementation — so far, so good. However, none of the following TKTokenSession methods are ever called: func tokenSession(_ session: TKTokenSession, beginAuthFor operation: TKTokenOperation, constraint: Any) throws -> TKTokenAuthOperation func tokenSession(_ session: TKTokenSession, supports operation: TKTokenOperation, keyObjectID: TKToken.ObjectID, algorithm: TKTokenKeyAlgorithm) -> Bool func tokenSession(_ session: TKTokenSession, sign dataToSign: Data, keyObjectID: Any, algorithm: TKTokenKeyAlgorithm) throws -> Data func tokenSession(_ session: TKTokenSession, decrypt ciphertext: Data, keyObjectID: Any, algorithm: TKTokenKeyAlgorithm) throws -> Data func tokenSession(_ session: TKTokenSession, performKeyExchange otherPartyPublicKeyData: Data, keyObjectID objectID: Any, algorithm: TKTokenKeyAlgorithm, parameters: TKTokenKeyExchangeParameters) throws -> Data The only relevant Console log is: default 11:31:15.453969+0200 PersistentToken [0x154d04850] invalidated because the client process (pid 4899) either cancelled the connection or exited There’s no crash report related to the extension, so my assumption is that ctkd is closing the connection for some unknown reason. Is there any way to debug this further? Thank you for your help.
3
0
147
Apr ’25
Application is not able to access any keychain info on application launch post device reboot
Before device Reboot: Here no issue from keychain. 2025-06-17 11:18:17.956334 +0530 WAVE PTX [DB_ENCRYPTION] Key successfully retrieved from the Keychain default When device is in reboot and locked (Keychain access is set to FirstUnlock) App got woken up in background SEEMS(NOT SURE) DEVICE STILL IN LOCKED STARE IF YES THEN WHICH IS EXPECTED 2025-06-17 12:12:30.036184 +0530 WAVE PTX <ALA_ERROR>: [OS-CCF] [DB_ENCRYPTION] Error while retriving Private key -25308 default 2025-06-17 12:15:28.914700 +0530 WAVE PTX <ALA_ERROR> [DB_ENCRYPTION] Error retrieving key from the Keychain: -25300 default —————————————————— And as per logs, here user has launch the application post unlock and application never got the keychain access here also. HERE STILL HAS ISSUE WITH KEYCHAIN ACCESS. 2025-06-17 12:52:55.640976 +0530 WAVE PTX DEBUG : willFinishLaunchingWithOptions default 2025-06-17 12:52:55.651371 +0530 WAVE PTX <ALA_ERROR> [DB_ENCRYPTION] Error retrieving key from the Keychain: -25300 default
7
0
197
Jul ’25
Submission Rejected: Guideline 5.1.1 - Legal - Privacy - Data Collection and Storage
Hello Experts, I am in need of your help with this feedback from the App Reviewer. Issue Description: One or more purpose strings in the app do not sufficiently explain the use of protected resources. Purpose strings must clearly and completely describe the app's use of data and, in most cases, provide an example of how the data will be used. Next Steps: Update the location purpose string to explain how the app will use the requested information and provide a specific example of how the data will be used. See the attached screenshot. Resources: Purpose strings must clearly describe how an app uses the ability, data, or resource. The following are hypothetical examples of unclear purpose strings that would not pass review: "App would like to access your Contacts" "App needs microphone access" Feedback #2 "Regarding 5.1.1, we understand why your app needs access to location. However, the permission request alert does not sufficiently explain this to your users before accessing the location. To resolve this issue, it would be appropriate to revise the location permission request, specify why your app needs access, and provide an example of how your app will use the user's data. To learn more about purpose string requirements, watch a video from App Review with tips for writing clear purpose strings. We look forward to reviewing your app once the appropriate changes have been made." May I know how can I update my purpose string? I appealed on the first feedback by explaining what is the purpose of it but got the Feedback #2. TYIA!!
1
0
262
Jun ’25
Problem with Private Access Token (PAT)
Since October 3rd, I've stopped receiving responses to the Private Access Tokens challenge. I'm using this link: https://demo-issuer.private-access-tokens.fastly.com/.well-known/token-issuer-directory. I receive tokens from Fastly and return a header to the iOS app, but then I don't receive another authentication request from iOS. The user has automatic verification enabled on their phone. The problem is global and affects all my mobile app users. Has anyone encountered a similar problem and found a solution?
16
0
2.1k
Dec ’25
Custom Authorization Plugin in Login Flow
What Has Been Implemented Replaced the default loginwindow:login with a custom authorization plugin. The plugin: Performs primary OTP authentication. Displays a custom password prompt. Validates the password using Open Directory (OD) APIs. Next Scenario was handling password change Password change is simulated via: sudo pwpolicy -u robo -setpolicy "newPasswordRequired=1" On next login: Plugin retrieves the old password. OD API returns kODErrorCredentialsPasswordChangeRequired. Triggers a custom change password window to collect and set new password. Issue Observed : After changing password: The user’s login keychain resets. Custom entries under the login keychain are removed. We have tried few solutions Using API, SecKeychainChangePassword(...) Using CLI, security set-keychain-password -o oldpwd -p newpwd ~/Library/Keychains/login.keychain-db These approaches appear to successfully change the keychain password, but: On launching Keychain Access, two password prompts appear, after authentication, Keychain Access window doesn't appear (no app visibility). Question: Is there a reliable way (API or CLI) to reset or update the user’s login keychain password from within the custom authorization plugin, so: The keychain is not reset or lost. Keychain Access works normally post-login. The password update experience is seamless. Thank you for your help and I appreciate your time and consideration
2
0
332
Jun ’25
Private Access Tokens - Documentation?
I cannot find any reference to this within the Apple developer documents (or certainly searching for multiple possible keywords yields no results). The only reference I can find is to documents written in support of its announcement in 2002: https://aninterestingwebsite.com/news/?id=huqjyh7k. Is there any further documentation on implementing or has the capability been deprecated?
1
0
420
Nov ’25
How to satisfy a custom Authorization Right?
I’m implementing a custom Authorization right with the following rule: &lt;key&gt;authenticate-user&lt;/key&gt; &lt;true/&gt; &lt;key&gt;allow-root&lt;/key&gt; &lt;true/&gt; &lt;key&gt;class&lt;/key&gt; &lt;string&gt;user&lt;/string&gt; &lt;key&gt;group&lt;/key&gt; &lt;string&gt;admin&lt;/string&gt; The currently logged-in user is a standard user, and I’ve created a hidden admin account, e.g. _hiddenadmin, which has UID≠0 but belongs to the admin group. From my Authorization Plug-in, I would like to programmatically satisfy this right using _hiddenadmin’s credentials, even though _hiddenadmin is not the logged-in user. My question: Is there a way to programmatically satisfy an authenticate-user right from an Authorization Plug-in using credentials of another (non-session) user?
5
0
179
Jul ’25
Permission requirements for LAContext's canEvaluatePolicy
Hi, I am developing an app that checks if biometric authentication capabilities (Face ID and Touch ID) are available on a device. I have a few questions: Do I need to include a privacy string in my app to use the LAContext's canEvaluatePolicy function? This function checks if biometric authentication is available on the device, but does not actually trigger the authentication. From my testing, it seems like a privacy declaration is only required when using LAContext's evaluatePolicy function, which would trigger the biometric authentication. Can you confirm if this is the expected behavior across all iOS versions and iPhone models? When exactly does the biometric authentication permission pop-up appear for users - is it when calling canEvaluatePolicy or evaluatePolicy? I want to ensure my users have a seamless experience. Please let me know if you have any insights on these questions. I want to make sure I'm handling the biometric authentication functionality correctly in my app. Thank you!
2
0
170
Jun ’25
Unable to change App Tracking configuration
I have reached out to support and they simply tell me they are unable to help me, first redirecting me to generic Apple support, after following up they provided the explanation that they only handle administrative tasks and to post on the forums. I am unable to change my App Tracking Transparency it provides no real error, though network traffic shows a 409 HTTP response from the backend API when trying to save. Here is a screenshot of the result when trying to save. Does anyone have any suggestions on how to get this resolved? I've commented back to the reviewers and they simply provided help documentation. I have a technical issue and am unable to get anyone to help resolve this.
2
0
373
Nov ’25
SecKeyCreateDecryptedDataWithParameters always fails with algo not supported
Attempting to DECRYPT a cipher message using the Apple API SecKeyCreateDecryptedData(privateKey, .rsaEncryptionOAEPSHA256, encryptedMessage). Decryption ALWAYS fails for every algorithm. SecKeyCreateDecryptedDataWithParameters Error: `Domain=NSOSStatusErrorDomain Code=-50 "algid:encrypt:RSA:OAEP:SHA256: algorithm not supported by the key &lt;SecKeyRef:('com.yubico.Authenticator.TokenExtension:5621CDF8560D4C412030886584EC4C9E394CC376DD9738B0CCBB51924FC26EB6') 0x3007fd150&gt;" UserInfo={numberOfErrorsDeep=0, NSDescription=algid:encrypt:RSA:OAEP:SHA256: algorithm not supported by the key &lt;SecKeyRef:('com.yubico.Authenticator.TokenExtension:5621CDF8560D4C412030886584EC4C9E394CC376DD9738B0CCBB51924FC26EB6') 0x3007fd150&gt;}` Decryption failed: SecKeyCreateDecryptedData returned nil. Error: One or more parameters passed to a function were not valid. When checking with SecKeyIsAlgorithmSupported(privateKey, .decrypt, &lt;ANYalgorithm&gt;) all algorithms fail. Btw - The privateKey does support decryption when retrieving the attributes. Important to know: The private key is a reference to an external private key placed in the iOS Keychain via a 3rd party CryptoTokenKit Extension app. When I perform, the SecKeyCreateSignature(...) and pass in the SAME privateKey reference, the OS automatically calls the 3rd party app to perform a successful signing with the private key that reside on a YubiKey. Here's my code for obtaining the private key reference from an Identity: func getKeyPairFromIdentity() -&gt; (privateKey: SecKey, publicKey: SecKey)? { let query = NSDictionary( dictionary: [ kSecClass as String: kSecClassIdentity, kSecAttrTokenID as String: self.tokenID!, kSecReturnRef as String: kCFBooleanTrue as Any ] ) var identityRef: CFTypeRef? let status = SecItemCopyMatching(query, &amp;identityRef) if status == errSecSuccess, let identity = identityRef { var privateKeyRef: SecKey? let keyStatus = SecIdentityCopyPrivateKey(identity as! SecIdentity, &amp;privateKeyRef) if keyStatus == errSecSuccess, let privateKey = privateKeyRef { let publicKey = SecKeyCopyPublicKey(privateKey) if let publicKey = publicKey { print("Private and public keys extracted successfully.") return (privateKey, publicKey) } else { print("Failed to extract public key from private key.") return nil } } else { print("SecIdentityCopyPrivateKey: Private key not found error: \(keyStatus)") return nil } } else { print("SecIdentity not found or error: \(status)") return nil } }
4
0
271
Apr ’25
Launch Constraint, SIP and legacy launchd plist
I have 2 basic questions related to Launch Constraints: [Q1] Are Launch Constraints supposed to work when SIP is disabled? From what I'm observing, when SIP is disabled, Launch Constraints (e.g. Launch Constraint Parent Process) are not enforced. I can understand that. But it's a bit confusing considering that the stack diagram in the WWDC 2023 session is placing the 'Environment Constraints' block under SIP, not above. Also the documentation only mentions SIP for the 'is-sip-protected' fact. [Q2] Is the SpawnConstraint key in legacy launchd plist files (i.e. inside /Library/Launch(Agents|Daemons)) officially supported? From what I'm seeing, it seems to be working when SIP is enabled. But the WWDC session and the documentation don't really talk about this case.
11
0
379
Jun ’25
LAContext.evaluatedPolicyDomainState change between major OS versions
The header documentation for the (deprecated) LAContext.evaluatedPolicyDomainState property contains the following: @warning Please note that the value returned by this property can change exceptionally between major OS versions even if the state of biometry has not changed. I noticed that the documentation for the new LAContext.domainState property does not contain a similar warning. I also found this related thread from 2016/17. Is the domainState property not susceptible to changes between major OS versions? Or is this generally not an issue anymore?
1
0
483
Oct ’25
Detecting SIM Swap and Implementing SIM Binding in iOS
Hi Forum, We’re building a security-focused SDK for iOS that includes SIM Binding and SIM Swap detection to help prevent fraud and unauthorised device access, particularly in the context of banking and fintech apps. We understand that iOS limits access to SIM-level data, and that previously available APIs (such as those in CoreTelephony, now deprecated from iOS 16 onwards) provide only limited support for these use cases. We have a few questions and would appreciate any guidance from the community or Apple engineers: Q1. Are there any best practices or Apple-recommended approaches for binding a SIM to a device or user account? Q2. Is there a reliable way to detect a SIM swap when the app is not running (e.g., via system callback, entitlement, or background mechanism)? Q3. Are fields like GID1, GID2, or ICCID accessible through any public APIs or entitlements (such as com.apple.coretelephony.IdentityAccess)? If so, what is the process to request access? Q4. For dual SIM and eSIM scenarios, is there a documented approach to identify which SIM is active or whether a SIM slot has changed? Q5. In a banking or regulated environment, is it possible for an app vendor (e.g., a bank) to acquire certain entitlements from Apple and securely expose that information to a security SDK like ours? What would be the compliant or recommended way to structure such a partnership? Thanks in advance for any insights!
1
0
555
Jul ’25
App Keychain will sync secitem from old device to new device
In my app, I use SecItem to store some data in the Keychain. I’d like to know — when a user sets up a new iPhone and transfers data from the old device, will those Keychain items be migrated or synced to the new device?
Replies
3
Boosts
0
Views
155
Activity
Jun ’25
CryptoKitError
Hi, I am using CryptoKit in my app. I am getting an error sometimes with some users. I log the description to Firebase but I am not sure what is it exactly about.  CryptoKit.CryptoKitError error 2  CryptoKit.CryptoKitError error 3 I receive both of these errors. I also save debug prints to a log file and let users share them with me. Logs are line-by-line encrypted but after getting these errors in the app also decryption of log files doesn't work and it throws these errors too. I couldn't reproduce the same error by myself, and I can't reach the user's logs so I am a little blind about what triggers this. It would be helpful to understand what these errors mean. Thanks
Replies
3
Boosts
0
Views
1.6k
Activity
May ’25
Access Unix Socket from App Sandbox
Hello, I want to access the Docker socket API from inside the macOS App Sandbox. The method queries the API using curl with --unix-socket. However, the Sandbox blocks the request, as shown by the log: curl(22299) deny(1) network-outbound /Users/user/.docker/run/docker.sock Outgoing network traffic is generally allowed, but access to the Docker Unix socket is denied. Here’s the code I’m using: private func executeDockerAPI() -> String { let process = Process() let pipe = Pipe() process.executableURL = URL(fileURLWithPath: "/usr/bin/curl") process.arguments = [ "--unix-socket", "/Users/user/.docker/run/docker.sock", "http://127.0.0.1/containers/json" ] process.standardOutput = pipe process.standardError = pipe do { try process.run() process.waitUntilExit() let data = pipe.fileHandleForReading.readDataToEndOfFile() if let output = String(data: data, encoding: .utf8) { return output } else { return "Error while decoding" } } catch { return "Error running command: \(error.localizedDescription)" } } Is there any entitlement or sandbox configuration I’m missing to allow access to /Users/user/.docker/run/docker.sock from inside the sandbox?
Replies
8
Boosts
0
Views
374
Activity
Jul ’25
macOS App Keychain errSecAuthFailed after long run, restart fixes
I'm writing an app on macOS that stores passwords in the Keychain and later retrieves them using SecItemCopyMatching(). This works fine 90% of the time. However, occasionally, the call to SecItemCopyMatching() fails with errSecAuthFailed (-25293). When this occurs, simply restarting the app resolves the issue; otherwise, it will consistently fail with errSecAuthFailed. What I suspect is that the Keychain access permission has a time limitation for a process. This issue always seems to arise when I keep my app running for an extended period.
Replies
3
Boosts
0
Views
141
Activity
Apr ’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
386
Activity
Jun ’25
ASWebAuthenticationSession + https iOS <17.4
Hi everyone, I am trying to use ASWebAuthenticationSession to authorize user using OAuth2. Service Webcredentials is set. /.well-known/apple-app-site-association file is set. When using API for iOS > 17.4 using new init with callback: .https(...) everything works as expected, however i cannot make .init(url: ,callbackURLScheme: ....) to work. How can i intercept callback using iOS <17.4? Do I really need to use universal links? callbackURL = https://mydomain.com/auth/callback
Replies
1
Boosts
0
Views
511
Activity
Apr ’25
TKTokenSession not used
Hi, I'm working on developing my own CryptoTokenKit (CTK) extension to enable codesign with HSM-backed keys. Here's what I’ve done so far: The container app sets up the tokenConfiguration with TKTokenKeychainCertificate and TKTokenKeychainKey. The extension registers successfully and is visible via pluginkit when launching the container app. The virtual smartcard appears when running security list-smartcards. The certificate, key, and identity are all visible using security export-smartcard -i [card]. However, nothing appears in the Keychain. After adding logging and reviewing output in the Console, I’ve observed the following behavior when running codesign: My TKTokenSession is instantiated correctly, using my custom TKToken implementation — so far, so good. However, none of the following TKTokenSession methods are ever called: func tokenSession(_ session: TKTokenSession, beginAuthFor operation: TKTokenOperation, constraint: Any) throws -> TKTokenAuthOperation func tokenSession(_ session: TKTokenSession, supports operation: TKTokenOperation, keyObjectID: TKToken.ObjectID, algorithm: TKTokenKeyAlgorithm) -> Bool func tokenSession(_ session: TKTokenSession, sign dataToSign: Data, keyObjectID: Any, algorithm: TKTokenKeyAlgorithm) throws -> Data func tokenSession(_ session: TKTokenSession, decrypt ciphertext: Data, keyObjectID: Any, algorithm: TKTokenKeyAlgorithm) throws -> Data func tokenSession(_ session: TKTokenSession, performKeyExchange otherPartyPublicKeyData: Data, keyObjectID objectID: Any, algorithm: TKTokenKeyAlgorithm, parameters: TKTokenKeyExchangeParameters) throws -> Data The only relevant Console log is: default 11:31:15.453969+0200 PersistentToken [0x154d04850] invalidated because the client process (pid 4899) either cancelled the connection or exited There’s no crash report related to the extension, so my assumption is that ctkd is closing the connection for some unknown reason. Is there any way to debug this further? Thank you for your help.
Replies
3
Boosts
0
Views
147
Activity
Apr ’25
Application is not able to access any keychain info on application launch post device reboot
Before device Reboot: Here no issue from keychain. 2025-06-17 11:18:17.956334 +0530 WAVE PTX [DB_ENCRYPTION] Key successfully retrieved from the Keychain default When device is in reboot and locked (Keychain access is set to FirstUnlock) App got woken up in background SEEMS(NOT SURE) DEVICE STILL IN LOCKED STARE IF YES THEN WHICH IS EXPECTED 2025-06-17 12:12:30.036184 +0530 WAVE PTX <ALA_ERROR>: [OS-CCF] [DB_ENCRYPTION] Error while retriving Private key -25308 default 2025-06-17 12:15:28.914700 +0530 WAVE PTX <ALA_ERROR> [DB_ENCRYPTION] Error retrieving key from the Keychain: -25300 default —————————————————— And as per logs, here user has launch the application post unlock and application never got the keychain access here also. HERE STILL HAS ISSUE WITH KEYCHAIN ACCESS. 2025-06-17 12:52:55.640976 +0530 WAVE PTX DEBUG : willFinishLaunchingWithOptions default 2025-06-17 12:52:55.651371 +0530 WAVE PTX <ALA_ERROR> [DB_ENCRYPTION] Error retrieving key from the Keychain: -25300 default
Replies
7
Boosts
0
Views
197
Activity
Jul ’25
Submission Rejected: Guideline 5.1.1 - Legal - Privacy - Data Collection and Storage
Hello Experts, I am in need of your help with this feedback from the App Reviewer. Issue Description: One or more purpose strings in the app do not sufficiently explain the use of protected resources. Purpose strings must clearly and completely describe the app's use of data and, in most cases, provide an example of how the data will be used. Next Steps: Update the location purpose string to explain how the app will use the requested information and provide a specific example of how the data will be used. See the attached screenshot. Resources: Purpose strings must clearly describe how an app uses the ability, data, or resource. The following are hypothetical examples of unclear purpose strings that would not pass review: "App would like to access your Contacts" "App needs microphone access" Feedback #2 "Regarding 5.1.1, we understand why your app needs access to location. However, the permission request alert does not sufficiently explain this to your users before accessing the location. To resolve this issue, it would be appropriate to revise the location permission request, specify why your app needs access, and provide an example of how your app will use the user's data. To learn more about purpose string requirements, watch a video from App Review with tips for writing clear purpose strings. We look forward to reviewing your app once the appropriate changes have been made." May I know how can I update my purpose string? I appealed on the first feedback by explaining what is the purpose of it but got the Feedback #2. TYIA!!
Replies
1
Boosts
0
Views
262
Activity
Jun ’25
Problem with Private Access Token (PAT)
Since October 3rd, I've stopped receiving responses to the Private Access Tokens challenge. I'm using this link: https://demo-issuer.private-access-tokens.fastly.com/.well-known/token-issuer-directory. I receive tokens from Fastly and return a header to the iOS app, but then I don't receive another authentication request from iOS. The user has automatic verification enabled on their phone. The problem is global and affects all my mobile app users. Has anyone encountered a similar problem and found a solution?
Replies
16
Boosts
0
Views
2.1k
Activity
Dec ’25
Custom Authorization Plugin in Login Flow
What Has Been Implemented Replaced the default loginwindow:login with a custom authorization plugin. The plugin: Performs primary OTP authentication. Displays a custom password prompt. Validates the password using Open Directory (OD) APIs. Next Scenario was handling password change Password change is simulated via: sudo pwpolicy -u robo -setpolicy "newPasswordRequired=1" On next login: Plugin retrieves the old password. OD API returns kODErrorCredentialsPasswordChangeRequired. Triggers a custom change password window to collect and set new password. Issue Observed : After changing password: The user’s login keychain resets. Custom entries under the login keychain are removed. We have tried few solutions Using API, SecKeychainChangePassword(...) Using CLI, security set-keychain-password -o oldpwd -p newpwd ~/Library/Keychains/login.keychain-db These approaches appear to successfully change the keychain password, but: On launching Keychain Access, two password prompts appear, after authentication, Keychain Access window doesn't appear (no app visibility). Question: Is there a reliable way (API or CLI) to reset or update the user’s login keychain password from within the custom authorization plugin, so: The keychain is not reset or lost. Keychain Access works normally post-login. The password update experience is seamless. Thank you for your help and I appreciate your time and consideration
Replies
2
Boosts
0
Views
332
Activity
Jun ’25
Private Access Tokens - Documentation?
I cannot find any reference to this within the Apple developer documents (or certainly searching for multiple possible keywords yields no results). The only reference I can find is to documents written in support of its announcement in 2002: https://aninterestingwebsite.com/news/?id=huqjyh7k. Is there any further documentation on implementing or has the capability been deprecated?
Replies
1
Boosts
0
Views
420
Activity
Nov ’25
How to satisfy a custom Authorization Right?
I’m implementing a custom Authorization right with the following rule: &lt;key&gt;authenticate-user&lt;/key&gt; &lt;true/&gt; &lt;key&gt;allow-root&lt;/key&gt; &lt;true/&gt; &lt;key&gt;class&lt;/key&gt; &lt;string&gt;user&lt;/string&gt; &lt;key&gt;group&lt;/key&gt; &lt;string&gt;admin&lt;/string&gt; The currently logged-in user is a standard user, and I’ve created a hidden admin account, e.g. _hiddenadmin, which has UID≠0 but belongs to the admin group. From my Authorization Plug-in, I would like to programmatically satisfy this right using _hiddenadmin’s credentials, even though _hiddenadmin is not the logged-in user. My question: Is there a way to programmatically satisfy an authenticate-user right from an Authorization Plug-in using credentials of another (non-session) user?
Replies
5
Boosts
0
Views
179
Activity
Jul ’25
Permission requirements for LAContext's canEvaluatePolicy
Hi, I am developing an app that checks if biometric authentication capabilities (Face ID and Touch ID) are available on a device. I have a few questions: Do I need to include a privacy string in my app to use the LAContext's canEvaluatePolicy function? This function checks if biometric authentication is available on the device, but does not actually trigger the authentication. From my testing, it seems like a privacy declaration is only required when using LAContext's evaluatePolicy function, which would trigger the biometric authentication. Can you confirm if this is the expected behavior across all iOS versions and iPhone models? When exactly does the biometric authentication permission pop-up appear for users - is it when calling canEvaluatePolicy or evaluatePolicy? I want to ensure my users have a seamless experience. Please let me know if you have any insights on these questions. I want to make sure I'm handling the biometric authentication functionality correctly in my app. Thank you!
Replies
2
Boosts
0
Views
170
Activity
Jun ’25
Unable to change App Tracking configuration
I have reached out to support and they simply tell me they are unable to help me, first redirecting me to generic Apple support, after following up they provided the explanation that they only handle administrative tasks and to post on the forums. I am unable to change my App Tracking Transparency it provides no real error, though network traffic shows a 409 HTTP response from the backend API when trying to save. Here is a screenshot of the result when trying to save. Does anyone have any suggestions on how to get this resolved? I've commented back to the reviewers and they simply provided help documentation. I have a technical issue and am unable to get anyone to help resolve this.
Replies
2
Boosts
0
Views
373
Activity
Nov ’25
Is there a way for MDM to push a unique mTLS certificate w/ our Application?
Hi, It may be a stupid question, but we really wonder if there is a way for MDM to push a unique mTLS cert to our iOS application or if it can populate a client certificate in the iOS where our application can access it. Like browser app, how do browser mTLS certs get pushed? Thanks, Ying
Replies
2
Boosts
0
Views
827
Activity
Apr ’25
SecKeyCreateDecryptedDataWithParameters always fails with algo not supported
Attempting to DECRYPT a cipher message using the Apple API SecKeyCreateDecryptedData(privateKey, .rsaEncryptionOAEPSHA256, encryptedMessage). Decryption ALWAYS fails for every algorithm. SecKeyCreateDecryptedDataWithParameters Error: `Domain=NSOSStatusErrorDomain Code=-50 "algid:encrypt:RSA:OAEP:SHA256: algorithm not supported by the key &lt;SecKeyRef:('com.yubico.Authenticator.TokenExtension:5621CDF8560D4C412030886584EC4C9E394CC376DD9738B0CCBB51924FC26EB6') 0x3007fd150&gt;" UserInfo={numberOfErrorsDeep=0, NSDescription=algid:encrypt:RSA:OAEP:SHA256: algorithm not supported by the key &lt;SecKeyRef:('com.yubico.Authenticator.TokenExtension:5621CDF8560D4C412030886584EC4C9E394CC376DD9738B0CCBB51924FC26EB6') 0x3007fd150&gt;}` Decryption failed: SecKeyCreateDecryptedData returned nil. Error: One or more parameters passed to a function were not valid. When checking with SecKeyIsAlgorithmSupported(privateKey, .decrypt, &lt;ANYalgorithm&gt;) all algorithms fail. Btw - The privateKey does support decryption when retrieving the attributes. Important to know: The private key is a reference to an external private key placed in the iOS Keychain via a 3rd party CryptoTokenKit Extension app. When I perform, the SecKeyCreateSignature(...) and pass in the SAME privateKey reference, the OS automatically calls the 3rd party app to perform a successful signing with the private key that reside on a YubiKey. Here's my code for obtaining the private key reference from an Identity: func getKeyPairFromIdentity() -&gt; (privateKey: SecKey, publicKey: SecKey)? { let query = NSDictionary( dictionary: [ kSecClass as String: kSecClassIdentity, kSecAttrTokenID as String: self.tokenID!, kSecReturnRef as String: kCFBooleanTrue as Any ] ) var identityRef: CFTypeRef? let status = SecItemCopyMatching(query, &amp;identityRef) if status == errSecSuccess, let identity = identityRef { var privateKeyRef: SecKey? let keyStatus = SecIdentityCopyPrivateKey(identity as! SecIdentity, &amp;privateKeyRef) if keyStatus == errSecSuccess, let privateKey = privateKeyRef { let publicKey = SecKeyCopyPublicKey(privateKey) if let publicKey = publicKey { print("Private and public keys extracted successfully.") return (privateKey, publicKey) } else { print("Failed to extract public key from private key.") return nil } } else { print("SecIdentityCopyPrivateKey: Private key not found error: \(keyStatus)") return nil } } else { print("SecIdentity not found or error: \(status)") return nil } }
Replies
4
Boosts
0
Views
271
Activity
Apr ’25
Launch Constraint, SIP and legacy launchd plist
I have 2 basic questions related to Launch Constraints: [Q1] Are Launch Constraints supposed to work when SIP is disabled? From what I'm observing, when SIP is disabled, Launch Constraints (e.g. Launch Constraint Parent Process) are not enforced. I can understand that. But it's a bit confusing considering that the stack diagram in the WWDC 2023 session is placing the 'Environment Constraints' block under SIP, not above. Also the documentation only mentions SIP for the 'is-sip-protected' fact. [Q2] Is the SpawnConstraint key in legacy launchd plist files (i.e. inside /Library/Launch(Agents|Daemons)) officially supported? From what I'm seeing, it seems to be working when SIP is enabled. But the WWDC session and the documentation don't really talk about this case.
Replies
11
Boosts
0
Views
379
Activity
Jun ’25
LAContext.evaluatedPolicyDomainState change between major OS versions
The header documentation for the (deprecated) LAContext.evaluatedPolicyDomainState property contains the following: @warning Please note that the value returned by this property can change exceptionally between major OS versions even if the state of biometry has not changed. I noticed that the documentation for the new LAContext.domainState property does not contain a similar warning. I also found this related thread from 2016/17. Is the domainState property not susceptible to changes between major OS versions? Or is this generally not an issue anymore?
Replies
1
Boosts
0
Views
483
Activity
Oct ’25
Detecting SIM Swap and Implementing SIM Binding in iOS
Hi Forum, We’re building a security-focused SDK for iOS that includes SIM Binding and SIM Swap detection to help prevent fraud and unauthorised device access, particularly in the context of banking and fintech apps. We understand that iOS limits access to SIM-level data, and that previously available APIs (such as those in CoreTelephony, now deprecated from iOS 16 onwards) provide only limited support for these use cases. We have a few questions and would appreciate any guidance from the community or Apple engineers: Q1. Are there any best practices or Apple-recommended approaches for binding a SIM to a device or user account? Q2. Is there a reliable way to detect a SIM swap when the app is not running (e.g., via system callback, entitlement, or background mechanism)? Q3. Are fields like GID1, GID2, or ICCID accessible through any public APIs or entitlements (such as com.apple.coretelephony.IdentityAccess)? If so, what is the process to request access? Q4. For dual SIM and eSIM scenarios, is there a documented approach to identify which SIM is active or whether a SIM slot has changed? Q5. In a banking or regulated environment, is it possible for an app vendor (e.g., a bank) to acquire certain entitlements from Apple and securely expose that information to a security SDK like ours? What would be the compliant or recommended way to structure such a partnership? Thanks in advance for any insights!
Replies
1
Boosts
0
Views
555
Activity
Jul ’25