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

mTLS : Guidance on Generating SecIdentity with Existing Private Key and Certificate
Hello, I am currently working on iOS application development using Swift, targeting iOS 17 and above, and need to implement mTLS for network connections. In the registration API flow, the app generates a private key and CSR on the device, sends the CSR to the server (via the registration API), and receives back the signed client certificate (CRT) along with the intermediate/CA certificate. These certificates are then imported on the device. The challenge I am facing is pairing the received CRT with the previously generated private key in order to create a SecIdentity. Could you please suggest the correct approach to generate a SecIdentity in this scenario? If there are any sample code snippets, WWDC videos, or documentation references available, I would greatly appreciate it if you could share them. Thank you for your guidance.
4
0
213
Aug ’25
Why can’t sandboxed mac app store apps have full disk access available in the system settings for full disk access?
Why can’t sandboxed mac app store apps have full disk access available in the system settings for full disk access? I discovered mac app store apps in release mode cannot access the ai auggie command line program and other command line programs like opengrep on your system. Debug builds fine. I came up with a workaround: Since I have an ssh client built in for connecting to remote servers, why not connect to ssh on the same local machine… Ask the user for their username and password in a popup. To do this, you have to enable remote login on your mac in system settings -> sharing. In addition you must grant full disk access to cli ssh in system settings: add /usr/libexec/sshd-keygen-wrapper It all works, but I don’t see the cli program in mac settings. To remove the cli program you must run a command line program to remove all full disk access support from all apps. No way to just undo ssh. So my question is, even though I got CodeFrog all working for a mac app store release, should I not do it because it’s insecure or too complicated with the system settings? Should I instead sell the app off the store like Panic Nova? Need some advice. I have not implemented in app purchases yet. Should I just have a reality check and sell the app off the store, or try for app store approval? Bummer… Maybe I’m ahead of my time, but perhaps Apple could review the source code for apps requesting full disk access and make sure there’s nothing fraudulent in them. Then, developer tools app store apps could be in the store with the user’s assurance that nothing is happening behind the scenes that is scary. From: https://blog.greenrobot.com/2025/11/10/i-have-a-decision-to-make/ Related post: https://developer.apple.com/forums/thread/806187 I submitted a code level tech support question for this. They directed me here.
4
0
411
Nov ’25
MacOS Authorisation Plugin Installation Strategy
I am developing an Authorisation Plugin which talks to Launch daemons over XPC. Above is working neat, now I have to decide on how to get it installed on a machine. Installation requires. Plugin Installation Launch Daemon Installation Both require Moving binary and text (.plist) file into privileged system managed directory. Firing install/load commands as root (sudo). I have referred this post BSD Privilege Escalation on macOS, but I am still not clear how to approach this. Q: My requirement is: I can use .pkg builder and install via script, however I have some initialisation task that needs to be performed. User will enter some details talk to a remote server and get some keys, all goes well restarts the system and my authorisation plugin will welcome him and get him started. If I cannot perform initialisation I will have to do it post restart on login screen which I want to avoid if possible. I tried unconventional way of using AppleScript from a SwiftUI application to run privileged commands, I am fine if it prompts for admin credentials, but it did not work. I don't want that I do something and when approving it from Apple it gets rejected. Basically, how can I provide some GUI to do initialisation during installation or may be an app which helps in this. Q: Please also guide if I am doing elevated actions, how will it affect app distribution mechanism. In Read Me for EvenBetterAuthorizationSample I read it does. Thanks.
4
0
145
Mar ’25
ASWebAuthenticationSession + Universal Links Callback Issue
Problem Description: In our App, When we launch the web login part using ASWebAuthentication + Universal Links with callback scheme as "https", we are not receiving callback. Note: We are using "SwiftUIWebAuthentication" Swift Package Manager to display page in ASWebAuth. But when we use custom url scheme instead of Universal link, app able to receive call back every time. We use ".onOpenURL" to receive universal link callback scheme.
4
0
236
Jul ’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
430
Feb ’25
Binary executable requires Accessibility Permissions in Tahoe
I have a binary executable which needs to be given Accessibility Permissions so it can inject keypresses and mouse moves. This was always possible up to macOS 15 - when the first keypress arrived the Accessibility Permissions window would open and allow me to add the executable. However this no longer works in macOS 26: the window still opens, I navigate to the executable file and select it but it doesn't appear in the list. No error message appears. I'm guessing that this may be due to some tightening of security in Tahoe but I need to figure out what to change with my executable to allow it to work.
4
2
749
2w
How to perform actions as root from GUI apps on macOS?
I'm building a tool for admins in the enterprise context. The app needs to do some things as root, such as executing a script. I was hoping to implement a workflow where the user clicks a button, then will be shown the authentication prompt, enter the credentials and then execute the desired action. However, I couldn't find a way to implement this. AuthorizationExecuteWithPrivileges looked promising, but that's deprecated since 10.7. I've now tried to use a launch daemon that's contained in the app bundle with XPC, but that seems overly complicated and has several downsides (daemon with global machservice and the approval of a launch daemon suggests to the user that something's always running in the background). Also I'd like to stream the output of the executed scripts in real time back to the UI which seems very complicated to implement in this fashion. Is there a better way to enable an app to perform authorized privilege escalation for certain actions? What about privileged helper tools? I couldn't find any documentation about them. I know privilege escalation is not allowed in the App Store, but that's not relevant for us.
4
0
516
Jan ’25
Using Cryptokit.SecureEnclave API from a Launch Daemon
We are interested in using a hardware-bound key in a launch daemon. In a previous post, Quinn explicitly told me this is not possible to use an SE keypair outside of the system context and my reading of the Apple documentation also supports that. That said, we have gotten the following key-creation and persistence flow to work, so we have some questions as to how this fits in with the above. (1) In a launch daemon (running thus as root), we do: let key = SecureEnclave.P256.Signing.PrivateKey() (2) We then use key.dataRepresentation to store a reference to the key in the system keychain as a kSecClassGenericPassword. (3) When we want to use the key, we fetch the data representation from system keychain and we "rehydrate" the key using: SecureEnclave.P256.Signing.PrivateKey(dataRepresentation: data) (4) We then use the output of the above to sign whatever we want. My questions: in the above flow, are we actually getting a hardware-bound key from the Secure Enclave or is this working because it's actually defaulting to a non-hardware-backed key? if it is an SE key, is it that the Apple documentation stating that you can only use the SE with the Data Protection Keychain in the user context is outdated (or wrong)? does the above work, but is not an approach sanctioned by Apple? Any feedback on this would be greatly appreciated.
4
0
507
Sep ’25
Strong Passwords with SecAccessControlCreateWithFlags
Hi everyone, I’ve been working on storing keys and passwords in the macOS Keychain using the Keychain Services API. Specifically, I’m leveraging SecAccessControlCreateWithFlags to bind items to access control flags, and overall, it’s been working smoothly. I have a question regarding the .applicationPassword flag of SecAccessControlCreateWithFlags. While it successfully prompts the user to input a password, there are no apparent password rules, even a simple “1” is accepted. My questions are: Is there a way to enforce strong password requirements when using the .applicationPassword flag? If enforcing strong passwords isn’t possible, is there an alternative approach to provide a predefined strong password during the creation process, bypassing the need for user input? With SecAccessControlCreateWithFlags, I noticed the item isn’t stored in the traditional file-based Keychain but in an iOS-style Keychain, is there a way to store it in a file-based Keychain while marking it as unexportable? I appreciate any insights or suggestions. Thank you! Neil
4
0
150
Mar ’25
SecTrustEvaluateAsyncWithError() and Certificate Transparency
For testing purposes we have code that calls SecTrustEvaluateAsyncWithError() with a trust object containing a hardcoded leaf certificate and the corresponding intermediate certificate required to form a valid chain. Because the leaf certificate has since expired we pass a date in the past via SecTrustSetVerifyDate() at wich the certificate was still valid, but trust evaluation fails: Error Domain=NSOSStatusErrorDomain Code=-67825 "“<redacted>” certificate is not standards compliant" UserInfo={NSLocalizedDescription=“<redacted>” certificate is not standards compliant, NSUnderlyingError=0x600000c282a0 {Error Domain=NSOSStatusErrorDomain Code=-67825 "Certificate 0 “<redacted>” has errors: Certificate Transparency validation required for this use;" UserInfo={NSLocalizedDescription=Certificate 0 “<redacted>” has errors: Certificate Transparency validation required for this use;}}} I know that App Transport Security enforces Certificate Transparency by default, but is there a way around that here?
4
0
493
Oct ’25
What is the code signing trust level?
In some crashlog files, there are additional pieces of information related to codesigning. I can understand what most of themcorresponds to (ID, TeamID, Flags, Validation Category). But there is one I have some doubt about: Trust Level. As far as I can tell (or at least what Google and other search engines say), this is an unsigned 32 bit integer that defines the trust level with -1 being untrusted, 0, being basically an Apple executable and other potential bigger values corresponding to App Store binaries, Developer ID signature, etc. Yet, I'm not able to find a corresponding detailed documentation about this on Apple's developer website. I also had a look at the LightweightCodeRequirements "include" file and there does not seem to be such a field available. [Q] Is there any official documentation listing the different values for this trust level value and providing a clear description of what it corresponds to?
4
0
264
Jul ’25
Unsandboxed app can't modify other app
I work for Brave, a browser with ~80M users. We want to introduce a new system for automatic updates called Omaha 4 (O4). It's the same system that powers automatic updates in Chrome. O4 runs as a separate application on users' systems. For Chrome, this works as follows: An app called GoogleUpdater.app regularly checks for updates in the background. When a new version is found, then GoogleUpdater.app installs it into Chrome's installation directory /Applications/Google Chrome.app. But consider what this means: A separate application, GoogleUpdater.app, is able to modify Google Chrome.app. This is especially surprising because, for example, the built-in Terminal.app is not able to modify Google Chrome.app. Here's how you can check this for yourself: (Re-)install Chrome with its DMG installer. Run the following command in Terminal: mkdir /Applications/Google\ Chrome.app/test. This works. Undo the command: rm -rf /Applications/Google\ Chrome.app/test Start Chrome and close it again. mkdir /Applications/Google\ Chrome.app/test now fails with "Operation not permitted". (These steps assume that Terminal does not have Full Disk Access and System Integrity Protection is enabled.) In other words, once Chrome was started at least once, another application (Terminal in this case) is no longer allowed to modify it. But at the same time, GoogleUpdater.app is able to modify Chrome. It regularly applies updates to the browser. For each update, this process begins with an mkdir call similarly to the one shown above. How is this possible? What is it in macOS that lets GoogleUpdater.app modify Chrome, but not another app such as Terminal? Note that Terminal is not sandboxed. I've checked that it's not related to codesigning or notarization issues. In our case, the main application (Brave) and the updater (BraveUpdater) are signed and notarized with the same certificate and have equivalent requirements, entitlements and provisioning profiles as Chrome and GoogleUpdater. The error that shows up in the Console for the disallowed mkdir call is: kernel (Sandbox) System Policy: mkdir(8917) deny(1) file-write-create /Applications/Google Chrome.app/foo (It's a similar error when BraveUpdater tries to install a new version into /Applications/Brave Browser.app.) The error goes away when I disable System Integrity Protection. But of course, we cannot ask users to do that. Any help would be greatly appreciated.
4
0
240
May ’25
Can child processes inherit Info.plist properties of a parent app (such as LSSupportsGameMode)?
My high-level goal is to add support for Game Mode in a Java game, which launches via a macOS "launcher" app that runs the actual java game as a separate process (e.g. using the java command line tool). I asked this over in the Graphics & Games section and was told this, which is why I'm reposting this here. I'm uncertain how to speak to CLI tools and Java games launched from a macOS app. These sound like security and sandboxing questions which we recommend you ask about in those sections of the forums. The system seems to decide whether to enable Game Mode based on values in the Info.plist (e.g. for LSApplicationCategoryType and GCSupportsGameMode). However, the child process can't seem to see these values. Is there a way to change that? (The rest of this post is copied from my other forums post to provide additional context.) Imagine a native macOS app that acts as a "launcher" for a Java game.** For example, the "launcher" app might use the Swift Process API or a similar method to run the java command line tool (lets assume the user has installed Java themselves) to run the game. I have seen How to Enable Game Mode. If the native launcher app's Info.plist has the following keys set: LSApplicationCategoryType set to public.app-category.games LSSupportsGameMode set to true (for macOS 26+) GCSupportsGameMode set to true The launcher itself can cause Game Mode to activate if the launcher is fullscreened. However, if the launcher opens a Java process that opens a window, then the Java window is fullscreened, Game Mode doesn't seem to activate. In this case activating Game Mode for the launcher itself is unnecessary, but you'd expect Game Mode to activate when the actual game in the Java window is fullscreened. Is there a way to get Game Mode to activate in the latter case? ** The concrete case I'm thinking of is a third-party Minecraft Java Edition launcher, but the issue can also be demonstrated in a sample project (FB13786152). It seems like the official Minecraft launcher is able to do this, though it's not clear how. (Is its bundle identifier hardcoded in the OS to allow for this? Changing a sample app's bundle identifier to be the same as the official Minecraft launcher gets the behavior I want, but obviously this is not a practical solution.)
3
0
237
Jun ’25
Creating machine identifier to be used by daemon based app
I am developing a daemon-based product that needs a cryptographic, non-spoofable proof of machine identity so a remote management server can grant permissions based on the physical machine. I was thinking to create a signing key in the Secure Enclave and use a certificate signed by that key as the machine identity. The problem is that the Secure Enclave key I can create is only accessible from user context, while my product runs as a system daemon and must not rely on user processes or launchAgents. Could you please advise on the recommended Apple-supported approaches for this use case ? Specifically, Is there a supported way for a system daemon to generate and use an unremovable Secure Enclave key during phases like the pre-logon, that doesn't have non user context (only the my application which created this key/certificate will have permission to use/delete it) If Secure Enclave access from a daemon is not supported, what Apple-recommended alternatives exist for providing a hardware-backed machine identity for system daemons? I'd rather avoid using system keychain, as its contents may be removed or used by root privileged users. The ideal solution would be that each Apple product, would come out with a non removable signing certificate, that represent the machine itself (lets say that the cetificate name use to represent the machine ID), and can be validated by verify that the root signer is "Apple Root CA"
3
0
564
Nov ’25
SecItemCopyMatching not saving permanent key
I am writing a MacOS app that uses the Apple crypto libraries to create, save, and use an RSA key pair. I am not using a Secure Enclave so that the private key can later the retrieved through the keychain. The problem I am running into is that on my and multiple other systems the creation and retrieval works fine. On a different system -- running MacOS 15.3 just like the working systems -- the SecKeyCreateRandomKey function appears to work fine and I get a key reference back, but on subsequent runs SecItemCopyMatching results in errSecItemNotFound. Why would it appear to save properly on some systems and not others? var error: Unmanaged<CFError>? let access = SecAccessControlCreateWithFlags(kCFAllocatorDefault, kSecAttrAccessibleWhenUnlockedThisDeviceOnly, .biometryAny, &error)! let tag = TAG.data(using: .utf8)! // com.example.myapp.rsakey let attributes: [String: Any] = [ kSecAttrKeyType as String: KEY_TYPE, // set to kSecAttrKeyTypeRSA kSecAttrKeySizeInBits as String: 3072, kSecPrivateKeyAttrs as String: [ kSecAttrIsPermanent as String: true, kSecAttrApplicationTag as String: tag, kSecAttrAccessControl as String: access, ], ] guard let newKey = SecKeyCreateRandomKey(attributes as CFDictionary, &error) else { throw error!.takeRetainedValue() as Error } return newKey This runs fine on both systems, getting a valid key reference that I can use. But then if I immediately try to pull the key, it works on my system but not the other. let query = [ kSecClass as String: kSecClassKey, kSecAttrApplicationTag as String: tag, kSecReturnRef as String: true, ] var item: CFTypeRef? let status = SecItemCopyMatching(query as CFDictionary, &item) let msg = SecCopyErrorMessageString(status, nil) if status == errSecItemNotFound { print("key not found") } guard status == errSecSuccess else { print("other retrieval error") } return item as! SecKey I've also tried a separate query using the secCall function from here (https://developer.apple.com/forums/thread/710961) that gets ALL kSecClassKey items before and after the "create the key" function and it'll report the same amount of keys before and after on the bugged system. On the other machines where it works, it'll show one more key as expected. In the Signing & Capabilities section of the project config, I have Keychain Sharing set up with a group like com.example.myapp where my key uses a tag like com.example.myapp.rsakey. The entitlements file has an associated entry for Keychain Access Groups with value $(AppIdentifierPrefix)com.example.myapp.
3
0
358
Feb ’25
Critical iOS Activation Vulnerability
There’s a critical, actively exploited vulnerability in Apple’s iOS activation servers allowing unauthenticated XML payload injection: https://cyberpress.org/apple-ios-activation-vulnerability/ This flaw targets the core activation process, bypassing normal security checks. Despite the severity, it’s barely discussed in public security channels. Why is this not being addressed or publicly acknowledged? Apple developers and security researchers should urgently review and audit activation flows—this is a direct attack vector on device trust integrity. Any insights or official response appreciated.
3
1
218
Jun ’25
Certificate Trust Failing in Latest OS Releases
Trying to apply 'always trust' to certificate added to keychain using both SecItemAdd() and SecPKCS12Import() with SecTrustSettingsSetTrustSettings(). I created a launchdaemon for this purpose. AuthorizationDB is modified so that any process running in root can apply trust to certificate. let option = SecTrustSettingsResult.trustRoot.rawValue // SecTrustSettingsResult.trustAsRoot.rawValue for non-root certificates let status = SecTrustSettingsSetTrustSettings(secCertificate, SecTrustSettingsDomain.admin, [kSecTrustSettingsResult: NSNumber(value: option.rawValue)] as CFTypeRef). Above code is used to trust certificates and it was working on os upto 14.7.4. In 14.7.5 SecTrustSettingsSetTrustSettings() returns errAuthorizationInteractionNotAllowed. In 15.5 modifying authorization db with AuthorizationRightSet() itself is returning errAuthorizationDenied.Tried manually editing authorization db via terminal and same error occurred. Did apple update anything on Security framework? Any other way to trust certificates?
3
0
168
Jun ’25