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

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
212
Jun ’25
Issue with DCAppAttestService for offloaded app
Hi, When calling generateAssertion on DCAppAttestService.shared, it gives invalidKey error when there was an update for an offloaded app. The offloading and reinstall always works fine if it is the same version on app store that was offloaded from device, but if there is an update and the app tries to reuse the keyID from previous installation for generateAssertion, attestation service rejects the key with error code 3 (invalid key) for a significant portion of our user. In our internal testing it failed for more than a third of the update attempts. STEPS TO REPRODUCE: install v1 from app store generate key using DCAppAttestService.shared.generateKey Attest this key using DCAppAttestService.shared.attestKey Send the attestation objection to our server and verify with apple servers Generate assertions for network calls to backend using DCAppAttestService.shared.generateAssertion with keyID from step 2 Device offloads the app (manually triggered by user, or automatically by iOS) A new version v2 is published to App Store Use tries to open the app Latest version is download from the App Store App tries to use the keyID from step 2 to generate assertions DCAppAttestService throws invalidKey error (Error Domain=com.apple.devicecheck.error Code=3) Step 7 is critical here, if there is no new version of the app, the reinstalled v1 can reuse the key from step 2 without any issues Is this behaviour expected? Is there any way we can make sure the key is preserved between offloaded app updates? Thanks
4
0
499
Feb ’25
identifierForVendor Changing Unexpectedly in Some Cases (App Store Builds)
We’ve noticed an unexpected behavior in our production iOS app where the UIDevice.current.identifierForVendor value occasionally changes, even though: The app is distributed via the App Store (not TestFlight or Xcode builds) We do not switch provisioning profiles or developer accounts No App Clips, App Thinning, or other advanced features are in use There’s no manual reinstall or device reset in the scenarios observed (as per user feedback) Any insights or confirmations would be much appreciated. Thanks!
1
0
172
Apr ’25
Unit tests and persistent tokens
I'd like to implement unit tests that exercise keys made available via a persistent token interface. However, when attempting to list available tokens by passing kSecAttrAccessGroupToken as the kSecAttrAccessGroup to SecItemCopyMatching from a unit test, -34018 is returned. It succeeds without the kSecAttrAccessGroup, which makes sense given the unit test binary does not have com.apple.token Keychain Group. The Xcode UI indicates "Capabilities are not supported" for the unit test binary when attempting to add a Keychain Sharing capability to enable use of persistent tokens. This feels like a dead end but begs the question is there any way to implement unit tests to exercise a persistent token interface? It seems like the only path may be write unit tests that drive an independent app that handles the interactions with the persistent token.
1
0
511
Feb ’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
109
Apr ’25
Something odd with Endpoint Security & was_mapped_writable
I'm seeing some odd behavior which may be a bug. I've broken it down to a least common denominator to reproduce it. But maybe I'm doing something wrong. I am opening a file read-write. I'm then mapping the file read-only and private: void* pointer = mmap(NULL, 17, PROT_READ, MAP_FILE | MAP_PRIVATE, fd, 0); I then unmap the memory and close the file. After the close, eslogger shows me this: {"close":{"modified":false,[...],"was_mapped_writable":false}} Which makes sense. I then change the mmap statement to: void* pointer = mmap(NULL, 17, PROT_READ, MAP_FILE | MAP_SHARED, fd, 0); I run the new code and and the close looks like: {"close":{"modified":false, [....], "was_mapped_writable":true}} Which also makes sense. I then run the original again (ie, with MAP_PRIVATE vs. MAP_SHARED) and the close looks like: {"close":{"modified":false,"was_mapped_writable":true,[...]} Which doesn't appear to be correct. Now if I just open and close the file (again, read-write) and don't mmap anything the close still shows: {"close":{ [...], "was_mapped_writable":true,"modified":false}} And the same is true if I open the file read-only. It will remain that way until I delete the file. If I recreate the file and try again, everything is good until I map it MAP_SHARED. I tried this with macOS 13.6.7 and macOS 15.0.1.
3
0
736
Oct ’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
126
Apr ’25
suddenly 'zsh: killed' my Xcode-based console app
I have a small command-line app I've been using for years to process files. I have it run by an Automator script, so that I can drop files onto it. It stopped working this morning. At first, I could still run the app from the command line, without Automator. But then after I recompiled the app, now I cannot even do that. When I run it, it's saying 'zsh: killed' followed by my app's path. What is that? The app does run if I run it from Xcode. How do I fix this?
3
0
603
Feb ’25
How to Programmatically Install and Trust Root Certificate in System Keychain
I am developing a macOS application (targeting macOS 13 and later) that is non-sandboxed and needs to install and trust a root certificate by adding it to the System keychain programmatically. I’m fine with prompting the user for admin privileges or password, if needed. So far, I have attempted to execute the following command programmatically from both: A user-level process A root-level process sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain /path/to/cert.pem While the certificate does get installed, it does not appear as trusted in the Keychain Access app. One more point: The app is not distributed via MDM. App will be distributed out side the app store. Questions: What is the correct way to programmatically install and trust a root certificate in the System keychain? Does this require additional entitlements, signing, or profile configurations? Is it possible outside of MDM management? Any guidance or working samples would be greatly appreciated.
3
0
377
Jul ’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 <SecKeyRef:('com.yubico.Authenticator.TokenExtension:5621CDF8560D4C412030886584EC4C9E394CC376DD9738B0CCBB51924FC26EB6') 0x3007fd150>" UserInfo={numberOfErrorsDeep=0, NSDescription=algid:encrypt:RSA:OAEP:SHA256: algorithm not supported by the key <SecKeyRef:('com.yubico.Authenticator.TokenExtension:5621CDF8560D4C412030886584EC4C9E394CC376DD9738B0CCBB51924FC26EB6') 0x3007fd150>}` Decryption failed: SecKeyCreateDecryptedData returned nil. Error: One or more parameters passed to a function were not valid. When checking with SecKeyIsAlgorithmSupported(privateKey, .decrypt, <ANYalgorithm>) 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() -> (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, &identityRef) if status == errSecSuccess, let identity = identityRef { var privateKeyRef: SecKey? let keyStatus = SecIdentityCopyPrivateKey(identity as! SecIdentity, &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
246
Apr ’25
Impact of Security Vulnerabilities Caused by Enabling "Generate Debug Symbols"
We are working with an iOS app where we have enabled the “Generate Debug Symbols” setting to true in Xcode. As a result, the .dSYM files are generated and utilized in Firebase Crashlytics for crash reporting. However, we received a note in our Vulnerability Assessment report indicating a potential security concern. The report mentions that the .ipa file could be reverse-engineered due to the presence of debug symbols, and that such symbols should not be included in a released app. We could not find any security-related information about this flag, “Generate Debug Symbols,” in Apple’s documentation. Could you please clarify if enabling the “Generate Debug Symbols” flag in Xcode for a production app creates any security vulnerabilities, such as the one described in the report? The report mentions the following vulnerability: TEST-0219: Testing for Debugging Symbols The concern raised is that debugging symbols, while useful for crash symbolication, may be leveraged to reverse-engineer the app and should not be present in a production release. Your prompt confirmation on this matter would be greatly appreciated. Thank you in advance for your assistance.
1
0
551
Mar ’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
272
Jun ’25
Transfer an application between accounts with an existing App Group
Due to business requirements, we need to transfer our app Gem Space for iOS from our current Apple Developer account to a new account. We have a major concern regarding our users and the data associated with the app. The user data is currently stored using an App Group with the identifier, for example: "group.com.app.sharedData" According to some information we’ve found, it might be possible to complete the transfer by removing the App Group from the old account and creating a new one with the same identifier in the new account. However, other sources suggest that App Group containers are owned by the specific team, and data stored in the container may become inaccessible after the app is transferred to a different team. This raises concerns about the possibility of users losing access to their data after updating the app from the new account. Could you please clarify the expected behavior of App Groups in this case? Do we need to perform any kind of data migration, and if so, could you please provide detailed guidance on how to do it safely and without impacting user data access?
2
0
90
Apr ’25
Gate Keeper Issue
Hi, I develop a Mac application, initially on Catalina/Xcode12, but I recently upgrade to Monterey/Xcode13. I'm about to publish a new version: on Monterey all works as expected, but when I try the app on Sequoia, as a last step before uploading to the App Store, I encountered some weird security issues: The main symptom is that it's no longer possible to save any file from the app using the Save panel, although the User Select File entitlement is set to Read/Write. I've tried reinstalling different versions of the app, including the most recent downloaded from TestFlight. But, whatever the version, any try to save using the panel (e.g. on the desktop) results in a warning telling that I don't have authorization to record the file to that folder. Moreover, when I type spctl -a -t exec -v /Applications/***.app in the terminal, it returns rejected, even when the application has been installed by TestFlight. An EtreCheck report tells that my app is not signed, while codesign -dv /Applications/***.app returns a valid signature. I'm lost... It suspect a Gate Keeper problem, but I cannot found any info on the web about how this system could be reset. I tried sudo spctl --reset-default, but it returns This operation is no longer supported... I wonder if these symptoms depend on how the app is archived and could be propagated to my final users, or just related to a corrupted install of Sequoia on my local machine. My feeling is that a signature problem should have been detected by the archive validation, but how could we be sure? Any idea would be greatly appreciated, thanks!
3
0
682
Feb ’25
Is it possible to launch a GUI application that is not killable by the logged in user
I'm trying to develop a GUI app on macOS that takes control of the screen so that user must perform certain actions before regaining control of the desktop. I don't want the user to be able to kill the process (for example via an "assassin" shell script that looks for the process and terminates it with kill). Based on this post it is not possible to create an unkillable process on macOS. I'm wondering, however, if it's possible to run the GUI process in root (or with other escalated privileges) such that the logged in user cannot kill it. So it's killable, but you need privileges above what the logged in user has (assuming they are not root). I'm not worried about a root user being able to kill it. Such an app would run in a managed context. I've played around with Service Background Tasks, but so far haven't found what I'm looking for. I'm hoping someone (especially from Apple) might be able to tell me if this goal is even achievable with macOS Sequoia (and beyond).
8
0
203
May ’25
Unable to add "One Time Codes" support to my app
I'm working on a Password Manager app that integrates with the AutoFill Credential Provider to provide stored passwords and OTPs to the user within Safari and other apps. Password AutoFill works perfectly. I'm unable to get iOS to register that the app supports OTPs though. I've followed the Apple documentation here: https://developer.apple.com/documentation/authenticationservices/providing-one-time-passcodes-to-autofill and added "ProvidesOneTimeCodes" to the AutoFill extension's Info.plist, but iOS just doesn't seem to notice the OTP support. <key>ASCredentialProviderExtensionCapabilities</key> <dict> <key>ProvidesOneTimeCodes</key> <true/> <key>ProvidesPasswords</key> <true/> </dict> Any help would be greatly appreicated!
1
0
394
Mar ’25
Whether non-Apple Store mac apps can use passkey?
Our desktop app for macos will be released in 2 channels appstore dmg package on our official website for users to download and install Now when we debug with passkey, we find that the package name of the appstore can normally arouse passkey, but the package name of the non-App Store can not arouse the passkey interface I need your help. Thank you
2
0
776
Apr ’25
Multiple views in SFAuthorizationPluginView
Hi there, I'm trying to use SFAuthorizationPluginView in order to show some fields in the login screen, have the user click the arrow, then continue to show more fields as a second step of authentication. How can I accomplish this? Register multiple SecurityAgentPlugins each with their own mechanism and nib? Some how get MacOS to call my SFAuthorizationPluginView::view() and return a new view? Manually remove text boxes and put in new ones when button is pressed I don't believe 1 works, for the second mechanism ended up calling the first mechanism's view's view() Cheers, -Ken
2
0
156
May ’25