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

All subtopics
Posts under Privacy & Security topic

Post

Replies

Boosts

Views

Activity

Endpoint Security Framework Bug: setuid Event Incorrectly Attributed to Parent Process During posix_spawn
Feedback ticket ID: FB21797397 Summary When using posix_spawn() with posix_spawnattr_set_uid_np() to spawn a child process with a different UID, the eslogger incorrectly reports a setuid event as an event originating from the parent process instead of the child process. Steps to Reproduce Create a binary that do the following: Configure posix_spawnattr_t that set the process UIDs to some other user ID (I'll use 501 in this example). Uses posix_spawn() to spawn a child process Run eslogger with the event types setuid, fork, exec Execute the binary as root process using sudo or from root owned shell Terminate the launched eslogger Observe the process field in the setuid event Expected behavior The eslogger will report events indicating a process launch and uid changes so the child process is set to 501. i.e.: fork setuid - Done by child process exec Actual behavior The process field in the setuid event is reported as the parent process (that called posix_spawn) - indicating UID change to the parent process. Attachments I'm attaching source code for a small project with a 2 binaries: I'll add the source code for the project at the end of the file + attach filtered eslogger JSONs One that runs the descirbed posix_spawn flow One that produces the exact same sequence of events by doing different operation and reaching a different process state: Parent calls fork() Parent process calls setuid(501) Child process calls exec() Why this is problematic Both binaries in my attachment do different operations, achieving different process state (1 is parent with UID=0 and child with UID=501 while the other is parent UID=501 and child UID=0), but report the same sequence of events. Code #include <cstdio> #include <spawn.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/wait.h> #include <string.h> // environ contains the current environment variables extern char **environ; extern "C" { int posix_spawnattr_set_uid_np(posix_spawnattr_t *attr, uid_t uid); int posix_spawnattr_set_gid_np(posix_spawnattr_t *attr, gid_t gid); } int main() { pid_t pid; int status; posix_spawnattr_t attr; // 1. Define the executable path and arguments const char *path = "/bin/sleep"; char *const argv[] = {(char *)"sleep", (char *)"1", NULL}; // 2. Initialize spawn attributes if ((status = posix_spawnattr_init(&attr)) != 0) { fprintf(stderr, "posix_spawnattr_init: %s\n", strerror(status)); return EXIT_FAILURE; } // 3. Set the UID for the child process (e.g., UID 501) // Note: Parent must be root to change to a different user uid_t target_uid = 501; if ((status = posix_spawnattr_set_uid_np(&attr, target_uid)) != 0) { fprintf(stderr, "posix_spawnattr_set_uid_np: %s\n", strerror(status)); posix_spawnattr_destroy(&attr); return EXIT_FAILURE; } // 4. Spawn the process printf("Spawning /bin/sleep 1 as UID %d...\n", target_uid); status = posix_spawn(&pid, path, NULL, &attr, argv, environ); if (status == 0) { printf("Successfully spawned child with PID: %d\n", pid); // Wait for the child to finish (will take 63 seconds) if (waitpid(pid, &status, 0) != -1) { printf("Child process exited with status %d\n", WEXITSTATUS(status)); } else { perror("waitpid"); } } else { fprintf(stderr, "posix_spawn: %s\n", strerror(status)); } // 5. Clean up posix_spawnattr_destroy(&attr); return (status == 0) ? EXIT_SUCCESS : EXIT_FAILURE; } #include <cstdio> #include <cstdlib> #include <unistd.h> #include <sys/wait.h> #include <errno.h> #include <string.h> // This program demonstrates fork + setuid + exec behavior for ES framework bug report // 1. Parent forks // 2. Parent does setuid(501) // 3. Child waits with sleep syscall // 4. Child performs exec int main() { printf("Parent PID: %d, UID: %d, EUID: %d\n", getpid(), getuid(), geteuid()); pid_t pid = fork(); if (pid < 0) { // Fork failed perror("fork"); return EXIT_FAILURE; } if (pid == 0) { // Child process printf("Child PID: %d, UID: %d, EUID: %d\n", getpid(), getuid(), geteuid()); // Child waits for a bit with sleep syscall printf("Child sleeping for 2 seconds...\n"); sleep(2); // Child performs exec printf("Child executing child_exec...\n"); // Get the path to child_exec (same directory as this executable) char *const argv[] = {(char *)"/bin/sleep", (char *)"2", NULL}; // Try to exec child_exec from current directory first execv("/bin/sleep", argv); // If exec fails perror("execv"); return EXIT_FAILURE; } else { // Parent process printf("Parent forked child with PID: %d\n", pid); // Parent does setuid(501) printf("Parent calling setuid(501)...\n"); if (setuid(501) != 0) { perror("setuid"); // Continue anyway to observe behavior } printf("Parent after setuid - UID: %d, EUID: %d\n", getuid(), geteuid()); // Wait for child to finish int status; if (waitpid(pid, &status, 0) != -1) { if (WIFEXITED(status)) { printf("Child exited with status %d\n", WEXITSTATUS(status)); } else if (WIFSIGNALED(status)) { printf("Child killed by signal %d\n", WTERMSIG(status)); } } else { perror("waitpid"); } } return EXIT_SUCCESS; } posix_spawn.json fork_exec.json
3
0
715
Feb ’26
Invalid Persona Issue
Has anyone here encountered this? It's driving me crazy. It appears on launch. App Sandbox is enabled. The proper entitlement is selected (com.apple.security.files.user-selected.read-write) I believe this is causing an issue with app functionality for users on different machines. There is zero documentation across the internet on this problem. I am on macOS 26 beta. This error appears in both Xcode and Xcode-beta. Please help! Thank you, Logan
3
0
514
Jul ’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
412
Jul ’25
Auth Plugin Timeout Issue During Screen Unlock
Hi! We are developing an authentication plugin for macOS that integrates with the system's authentication flow. The plugin is designed to prompt the user for approval via a push notification in our app before allowing access. The plugin is added as the first mechanism in the authenticate rule, followed by the default builtin:authenticate as a fallback. When the system requests authentication (e.g., during screen unlock), our plugin successfully displays the custom UI and sends a push notification to the user's device. However, I've encountered the following issue: If the user does not approve the push notification within ~30 seconds, the system resets the screen lock (expected behavior). If the user approves the push notification within approximately 30 seconds but doesn’t start entering their password before the timeout expires, the system still resets the screen lock before they can enter their password, effectively canceling the session. What I've Tried: Attempted to imitate mouse movement after the push button was clicked to keep the session active. Created a display sleep prevention assertion using IOKit to prevent the screen from turning off. Used the caffeinate command to keep the display and system awake. Tried setting the result as allow for the authorization request and passing an empty password to prevent the display from turning off. I also checked the system logs when this issue occurred and found the following messages: ___loginwindow: -[LWScreenLock (Private) askForPasswordSecAgent] | localUser = >timeout loginwindow: -[LWScreenLock handleUnlockResult:] _block_invoke | ERROR: Unexpected _lockRequestedBy of:7 sleeping screen loginwindow: SleepDisplay | enter powerd: Process (loginwindow) is requesting display idle___ These messages suggest that the loginwindow process encounters a timeout condition, followed by the display entering sleep mode. Despite my attempts to prevent this behavior, the screen lock still resets prematurely. Questions: Is there a documented (or undocumented) system timeout for the entire authentication flow during screen unlock that I cannot override? Are there any strategies for pausing or extending the authentication timeout to allow for complex authentication flows like push notifications? Any guidance or insights would be greatly appreciated. Thank you!
3
2
351
Jun ’25
MFA MacOS At ScreenSaver (Lock Screen).
Hi , I did The MFA(2FA) of Email OTP For MacOS Login Screen using, Authorization Plugin, Using This git hub project. It is working For Login Screen , Im trying to Add The Same plugin for LockScreen but it is not working at lock Screen , Below is the reffrense theard For The issue , https://aninterestingwebsite.com/forums/thread/127614, please Share The Code that should Present the NSwindow at Screen Saver (Lock Screen) MacOS .
3
0
983
1w
Repeated account-deleted Server-to-Server notifications for the same Apple ID
Hello, We are experiencing an issue related to Sign in with Apple Server-to-Server (S2S) notifications, specifically involving repeated delivery of the account-deleted event, and would like to ask whether this behavior is expected or known. Background We have configured an S2S notification endpoint for Sign in with Apple in accordance with Apple’s requirements for account status change notifications. Our endpoint: Is reachable over HTTPS Consistently returns HTTP 200 OK Successfully receives other S2S events, including: email-enabled email-disabled consent-revoked Issue: Repeated 'account-deleted' events for the same Apple ID For most users, the account-deleted event is delivered only once, as expected. However, for a specific Apple ID used with Sign in with Apple, we are observing repeated deliveries of the same account-deleted event, arriving at regular intervals (approximately every 5 minutes). The payload contents are identical between deliveries and include the same user identifier (sub) and event timestamp. Notably: The Apple ID deletion itself completed successfully The payload does not change between deliveries Our endpoint continues to return HTTP 200 OK for every request Questions We would appreciate clarification on the following points: Is repeated delivery of the same account-deleted event expected behavior in any scenario? Is there a retry or redelivery mechanism for this event type, even when HTTP 200 is returned? Could repeated deliveries indicate that the deletion process is still considered “in progress” on Apple’s side? Are developers expected to treat account-deleted events as at-least-once delivery and handle them idempotently? Additional context While researching this issue, we found a forum thread describing a very similar case: https://aninterestingwebsite.com/forums/thread/735674 In that discussion, Apple staff advised submitting the issue via Feedback Assistant, which suggests that this behavior may already be understood internally. We have also submitted a Feedback Assistant report with detailed logs and timestamps. Any clarification on the expected behavior or recommended handling for this scenario would be greatly appreciated. Thank you for your time and support.
3
2
977
3w
Errors with Attestation on App
We recently deployed Attestation on our application, and for a majority of the 40,000 users it works well. We have about six customers who are failing attestation. In digging through debug logs, we're seeing this error "iOS assertion verification failed. Unauthorized access attempted." We're assuming that the UUID is blocked somehow on Apple side but we're stumped as to why. We had a customer come in and we could look at the phone, and best we can tell it's just a generic phone with no jailbroken or any malicious apps. How can we determine if the UUID is blocked?
3
0
226
May ’25
iPhone + Safari + Passwords violates WebAuthn spec when pubKeyCredParams doesn't contain ES256
WebAuthn Level 3 § 6.3.2 Step 2 states the authenticator must : Check if at least one of the specified combinations of PublicKeyCredentialType and cryptographic parameters in credTypesAndPubKeyAlgs is supported. If not, return an error code equivalent to "NotSupportedError" and terminate the operation. On my iPhone 15 Pro Max running iOS 18.5, Safari + Passwords does not exhibit this behavior; instead an error is not reported and an ES256 credential is created when an RP passes a non-empty sequence that does not contain {"type":"public-key","alg":-7} (e.g., [{"type":"public-key","alg":-8}]). When I use Chromium 138.0.7204.92 on my laptop running Arch Linux in conjunction with the Passwords app (connected via the "hybrid" protocol), a credential is not created and instead an error is reported per the spec.
3
0
532
Jul ’25
App Attest Issue in Production - Attestation Object Size Increased
Hi Apple Team and Community, We encountered a sudden and widespread failure related to the App Attest service on Friday, July 25, starting at around 9:22 AM UTC. After an extended investigation, our network engineers noted that the size of the attestation objects received from the attestKey call grew in size notably starting at that time. As a result, our firewall began blocking the requests from our app made to our servers with the Base64-encoded attestation objects in the payload, as these requests began triggering our firewall's max request length rule. Could Apple engineers please confirm whether there was any change rolled out by Apple at or around that time that would cause the attestation object size to increase? Can anyone else confirm seeing this? Any insights from Apple or others would be appreciated to ensure continued stability. Thanks!
3
0
335
Jul ’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
783
Oct ’25
Background Unix executable not appearing in Screen Recording permissions UI (macOS Tahoe 26.1)
Our background monitoring application uses a Unix executable that requests Screen Recording permission via CGRequestScreenCaptureAccess(). This worked correctly in macOS Tahoe 26.0.1, but broke in 26.1. Issue: After calling CGRequestScreenCaptureAccess() in macOS Tahoe 26.1: System dialog appears and opens System Settings Our executable does NOT appear in the Screen Recording list Manually adding via "+" button grants permission internally, but the executable still doesn't show in the UI Users cannot verify or revoke permissions Background: Unix executable runs as a background process (not from Terminal) Uses Accessibility APIs to retrieve window titles Same issue occurs with Full Disk Access permissions Environment: macOS Tahoe 26.1 (worked in 26.0.1) Background process (not launched from Terminal) Questions: Is this a bug or intentional design change in 26.1? What's the recommended approach for background executables to properly register with TCC? Are there specific requirements (Info.plist, etc.) needed? This significantly impacts user experience as they cannot manage permissions through the UI. Any guidance would be greatly appreciated. Thank you
3
2
552
Nov ’25
Why does appleid.apple.com/auth/authorize throw an "invalid_client" error?
Hi https://appleid.apple.com/auth/authorize?client_id=com.adobe.services.adobeid-na1.web shows: invalid_request But https://appleid.apple.com/auth/authorize?client_id=xrqxnpjgps shows: invalid_client I've created a Primary App ID and ticked "Sign In with Apple". I've created a Service ID and ticked "Sign In with Apple" (identifier is xrqxnpjgps). When I click "Configure" for the "Sign In with Apple" of the Service ID, it is linked to the Primary App ID. Why do I get an invalid_client error? I've contacted the support by mail, and have been redirected here, does someone here have the ability/access/knowledge/will to figure out the cause and then tell me? Regards
3
1
255
Jun ’25
Migrating Sign in with Apple users for an app transfer
Dear Apple Developer Technical Support, We are currently following the official Apple documentation “TN3159: Migrating Sign in with Apple users for an app transfer” to carry out a Sign in with Apple user migration after successfully transferring several apps to a new developer account. Here is a summary of our situation: Under the original Apple developer account, we had five apps using Sign in with Apple, grouped under a shared primary app using App Grouping. Recently, we transferred three of these apps to our new Apple developer account via App Store Connect. After the transfer, these three apps are no longer associated with the original primary App ID. We reconfigured individual Services IDs for each app in the new account and enabled Sign in with Apple for each. More than 24 hours have passed since the app transfer was completed. Now we are attempting to follow the migration process to restore user access via the user.migration flow. Specifically, we are using the following script to request an Apple access token: url = "https://appleid.apple.com/auth/token" headers = {"Content-Type": "application/x-www-form-urlencoded"} data = { "grant_type": "client_credentials", "scope": "user.migration", "client_id": "com.game.friends.ios.toptop.sea", # New Services ID in the new account "client_secret": "<JWT signed with new p8 key>" } response = requests.post(url, headers=headers, data=data) However, the API response consistently returns: { "error": "invalid_client" } We have verified that the following configurations are correct: The client_secret is generated using the p8 key from the new account, signed with ES256 and correct key_id, team_id, and client_id. The client_id corresponds to the Services ID created in the new account and properly associated with the migrated app. The scope is set to user.migration. The JWT payload contains correct iss, sub, and aud values as per Apple documentation. The app has been fully transferred and reconfigured more than 24 hours ago. Problem Summary & Request for Support: According to Apple’s official documentation: “After an app is transferred, Apple updates the Sign in with Apple configuration in the background. This can take up to 24 hours. During this time, attempts to authenticate users or validate tokens may fail.” However, we are still consistently receiving invalid_client errors after the 24-hour waiting period. We suspect one of the following issues: The transferred apps may still be partially associated with the original App Grouping or primary App ID. Some Sign in with Apple configuration in Apple’s backend may not have been fully updated after the transfer. Or the Services ID is not yet fully operational for the transferred apps in the new account. We kindly request your assistance to: Verify whether the transferred apps have been completely detached from the original App Grouping and primary App ID. Confirm whether the new Services IDs under the new account are fully functional and eligible for Sign in with Apple with user.migration scope. Help identify any remaining configuration or migration issues that may cause the invalid_client error. If necessary, assist in manually ungrouping or clearing any residual App Grouping relationships affecting the new environment. We have also generated and retained the original transfer_sub identifiers and are fully prepared to complete the sub mapping once the user.migration flow becomes functional. Thank you very much for your time and support!
3
0
414
Jul ’25
Secure Enclave Cryptokit
I am using the CryptoKit SecureEnclave enum to generate Secure Enclave keys. I've got a couple of questions: What is the lifetime of these keys? When I don't store them somewhere, how does the Secure Enclave know they are gone? Do backups impact these keys? I.e. can I lose access to the key when I restore a backup? Do these keys count to the total storage capacity of the Secure Enclave? If I recall correctly, the Secure Enclave has a limited storage capacity. Do the SecureEnclave key instances count towards this storage capacity? What is the dataRepresentation and how can I use this? I'd like to store the Secure Enclave (preferably not in the Keychain due to its limitations). Is it "okay" to store this elsewhere, for instance in a file or in the UserDefaults? Can the dataRepresentation be used in other apps? If I had the capability of extracting the dataRepresentation as an attacker, could I then rebuild that key in my malicious app, as the key can be rebuilt with the Secure Enclave on the same device, or are there measures in place to prevent this (sandbox, bundle id, etc.)
3
0
380
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
3
0
1.6k
May ’25
Issue: Plain Executables Do Not Appear Under “Screen & System Audio Recording” on macOS 26.1 (Tahoe)
Summary I am investigating a change in macOS 26.1 (Tahoe) where plain (non-bundled) executables that request screen recording access no longer appear under: System Settings → Privacy & Security → Screen & System Audio Recording This behavior differs from macOS Sequoia, where these executables did appear in the list and could be managed through the UI. Tahoe still prompts for permission and still allows the executable to capture the screen once permission is granted, but the executable never shows up in the UI list. This breaks user expectations and removes UI-based permission management. To confirm the behavior, I created a small reproduction project with both: a plain executable, and an identical executable packaged inside an .app bundle. Only the bundled version appears in System Settings. Observed Behaviour 1. Plain Executable (from my reproduction project) When running a plain executable that captures the screen: macOS displays the normal screen-recording permission prompt. Before granting permission: screenshots show only the desktop background. After granting permission: screenshots capture the full display. The executable does not appear under “Screen & System Audio Recording”. Even when permission is granted manually (e.g., dragging the executable into the pane), the executable still does not appear, which prevents the user from modifying or revoking the permission through the UI. If the executable is launched from inside another app (e.g., VS Code, Terminal), the parent app appears in the list instead, not the executable itself. 2. Bundled App Version (from the reproduction project) I packaged the same code into a simple .app bundle (ScreenCaptureApp.app). When running the app: The same permission prompt appears. Pre-permission screenshots show the desktop background. Post-permission screenshots capture the full display. The app does appear under “Screen & System Audio Recording”. This bundle uses the same underlying executable — the only difference is packaging. Hypothesis macOS 26.1 (Tahoe) appears to require app bundles for an item to be shown in the Screen Recording privacy UI. Plain executables: still request and receive permission, still function correctly after permission is granted, but do not appear in the System Settings list. This may be an intentional change, undocumented behavior, or a regression. Reproduction Project The reproduction project includes: screen_capture.go A simple Go program that captures screenshots in a loop. screen_capture_executable Plain executable built from the Go source. ScreenCaptureApp.app/ App bundle containing the same executable. build.sh Builds both the plain executable and the app bundle. Permission reset and TCC testing scripts. The project demonstrates the behavior consistently. Steps to Reproduce Plain Executable Build: ./build.sh Reset screen capture permissions: sudo tccutil reset ScreenCapture Run: ./screen_capture_executable Before granting: screenshots show desktop only. Grant permission when prompted. After granting: full screenshots. Executable does not appear in “Screen & System Audio Recording”. Bundled App Build (if not already built): ./build.sh Reset permissions (optional): sudo tccutil reset ScreenCapture Run: open ScreenCaptureApp.app Before granting: screenshots show desktop. After granting: full screenshots. App bundle appears in the System Settings list. Additional Check I also tested launching the plain executable as a child process of another executable, similar to how some software architectures work. Result: Permission prompt appears Permission can be granted Executable still does not appear in the UI, even though TCC tracks it internally → consistent with the plain-executable behaviour. This reinforces that only app bundles are listed. Questions for Apple Is the removal of plain executables from “Screen & System Audio Recording” an intentional change in macOS Tahoe? If so, does Apple now require all screen-recording capable binaries to be packaged as .app bundles for the UI to display them? Is there a supported method for making a plain executable (launched by a parent process) appear in the list? If this is not intentional, what is the recommended path for reporting this as a regression? Files Unfortunately, I have discovered the zip file that contains my reproduction project can't be directly uploaded here. Here is a Google Drive link instead: https://drive.google.com/file/d/1sXsr3Q0g6_UzlOIL54P5wbS7yBkpMJ7A/view?usp=sharing Thank you for taking the time to review this. Any insight into whether this change is intentional or a regression would be very helpful.
3
0
1k
Dec ’25
How to undisplay `Private Access` in `Contacts Access` when i use `CNContactPickerViewController`?
In iOS 18, i use CNContactPickerViewController to access to Contacts (i know it is one-time access). After first pick up one contact, the Setting > Apps > my app > Contacts shows Private Access without any option to close it. Is there any way to close it and undisplay it ? I tried to uninstall and reinstall my app, but it didn't work.
3
0
378
Apr ’25
How to use an Intune-delivered SCEP certificate for mTLS in iOS app using URLSessionDelegate?
I am working on implementing mTLS authentication in my iOS app (Apple Inhouse &amp; intune MAM managed app). The SCEP client certificate is deployed on the device via Intune MDM. When I try accessing the protected endpoint via SFSafariViewController/ASWebAuthenticationSession, the certificate picker appears and the request succeeds. However, from within my app (using URLSessionDelegate), the certificate is not found (errSecItemNotFound). The didReceive challenge method is called, but my SCEP certificate is not found in the app. The certificate is visible under Settings &gt; Device Management &gt; SCEP Certificate. How can I make my iOS app access and use the SCEP certificate (installed via Intune MDM) for mTLS requests? Do I need a special entitlement, keychain access group, or configuration in Intune or Developer account to allow my app to use the certificate? Here is the sample code I am using: final class KeychainCertificateDelegate: NSObject, URLSessionDelegate { func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -&gt; Void) { guard challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodClientCertificate else { completionHandler(.performDefaultHandling, nil) return } // Get the DNs the server will accept guard let expectedDNs = challenge.protectionSpace.distinguishedNames else { completionHandler(.cancelAuthenticationChallenge, nil) return } var identityRefs: CFTypeRef? = nil let err = SecItemCopyMatching([ kSecClass: kSecClassIdentity, kSecMatchLimit: kSecMatchLimitAll, kSecMatchIssuers: expectedDNs, kSecReturnRef: true, ] as NSDictionary, &amp;identityRefs) if err != errSecSuccess { completionHandler(.cancelAuthenticationChallenge, nil) return } guard let identities = identityRefs as? [SecIdentity], let identity = identities.first else { print("Identity list is empty") completionHandler(.cancelAuthenticationChallenge, nil) return } let credential = URLCredential(identity: identity, certificates: nil, persistence: .forSession) completionHandler(.useCredential, credential) } } func perform_mTLSRequest() { guard let url = URL(string: "https://sample.com/api/endpoint") else { return } var request = URLRequest(url: url) request.httpMethod = "POST" request.setValue("application/json", forHTTPHeaderField: "Accept") request.setValue("Bearer \(bearerToken)", forHTTPHeaderField: "Authorization") let delegate = KeychainCertificateDelegate() let session = URLSession(configuration: .ephemeral, delegate: delegate, delegateQueue: nil) let task = session.dataTask(with: request) { data, response, error in guard let httpResponse = response as? HTTPURLResponse, (200...299).contains(httpResponse.statusCode) else { print("Bad response") return } if let data = data { print(String(data: data, encoding: .utf8)!) } } task.resume() }
3
0
890
Sep ’25
Endpoint Security Framework Bug: setuid Event Incorrectly Attributed to Parent Process During posix_spawn
Feedback ticket ID: FB21797397 Summary When using posix_spawn() with posix_spawnattr_set_uid_np() to spawn a child process with a different UID, the eslogger incorrectly reports a setuid event as an event originating from the parent process instead of the child process. Steps to Reproduce Create a binary that do the following: Configure posix_spawnattr_t that set the process UIDs to some other user ID (I'll use 501 in this example). Uses posix_spawn() to spawn a child process Run eslogger with the event types setuid, fork, exec Execute the binary as root process using sudo or from root owned shell Terminate the launched eslogger Observe the process field in the setuid event Expected behavior The eslogger will report events indicating a process launch and uid changes so the child process is set to 501. i.e.: fork setuid - Done by child process exec Actual behavior The process field in the setuid event is reported as the parent process (that called posix_spawn) - indicating UID change to the parent process. Attachments I'm attaching source code for a small project with a 2 binaries: I'll add the source code for the project at the end of the file + attach filtered eslogger JSONs One that runs the descirbed posix_spawn flow One that produces the exact same sequence of events by doing different operation and reaching a different process state: Parent calls fork() Parent process calls setuid(501) Child process calls exec() Why this is problematic Both binaries in my attachment do different operations, achieving different process state (1 is parent with UID=0 and child with UID=501 while the other is parent UID=501 and child UID=0), but report the same sequence of events. Code #include <cstdio> #include <spawn.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/wait.h> #include <string.h> // environ contains the current environment variables extern char **environ; extern "C" { int posix_spawnattr_set_uid_np(posix_spawnattr_t *attr, uid_t uid); int posix_spawnattr_set_gid_np(posix_spawnattr_t *attr, gid_t gid); } int main() { pid_t pid; int status; posix_spawnattr_t attr; // 1. Define the executable path and arguments const char *path = "/bin/sleep"; char *const argv[] = {(char *)"sleep", (char *)"1", NULL}; // 2. Initialize spawn attributes if ((status = posix_spawnattr_init(&attr)) != 0) { fprintf(stderr, "posix_spawnattr_init: %s\n", strerror(status)); return EXIT_FAILURE; } // 3. Set the UID for the child process (e.g., UID 501) // Note: Parent must be root to change to a different user uid_t target_uid = 501; if ((status = posix_spawnattr_set_uid_np(&attr, target_uid)) != 0) { fprintf(stderr, "posix_spawnattr_set_uid_np: %s\n", strerror(status)); posix_spawnattr_destroy(&attr); return EXIT_FAILURE; } // 4. Spawn the process printf("Spawning /bin/sleep 1 as UID %d...\n", target_uid); status = posix_spawn(&pid, path, NULL, &attr, argv, environ); if (status == 0) { printf("Successfully spawned child with PID: %d\n", pid); // Wait for the child to finish (will take 63 seconds) if (waitpid(pid, &status, 0) != -1) { printf("Child process exited with status %d\n", WEXITSTATUS(status)); } else { perror("waitpid"); } } else { fprintf(stderr, "posix_spawn: %s\n", strerror(status)); } // 5. Clean up posix_spawnattr_destroy(&attr); return (status == 0) ? EXIT_SUCCESS : EXIT_FAILURE; } #include <cstdio> #include <cstdlib> #include <unistd.h> #include <sys/wait.h> #include <errno.h> #include <string.h> // This program demonstrates fork + setuid + exec behavior for ES framework bug report // 1. Parent forks // 2. Parent does setuid(501) // 3. Child waits with sleep syscall // 4. Child performs exec int main() { printf("Parent PID: %d, UID: %d, EUID: %d\n", getpid(), getuid(), geteuid()); pid_t pid = fork(); if (pid < 0) { // Fork failed perror("fork"); return EXIT_FAILURE; } if (pid == 0) { // Child process printf("Child PID: %d, UID: %d, EUID: %d\n", getpid(), getuid(), geteuid()); // Child waits for a bit with sleep syscall printf("Child sleeping for 2 seconds...\n"); sleep(2); // Child performs exec printf("Child executing child_exec...\n"); // Get the path to child_exec (same directory as this executable) char *const argv[] = {(char *)"/bin/sleep", (char *)"2", NULL}; // Try to exec child_exec from current directory first execv("/bin/sleep", argv); // If exec fails perror("execv"); return EXIT_FAILURE; } else { // Parent process printf("Parent forked child with PID: %d\n", pid); // Parent does setuid(501) printf("Parent calling setuid(501)...\n"); if (setuid(501) != 0) { perror("setuid"); // Continue anyway to observe behavior } printf("Parent after setuid - UID: %d, EUID: %d\n", getuid(), geteuid()); // Wait for child to finish int status; if (waitpid(pid, &status, 0) != -1) { if (WIFEXITED(status)) { printf("Child exited with status %d\n", WEXITSTATUS(status)); } else if (WIFSIGNALED(status)) { printf("Child killed by signal %d\n", WTERMSIG(status)); } } else { perror("waitpid"); } } return EXIT_SUCCESS; } posix_spawn.json fork_exec.json
Replies
3
Boosts
0
Views
715
Activity
Feb ’26
Invalid Persona Issue
Has anyone here encountered this? It's driving me crazy. It appears on launch. App Sandbox is enabled. The proper entitlement is selected (com.apple.security.files.user-selected.read-write) I believe this is causing an issue with app functionality for users on different machines. There is zero documentation across the internet on this problem. I am on macOS 26 beta. This error appears in both Xcode and Xcode-beta. Please help! Thank you, Logan
Replies
3
Boosts
0
Views
514
Activity
Jul ’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.
Replies
3
Boosts
0
Views
412
Activity
Jul ’25
Auth Plugin Timeout Issue During Screen Unlock
Hi! We are developing an authentication plugin for macOS that integrates with the system's authentication flow. The plugin is designed to prompt the user for approval via a push notification in our app before allowing access. The plugin is added as the first mechanism in the authenticate rule, followed by the default builtin:authenticate as a fallback. When the system requests authentication (e.g., during screen unlock), our plugin successfully displays the custom UI and sends a push notification to the user's device. However, I've encountered the following issue: If the user does not approve the push notification within ~30 seconds, the system resets the screen lock (expected behavior). If the user approves the push notification within approximately 30 seconds but doesn’t start entering their password before the timeout expires, the system still resets the screen lock before they can enter their password, effectively canceling the session. What I've Tried: Attempted to imitate mouse movement after the push button was clicked to keep the session active. Created a display sleep prevention assertion using IOKit to prevent the screen from turning off. Used the caffeinate command to keep the display and system awake. Tried setting the result as allow for the authorization request and passing an empty password to prevent the display from turning off. I also checked the system logs when this issue occurred and found the following messages: ___loginwindow: -[LWScreenLock (Private) askForPasswordSecAgent] | localUser = >timeout loginwindow: -[LWScreenLock handleUnlockResult:] _block_invoke | ERROR: Unexpected _lockRequestedBy of:7 sleeping screen loginwindow: SleepDisplay | enter powerd: Process (loginwindow) is requesting display idle___ These messages suggest that the loginwindow process encounters a timeout condition, followed by the display entering sleep mode. Despite my attempts to prevent this behavior, the screen lock still resets prematurely. Questions: Is there a documented (or undocumented) system timeout for the entire authentication flow during screen unlock that I cannot override? Are there any strategies for pausing or extending the authentication timeout to allow for complex authentication flows like push notifications? Any guidance or insights would be greatly appreciated. Thank you!
Replies
3
Boosts
2
Views
351
Activity
Jun ’25
MFA MacOS At ScreenSaver (Lock Screen).
Hi , I did The MFA(2FA) of Email OTP For MacOS Login Screen using, Authorization Plugin, Using This git hub project. It is working For Login Screen , Im trying to Add The Same plugin for LockScreen but it is not working at lock Screen , Below is the reffrense theard For The issue , https://aninterestingwebsite.com/forums/thread/127614, please Share The Code that should Present the NSwindow at Screen Saver (Lock Screen) MacOS .
Replies
3
Boosts
0
Views
983
Activity
1w
Repeated account-deleted Server-to-Server notifications for the same Apple ID
Hello, We are experiencing an issue related to Sign in with Apple Server-to-Server (S2S) notifications, specifically involving repeated delivery of the account-deleted event, and would like to ask whether this behavior is expected or known. Background We have configured an S2S notification endpoint for Sign in with Apple in accordance with Apple’s requirements for account status change notifications. Our endpoint: Is reachable over HTTPS Consistently returns HTTP 200 OK Successfully receives other S2S events, including: email-enabled email-disabled consent-revoked Issue: Repeated 'account-deleted' events for the same Apple ID For most users, the account-deleted event is delivered only once, as expected. However, for a specific Apple ID used with Sign in with Apple, we are observing repeated deliveries of the same account-deleted event, arriving at regular intervals (approximately every 5 minutes). The payload contents are identical between deliveries and include the same user identifier (sub) and event timestamp. Notably: The Apple ID deletion itself completed successfully The payload does not change between deliveries Our endpoint continues to return HTTP 200 OK for every request Questions We would appreciate clarification on the following points: Is repeated delivery of the same account-deleted event expected behavior in any scenario? Is there a retry or redelivery mechanism for this event type, even when HTTP 200 is returned? Could repeated deliveries indicate that the deletion process is still considered “in progress” on Apple’s side? Are developers expected to treat account-deleted events as at-least-once delivery and handle them idempotently? Additional context While researching this issue, we found a forum thread describing a very similar case: https://aninterestingwebsite.com/forums/thread/735674 In that discussion, Apple staff advised submitting the issue via Feedback Assistant, which suggests that this behavior may already be understood internally. We have also submitted a Feedback Assistant report with detailed logs and timestamps. Any clarification on the expected behavior or recommended handling for this scenario would be greatly appreciated. Thank you for your time and support.
Replies
3
Boosts
2
Views
977
Activity
3w
Apply MacOS OS updated without password prompt
Hello, I am currently researching to develop an application where I want to apply the MacOS updates without the password prompt shown to the users. I did some research on this and understand that an MDM solution can apply these patches without user intervention. Are there any other ways we can achieve this? Any leads are much appreciated.
Replies
3
Boosts
0
Views
311
Activity
Jul ’25
Errors with Attestation on App
We recently deployed Attestation on our application, and for a majority of the 40,000 users it works well. We have about six customers who are failing attestation. In digging through debug logs, we're seeing this error "iOS assertion verification failed. Unauthorized access attempted." We're assuming that the UUID is blocked somehow on Apple side but we're stumped as to why. We had a customer come in and we could look at the phone, and best we can tell it's just a generic phone with no jailbroken or any malicious apps. How can we determine if the UUID is blocked?
Replies
3
Boosts
0
Views
226
Activity
May ’25
iPhone + Safari + Passwords violates WebAuthn spec when pubKeyCredParams doesn't contain ES256
WebAuthn Level 3 § 6.3.2 Step 2 states the authenticator must : Check if at least one of the specified combinations of PublicKeyCredentialType and cryptographic parameters in credTypesAndPubKeyAlgs is supported. If not, return an error code equivalent to "NotSupportedError" and terminate the operation. On my iPhone 15 Pro Max running iOS 18.5, Safari + Passwords does not exhibit this behavior; instead an error is not reported and an ES256 credential is created when an RP passes a non-empty sequence that does not contain {"type":"public-key","alg":-7} (e.g., [{"type":"public-key","alg":-8}]). When I use Chromium 138.0.7204.92 on my laptop running Arch Linux in conjunction with the Passwords app (connected via the "hybrid" protocol), a credential is not created and instead an error is reported per the spec.
Replies
3
Boosts
0
Views
532
Activity
Jul ’25
App Attest Issue in Production - Attestation Object Size Increased
Hi Apple Team and Community, We encountered a sudden and widespread failure related to the App Attest service on Friday, July 25, starting at around 9:22 AM UTC. After an extended investigation, our network engineers noted that the size of the attestation objects received from the attestKey call grew in size notably starting at that time. As a result, our firewall began blocking the requests from our app made to our servers with the Base64-encoded attestation objects in the payload, as these requests began triggering our firewall's max request length rule. Could Apple engineers please confirm whether there was any change rolled out by Apple at or around that time that would cause the attestation object size to increase? Can anyone else confirm seeing this? Any insights from Apple or others would be appreciated to ensure continued stability. Thanks!
Replies
3
Boosts
0
Views
335
Activity
Jul ’25
How can I configure the application or environment to suppress this repeated permission prompt?"
"I am attempting to read and write data to an Office Group Container, and I am consistently prompted with the "App would like to access data from other apps" alert. How can I configure the application or environment to suppress this repeated permission prompt?"
Replies
3
Boosts
0
Views
294
Activity
Jan ’26
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.
Replies
3
Boosts
0
Views
783
Activity
Oct ’25
Background Unix executable not appearing in Screen Recording permissions UI (macOS Tahoe 26.1)
Our background monitoring application uses a Unix executable that requests Screen Recording permission via CGRequestScreenCaptureAccess(). This worked correctly in macOS Tahoe 26.0.1, but broke in 26.1. Issue: After calling CGRequestScreenCaptureAccess() in macOS Tahoe 26.1: System dialog appears and opens System Settings Our executable does NOT appear in the Screen Recording list Manually adding via "+" button grants permission internally, but the executable still doesn't show in the UI Users cannot verify or revoke permissions Background: Unix executable runs as a background process (not from Terminal) Uses Accessibility APIs to retrieve window titles Same issue occurs with Full Disk Access permissions Environment: macOS Tahoe 26.1 (worked in 26.0.1) Background process (not launched from Terminal) Questions: Is this a bug or intentional design change in 26.1? What's the recommended approach for background executables to properly register with TCC? Are there specific requirements (Info.plist, etc.) needed? This significantly impacts user experience as they cannot manage permissions through the UI. Any guidance would be greatly appreciated. Thank you
Replies
3
Boosts
2
Views
552
Activity
Nov ’25
Why does appleid.apple.com/auth/authorize throw an "invalid_client" error?
Hi https://appleid.apple.com/auth/authorize?client_id=com.adobe.services.adobeid-na1.web shows: invalid_request But https://appleid.apple.com/auth/authorize?client_id=xrqxnpjgps shows: invalid_client I've created a Primary App ID and ticked "Sign In with Apple". I've created a Service ID and ticked "Sign In with Apple" (identifier is xrqxnpjgps). When I click "Configure" for the "Sign In with Apple" of the Service ID, it is linked to the Primary App ID. Why do I get an invalid_client error? I've contacted the support by mail, and have been redirected here, does someone here have the ability/access/knowledge/will to figure out the cause and then tell me? Regards
Replies
3
Boosts
1
Views
255
Activity
Jun ’25
Migrating Sign in with Apple users for an app transfer
Dear Apple Developer Technical Support, We are currently following the official Apple documentation “TN3159: Migrating Sign in with Apple users for an app transfer” to carry out a Sign in with Apple user migration after successfully transferring several apps to a new developer account. Here is a summary of our situation: Under the original Apple developer account, we had five apps using Sign in with Apple, grouped under a shared primary app using App Grouping. Recently, we transferred three of these apps to our new Apple developer account via App Store Connect. After the transfer, these three apps are no longer associated with the original primary App ID. We reconfigured individual Services IDs for each app in the new account and enabled Sign in with Apple for each. More than 24 hours have passed since the app transfer was completed. Now we are attempting to follow the migration process to restore user access via the user.migration flow. Specifically, we are using the following script to request an Apple access token: url = "https://appleid.apple.com/auth/token" headers = {"Content-Type": "application/x-www-form-urlencoded"} data = { "grant_type": "client_credentials", "scope": "user.migration", "client_id": "com.game.friends.ios.toptop.sea", # New Services ID in the new account "client_secret": "<JWT signed with new p8 key>" } response = requests.post(url, headers=headers, data=data) However, the API response consistently returns: { "error": "invalid_client" } We have verified that the following configurations are correct: The client_secret is generated using the p8 key from the new account, signed with ES256 and correct key_id, team_id, and client_id. The client_id corresponds to the Services ID created in the new account and properly associated with the migrated app. The scope is set to user.migration. The JWT payload contains correct iss, sub, and aud values as per Apple documentation. The app has been fully transferred and reconfigured more than 24 hours ago. Problem Summary & Request for Support: According to Apple’s official documentation: “After an app is transferred, Apple updates the Sign in with Apple configuration in the background. This can take up to 24 hours. During this time, attempts to authenticate users or validate tokens may fail.” However, we are still consistently receiving invalid_client errors after the 24-hour waiting period. We suspect one of the following issues: The transferred apps may still be partially associated with the original App Grouping or primary App ID. Some Sign in with Apple configuration in Apple’s backend may not have been fully updated after the transfer. Or the Services ID is not yet fully operational for the transferred apps in the new account. We kindly request your assistance to: Verify whether the transferred apps have been completely detached from the original App Grouping and primary App ID. Confirm whether the new Services IDs under the new account are fully functional and eligible for Sign in with Apple with user.migration scope. Help identify any remaining configuration or migration issues that may cause the invalid_client error. If necessary, assist in manually ungrouping or clearing any residual App Grouping relationships affecting the new environment. We have also generated and retained the original transfer_sub identifiers and are fully prepared to complete the sub mapping once the user.migration flow becomes functional. Thank you very much for your time and support!
Replies
3
Boosts
0
Views
414
Activity
Jul ’25
Secure Enclave Cryptokit
I am using the CryptoKit SecureEnclave enum to generate Secure Enclave keys. I've got a couple of questions: What is the lifetime of these keys? When I don't store them somewhere, how does the Secure Enclave know they are gone? Do backups impact these keys? I.e. can I lose access to the key when I restore a backup? Do these keys count to the total storage capacity of the Secure Enclave? If I recall correctly, the Secure Enclave has a limited storage capacity. Do the SecureEnclave key instances count towards this storage capacity? What is the dataRepresentation and how can I use this? I'd like to store the Secure Enclave (preferably not in the Keychain due to its limitations). Is it "okay" to store this elsewhere, for instance in a file or in the UserDefaults? Can the dataRepresentation be used in other apps? If I had the capability of extracting the dataRepresentation as an attacker, could I then rebuild that key in my malicious app, as the key can be rebuilt with the Secure Enclave on the same device, or are there measures in place to prevent this (sandbox, bundle id, etc.)
Replies
3
Boosts
0
Views
380
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
Issue: Plain Executables Do Not Appear Under “Screen & System Audio Recording” on macOS 26.1 (Tahoe)
Summary I am investigating a change in macOS 26.1 (Tahoe) where plain (non-bundled) executables that request screen recording access no longer appear under: System Settings → Privacy & Security → Screen & System Audio Recording This behavior differs from macOS Sequoia, where these executables did appear in the list and could be managed through the UI. Tahoe still prompts for permission and still allows the executable to capture the screen once permission is granted, but the executable never shows up in the UI list. This breaks user expectations and removes UI-based permission management. To confirm the behavior, I created a small reproduction project with both: a plain executable, and an identical executable packaged inside an .app bundle. Only the bundled version appears in System Settings. Observed Behaviour 1. Plain Executable (from my reproduction project) When running a plain executable that captures the screen: macOS displays the normal screen-recording permission prompt. Before granting permission: screenshots show only the desktop background. After granting permission: screenshots capture the full display. The executable does not appear under “Screen & System Audio Recording”. Even when permission is granted manually (e.g., dragging the executable into the pane), the executable still does not appear, which prevents the user from modifying or revoking the permission through the UI. If the executable is launched from inside another app (e.g., VS Code, Terminal), the parent app appears in the list instead, not the executable itself. 2. Bundled App Version (from the reproduction project) I packaged the same code into a simple .app bundle (ScreenCaptureApp.app). When running the app: The same permission prompt appears. Pre-permission screenshots show the desktop background. Post-permission screenshots capture the full display. The app does appear under “Screen & System Audio Recording”. This bundle uses the same underlying executable — the only difference is packaging. Hypothesis macOS 26.1 (Tahoe) appears to require app bundles for an item to be shown in the Screen Recording privacy UI. Plain executables: still request and receive permission, still function correctly after permission is granted, but do not appear in the System Settings list. This may be an intentional change, undocumented behavior, or a regression. Reproduction Project The reproduction project includes: screen_capture.go A simple Go program that captures screenshots in a loop. screen_capture_executable Plain executable built from the Go source. ScreenCaptureApp.app/ App bundle containing the same executable. build.sh Builds both the plain executable and the app bundle. Permission reset and TCC testing scripts. The project demonstrates the behavior consistently. Steps to Reproduce Plain Executable Build: ./build.sh Reset screen capture permissions: sudo tccutil reset ScreenCapture Run: ./screen_capture_executable Before granting: screenshots show desktop only. Grant permission when prompted. After granting: full screenshots. Executable does not appear in “Screen & System Audio Recording”. Bundled App Build (if not already built): ./build.sh Reset permissions (optional): sudo tccutil reset ScreenCapture Run: open ScreenCaptureApp.app Before granting: screenshots show desktop. After granting: full screenshots. App bundle appears in the System Settings list. Additional Check I also tested launching the plain executable as a child process of another executable, similar to how some software architectures work. Result: Permission prompt appears Permission can be granted Executable still does not appear in the UI, even though TCC tracks it internally → consistent with the plain-executable behaviour. This reinforces that only app bundles are listed. Questions for Apple Is the removal of plain executables from “Screen & System Audio Recording” an intentional change in macOS Tahoe? If so, does Apple now require all screen-recording capable binaries to be packaged as .app bundles for the UI to display them? Is there a supported method for making a plain executable (launched by a parent process) appear in the list? If this is not intentional, what is the recommended path for reporting this as a regression? Files Unfortunately, I have discovered the zip file that contains my reproduction project can't be directly uploaded here. Here is a Google Drive link instead: https://drive.google.com/file/d/1sXsr3Q0g6_UzlOIL54P5wbS7yBkpMJ7A/view?usp=sharing Thank you for taking the time to review this. Any insight into whether this change is intentional or a regression would be very helpful.
Replies
3
Boosts
0
Views
1k
Activity
Dec ’25
How to undisplay `Private Access` in `Contacts Access` when i use `CNContactPickerViewController`?
In iOS 18, i use CNContactPickerViewController to access to Contacts (i know it is one-time access). After first pick up one contact, the Setting > Apps > my app > Contacts shows Private Access without any option to close it. Is there any way to close it and undisplay it ? I tried to uninstall and reinstall my app, but it didn't work.
Replies
3
Boosts
0
Views
378
Activity
Apr ’25
How to use an Intune-delivered SCEP certificate for mTLS in iOS app using URLSessionDelegate?
I am working on implementing mTLS authentication in my iOS app (Apple Inhouse &amp; intune MAM managed app). The SCEP client certificate is deployed on the device via Intune MDM. When I try accessing the protected endpoint via SFSafariViewController/ASWebAuthenticationSession, the certificate picker appears and the request succeeds. However, from within my app (using URLSessionDelegate), the certificate is not found (errSecItemNotFound). The didReceive challenge method is called, but my SCEP certificate is not found in the app. The certificate is visible under Settings &gt; Device Management &gt; SCEP Certificate. How can I make my iOS app access and use the SCEP certificate (installed via Intune MDM) for mTLS requests? Do I need a special entitlement, keychain access group, or configuration in Intune or Developer account to allow my app to use the certificate? Here is the sample code I am using: final class KeychainCertificateDelegate: NSObject, URLSessionDelegate { func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -&gt; Void) { guard challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodClientCertificate else { completionHandler(.performDefaultHandling, nil) return } // Get the DNs the server will accept guard let expectedDNs = challenge.protectionSpace.distinguishedNames else { completionHandler(.cancelAuthenticationChallenge, nil) return } var identityRefs: CFTypeRef? = nil let err = SecItemCopyMatching([ kSecClass: kSecClassIdentity, kSecMatchLimit: kSecMatchLimitAll, kSecMatchIssuers: expectedDNs, kSecReturnRef: true, ] as NSDictionary, &amp;identityRefs) if err != errSecSuccess { completionHandler(.cancelAuthenticationChallenge, nil) return } guard let identities = identityRefs as? [SecIdentity], let identity = identities.first else { print("Identity list is empty") completionHandler(.cancelAuthenticationChallenge, nil) return } let credential = URLCredential(identity: identity, certificates: nil, persistence: .forSession) completionHandler(.useCredential, credential) } } func perform_mTLSRequest() { guard let url = URL(string: "https://sample.com/api/endpoint") else { return } var request = URLRequest(url: url) request.httpMethod = "POST" request.setValue("application/json", forHTTPHeaderField: "Accept") request.setValue("Bearer \(bearerToken)", forHTTPHeaderField: "Authorization") let delegate = KeychainCertificateDelegate() let session = URLSession(configuration: .ephemeral, delegate: delegate, delegateQueue: nil) let task = session.dataTask(with: request) { data, response, error in guard let httpResponse = response as? HTTPURLResponse, (200...299).contains(httpResponse.statusCode) else { print("Bad response") return } if let data = data { print(String(data: data, encoding: .utf8)!) } } task.resume() }
Replies
3
Boosts
0
Views
890
Activity
Sep ’25