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

AutoFill extension loading woes
I'm trying to diagnose some issues with my AutoFill credential provider not loading on macOS. As far as I can tell I have all the entitlements and provisioning profiles correct, and ASSettingsHelper.requestToTurnOnCredentialProviderExtension() returns true with the Credential Provider showing up enabled in System Settings. However all other attempts to call into AuthenticationServices fail, and ASCredentialIdentityStore.shared.getState() always returns false for state.isEnabled Looking at the logs I don't see anything that stands out but I am not sure I've got the correct filter on the logs. I see discovery taking place 2026-05-29 08:43:09.389967-0700 0xd7d00 Default 0x83c0b1 26490 0 CredentialProviderExtensionHelper: (PlugInKit) [com.apple.PlugInKit:discovery] [d 88616305-672E-4143-81A6-832522BCD790] <PKHost:0x7e6c24900> Beginning discovery for flags: 0, point: com.apple.authentication-services-credential-provider-ui 2026-05-29 08:43:09.390070-0700 0xd7d00 Info 0x83c0b1 26490 0 CredentialProviderExtensionHelper: (PlugInKit) [com.apple.PlugInKit:discovery] [d 88616305-672E-4143-81A6-832522BCD790] <PKHost:0x7e6c24900> Query: { "LS:ExtensionPlatforms" = ( 1, 6, 2 ); NSExtensionPointName = "com.apple.authentication-services-credential-provider-ui"; NSUserElection = 1; } 2026-05-29 08:43:09.392893-0700 0xd79ee Debug 0x83c0b1 487 0 pkd: (PlugInKit) [com.apple.PlugInKit:sandbox] issued file extension for [/Applications/test.app/Contents/PlugIns/testIDCredentialProvider.appex] 2026-05-29 08:43:09.392936-0700 0xd79ee Debug 0x83c0b1 487 0 pkd: (PlugInKit) [com.apple.PlugInKit:ls] [u C85BFC1E-25E1-4917-A1D8-0123013482EE] [com.myapp.test.App.testid-credential-provider(7.35)] info [CFBundleIdentifier] => [com.myapp.test.App.testid-credential-provider] 2026-05-29 08:43:09.392947-0700 0xd79ee Debug 0x83c0b1 487 0 pkd: (PlugInKit) [com.apple.PlugInKit:sandbox] issued mach extension for [com.myapp.test.App.testid-credential-provider] And I see it being discovered correctly: 2026-05-29 08:43:09.394535-0700 0xd7d00 Default 0x83c0b2 26490 0 CredentialProviderExtensionHelper: (ExtensionFoundation) [com.apple.extensionkit:NSExtension] discovered extensions: attributes { "LS:ExtensionPlatforms" = ( 1, 6, 2 ); NSExtensionPointName = "com.apple.authentication-services-credential-provider-ui"; NSUserElection = 1; }, extensionSet {( <EXConcreteExtension: 0x7e71b41c0> {id = com.myapp.test.App.testid-credential-provider} )} I don't see any errors related to security or provisioning that I can tell. Any tricks I can use to see why I can't use my Credential Provider?
4
0
858
Jun ’26
PCC VRE: 403 Forbidden when downloading SW Release 41303
Is anyone else seeing 403 errors for PCC VRE when trying to pull assets for Release 41303? My pccvre audit of the Transparency Log passes (valid root digests for 41385), but the download fails consistently on specific CDN URLs: Failed to download SW release asset... response: 403 I’ve verified csrutil allow-research-guests is active and the license is accepted. Release 41385 seems fine, but 41303 is a brick wall. Is this a known pull-back or a CDN permissions sync issue?
1
0
550
Jun ’26
canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics) returns LAError.biometryNotAvailable despite Face ID being configured
We have encountered an issue reported by one of our users involving the Local Authentication framework. In our biometric authentication flow, we first check biometric availability using: let context = LAContext() var error: NSError? let canEvaluate = context.canEvaluatePolicy( .deviceOwnerAuthenticationWithBiometrics, error: &error ) For this particular user, canEvaluatePolicy repeatedly returned false with the error LAError.biometryNotAvailable (observed 7 times in our logs). What makes this unexpected is that: The user had Face ID configured and actively using it on the device. The user reported that they had not changed their Face ID enrollment. The user reported that they had not changed their device passcode. We are not aware of any MDM restrictions applied to the device. The issue appears to have been transient, as it was reported only for this user. We are trying to better understand under what conditions iOS may return LAError.biometryNotAvailable even when Face ID is configured on the device. Some questions we have: Are there known scenarios where Face ID is enrolled but canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics) can temporarily return LAError.biometryNotAvailable? Can iOS return this error during transient system states (e.g., Face ID subsystem restart, device startup, system update, thermal conditions, etc.)? Is there any recommended diagnostic information we should collect to help identify the root cause when this occurs in production? Environment: iOS version: 26.4.2 Device model: iPhone 14 Pro Max LocalAuthentication framework Face ID authentication Any insights into possible causes of this behavior would be appreciated.
1
0
575
Jun ’26
How to make app appear in Input Monitoring permissions list (like Accessibility does automatically)?
My app needs both Accessibility and Input Monitoring permissions. Accessibility works as expected — calling AXIsProcessTrusted() automatically adds the app to System Settings > Privacy & Security > Accessibility, and the user just needs to toggle it on. Input Monitoring doesn't behave the same way. I'm calling CGRequestListenEventAccess() and creating a CGEvent.tapCreate(.listenOnly), but the app doesn't reliably appear in the Input Monitoring list. The user opens the pane and sees nothing to enable. What I've tried: CGRequestListenEventAccess() — shows the system prompt once per install, but doesn't always add the app to the list CGEvent.tapCreate(tap: .cgSessionEventTap, place: .headInsertEventTap, options: .listenOnly, ...) — returns nil before Accessibility is granted; after Accessibility is granted, the tap succeeds but the app still may not appear in the Input Monitoring list 3. Calling both after Accessibility is confirmed, with a delay before opening the Settings pane The flow: User grants Accessibility (app appears automatically via AXIsProcessTrusted()) App creates a listen-only CGEventTap (succeeds) App opens x-apple.systempreferences:com.apple.preference.security?Privacy_ListenEvent User sees the Input Monitoring pane but the app is not listed Environment: macOS 15 (Sequoia), signed and notarized app, correct bundle ID, Hardened Runtime with com.apple.security.device.audio-input-monitoring entitlement not set (not applicable — this is for audio, not HID). Question: Is there an API equivalent to AXIsProcessTrusted() that reliably registers an app in the Input Monitoring list? Or is there a specific entitlement, Info.plist key, or sequence of calls required on macOS 14+/15 to ensure the app appears?
1
0
1.1k
May ’26
How to muse app appear in Input Monitoring permissions list (like Accessibility does automatically)?
My app needs both Accessibility and Input Monitoring permissions. Accessibility works as expected - calling AXIsProcesstrusted() automatically adds the app to System Settings > Privacy & Security > Accessibility, and the user just needs to toggle it on. Input Monitoring doesn't behave the same way. I'm calling CGRequestListenEventAccess() and creating a CGEvent.tapCreate(.listenOnly), but the app doesn't reliably appear in the Input Monitoring list. The user opens the pane and sees nothing to enable. What I've tried: CGRequestListenEventAccess() — shows the system prompt once per install, but doesn't always add the app to the list CGEvet.tapCreate(tsp: .cgSessionEventTap, place: .headInsertEventTap, options: listenOnly, ...) — returns nil before Accessibility is granted; after Accessibility is granted, the tap succeeds but the app still may not appear in the Input Monitoring list Calling both after Accessibility is confirmed, with a delay before opening the Settings pane The flow: User grants Accessibility (app appears automatically via AXIsProcessTrusted()) App creates a listen-only CGEventTap (succeeds) App opens x-apple.systempreferences:com.apple.preferences.security?Privacy_ListenEvent User sees the Input Monitoring pane but the app is not listed Environment: macOS 15, signed and notarized app, correct bundle ID, Hardened Runtime with com.apple.security.device.audio-input-monitoring entitlement not set (not applicable). Is there an API equivalent to AXIsProcessTrusted() that reliably registers an app in the Input Monitoring list? Or is there a specific entitlement, Info.plist key, or sequence of calls required on macOS 14+/15 to ensure the app appears?
1
0
1.1k
May ’26
current security support for OS
Hi, is there official information about iOS and iPadOS versions which no longer get security updates/support. I only know of an unofficial site "endoflife.com" and by their data there are no updates for iOS v18 but where can I verify that this information is legit. Our strict policy only allows that we deploy our app for OS version which still get security updates. Regards
2
0
1.2k
May ’26
QuickLookAR shares the actual USDZ model instead of the original website URL — critical copyright and data leak issue on iOS 26
QuickLookAR shares the actual USDZ model instead of the original website URL — critical copyright and data leak issue on iOS 26 Since iOS 26, QuickLookAR (or ARQuickLookPreviewItem) no longer preserves the original web URL when sharing a model. Instead of sending the link to the hosted file, the system directly shares the actual USDZ model file with the recipient. This is a critical regression and a severe breach of intellectual property protection, as it exposes proprietary 3D models that must never be distributed outside of the controlled web environment. In earlier iOS versions (tested up to iOS 18), QuickLookAR correctly handled sharing — the share sheet would send the website link where the model is hosted, not the file itself. Starting with iOS 26, this behavior has changed and completely breaks the intended secure flow for AR experiences. Our project relies on allowing users to view models in AR via QuickLook, without ever transferring the underlying 3D assets. Now, the share operation forces full file sharing, giving end users unrestricted access to the model file, which can be copied, rehosted, or reverse-engineered. This issue critically affects production environments and prevents us from deploying our AR-based solutions. Implement a standard QuickLookAR preview with a USDZ file hosted on your web server (e.g., via ARQuickLookPreviewItem). 2. Open the AR view on iOS 26. 3. Tap the Share icon from QuickLookAR. 4. Send via any messenger (Telegram, WhatsApp, etc.). 5. Observe that the actual .usdz model is sent instead of the original website URL. ⸻ Expected behavior: QuickLookAR should share only the original URL (as in iOS 17–18), not the file itself. This ensures that intellectual property and licensed 3D models remain protected and controlled by the content owner. ⸻ Actual behavior: QuickLookAR shares the entire USDZ file, leaking the model content outside of the intended environment. ⸻ Impact: • Violation of copyright and confidential data policies • Loss of control over proprietary 3D assets • Breaking change for all existing web-based AR integrations • Critical blocker for AR production deployment ⸻ Environment: • iOS 26.0 and 26.1 (tested on iPhone 14, iPhone 15) • Safari + QuickLookAR integration • Works correctly on iOS 17 / iOS 18 ⸻ Notes: This regression appears to have been introduced in the latest iOS 26 system handling of QuickLookAR sharing. Please escalate this issue to the ARKit / QuickLook engineering team as it directly affects compliance, IP protection, and usability of AR features across production applications. Additional Notes / Verification: Please test this behavior yourself using the CheckAR test model on my website: https://admixreality.com/ios26/ • If the login page appears, click “Check AR” and then “View in Your Space”. • On iOS 18 and earlier, sharing correctly sends the website URL. • On iOS 26, sharing sends the actual USDZ model file. This clearly demonstrates the regression and the security/IP issue.
9
0
1.6k
May ’26
Platform SSO duplicate registration notifications after cancelled user registration during Setup Assistant / after login
We are implementing a Platform SSO extension on macOS and are seeing repeated registration notifications from AppSSOAgent for the same unresolved registration state. We are trying to understand whether this is expected Platform SSO behavior, or whether our extension should be returning a different registration result for a cancelled user-registration flow. Scenario 1: Setup Assistant / preboot cancellation Device registration succeeds during setup. User registration starts. The user closes/cancels the registration web auth UI. Setup completes and the user reaches the desktop. Two “registration required” notifications are posted a few seconds apart, before the user clicks anything. In AppSSOAgent logs, we see two separate cycles like: resetRegistrationWithCompletion handleUserRegistrationForUser:repair:newPasswordUser:newSmartCardUser:notified:profile: Sending registration notification Adding notification request ... then again roughly 10–12 seconds later, before any user action. In some runs, even if the user clicks the first notification and registration is already in progress, another notification still appears. If the first registration attempt does not complete successfully, registration does not finish and the user must click the second notification and repeat the registration flow. After acting on the second notification, registration may then succeed. Scenario 2: login / repair window already open In another run after logout/login, while the registration window is already open, AppSSOAgent posts another registration notification. Additional detail: In some runs, our extension logs show the web auth flow failing with: breaking calling recursion for caller with bundleIdentifier: ... no extension WebAuthenticationSession error 1 But the duplicate-notification behavior is specifically interesting when AppSSOAgent posts a second notification before any new desktop click/retry. We also see AppSSOAgent logs such as: Removing 1 delivered notifications with identifiers (...) Removing 1 pending notification requests with identifiers (...) which suggests the same Platform SSO registration notification can exist in both delivered and pending state before being reposted. Questions After a user cancels Platform SSO user registration UI during Setup Assistant, what is the expected ASAuthorizationProviderExtensionRegistrationResult the extension should return? (.failed, .userInterfaceRequired, something else?) Is it expected for AppSSOAgent to run multiple resetRegistrationWithCompletion / handleUserRegistrationForUser... cycles for the same incomplete registration state and post duplicate registration notifications before any user action? Is there any documented meaning for the retry timing gaps (for example ~3 seconds in some runs, ~11 seconds in others)? If the registration UI is cancelled by the user, is there a recommended way for the extension to prevent AppSSOAgent from re-posting multiple notifications for the same unresolved registration state? We want to understand whether the duplicate notifications are expected Apple-side Platform SSO behavior for incomplete registration, or whether the extension is expected to signal cancellation differently.
0
0
440
May ’26
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.
5
0
1.1k
May ’26
App Transfer Impact on DeviceCheck Token/keyid
Hello, I was planning to transfer an app to a different Apple Developer account and had a question regarding DeviceCheck behavior after the transfer. Currently, the app uses the DeviceCheck service with a DeviceCheck key associated with the transferring account. We are specifically interested in the period immediately after the app transfer, but before the app has been updated under the recipient account. Could you clarify the following: Will DeviceCheck validations continue to function after the app transfer using the existing DeviceCheck key and "iss" value associated with the transferor account? Or will DeviceCheck requests begin failing until a new DeviceCheck key is generated under the recipient account and our backend is updated to use the new "iss" value? Any guidance on the expected transition behavior would be greatly appreciated. Thank you.
1
0
713
May ’26
Platform SSO user registration never starts after successful device registration during Setup Assistant
I’m testing a macOS Platform SSO extension deployed through Jamf, and I’m seeing an issue where device registration completes successfully during Setup Assistant, but user registration never gets triggered. Current Platform SSO profile settings: Authentication mode:Secure Enclave Enable registration during setup:Enabled Create first user during Setup:Enabled New user creation authentication method:Password Observed behavior: The Platform SSO extension is discovered and loaded. Device registration starts and completes successfully. My extension’s device registration completion path is reached. registrationDidCompleteis called. The device configuration appears to be updated. After that, I expect Platform SSO to call the user registration flow, but my extension’sbeginUserRegistration(...)is never invoked. The strange part is that this only seems blocked at the user-registration handoff. Device registration during Setup Assistant works reliably.
2
0
618
May ’26
App Review Guidelines 2.5.1 / 2.5.2 — official guidance on screen capture protection for sensitive content
Hi all, We are developing an iOS app that includes private user-to-user chats, commercial offer details with monetary value, and customer identification data. In line with OWASP MASVS-PLATFORM-3 requirements regarding unintentional sensitive data exposure, we need to protect these specific screens from screenshots and screen recording. We have carefully reviewed the relevant App Review Guidelines (2.5.1 on public APIs, 2.5.2 on self-contained bundles, 5.1.1 on privacy) and the related Human Interface Guidelines. From this analysis we have observed the following: iOS does not expose a public API to globally disable screen capture (no direct equivalent of Android's FLAG_SECURE). The SwiftUI .privacySensitive() modifier is effective for Lock Screen widgets and Always-On Display, but it does not appear to prevent screenshots or screen recording of an app's main UI while in the foreground. A number of widely distributed App Store apps (banking, authenticator, secure messaging) implement some form of screenshot protection on sensitive screens. Several established open-source libraries leverage the system behavior of UITextField with isSecureTextEntry as a wrapping container for arbitrary views, in order to achieve pixel-level protection for sensitive content. We would appreciate clarification on the following points: For privacy-driven protection of sensitive screens (private chats, customer data, monetized offers), is there an officially recommended approach we may have missed? Are there public APIs intended specifically for this use case beyond .privacySensitive()? Is the practice of leveraging UITextField with isSecureTextEntry as a wrapping container for arbitrary views considered an acceptable use of public APIs under Guideline 2.5.1, or does it carry App Review risk? Are there official recommendations or documentation for apps handling sensitive personal data that wish to align with industry standards such as OWASP MASVS-PLATFORM-3 for screenshot and screen recording leakage prevention? The intended use is strictly limited to a small number of screens marked as containing sensitive data (private messages, deal details, customer information). The protection would be selective and clearly communicated to the user via in-app messaging, not global to the app. Thanks in advance for any clarification, including pointers to existing documentation or threads we may have missed. Deployment target: iOS 15+
5
0
1.2k
May ’26
Platform SSO registration dialogs remain after later success
We’re investigating a Platform SSO registration issue on macOS and wanted to check whether others have seen similar behavior or know whether this is expected system behavior. Scenario: Our extension implements ASAuthorizationProviderExtensionRegistrationHandler for device and user registration. On failure we complete with ASAuthorizationProviderExtensionRegistrationResult.failed, and on success we complete with .success. What we’re seeing: If registration fails multiple times, macOS shows multiple system dialogs saying: Registration failed and will automatically retry in a few minutes. If we do not close those earlier failure dialogs and then start another registration that succeeds, the old failure dialogs remain visible and do not dismiss automatically. They have to be closed manually one by one. From our side, these appear to be system-owned Platform SSO dialogs, not app-owned windows. We only return the registration result via the handler completion. Any guidance on whether macOS is expected to reconcile/dismiss earlier failure dialogs after a later success would also be helpful.
5
0
1.3k
May ’26
SFAuthorizationPluginView
I’ve developed an authorization plug-in with a mechanism that runs an SFAuthorizationPluginView subclass and I’m facing a couple issues: - Glitch after successful login After setting kAuthorizationResultAllow in the context the user is successfully logged in and brought to the desktop but the login controls remain onscreen for a few seconds after login is complete, resulting in them being visible at the same time as the dock, menu bar and desktop.
 I’ve also tried what’s mentioned here https://developer.apple.com/forums/thread/780212 but without any luck. It’s also worth mentioning that the deinit() in my SFAuthorizationPluginView subclass never gets called when the plugin it’s loaded at the login stage but it does get called the plugin is used to re-authenticate the user after they locked their screen. - update() doesn't trigger the plugin to call view(for:) I’m trying to update the UI elements out of my control (like buttons and user avatar images) in order to have them placed at the proper position on the screen after a resize of my inner NSView. To do that I call update() but it appears that does not trigger the plugin to call view(for:) and update system UI elements placement. Is this the expected behavior? - setButton not working as expected 
I’m trying to disable the login button by calling the setButton(_:enabled:) passing a SFButtonTypeLogin as inButtonType, as suggested here: https://developer.apple.com/forums/thread/777432. When the method is called at the login screen it has no effect on the button (the one with the forward-arrow icon) but when it’s called by the plugin loaded at the ‘unlock screen’ stage it successfully disable the ‘OK’ button. - Certificate issue When trying to run a network request from the plugin loaded in the ‘unlock screen’ scenario, I always get this type of error: The certificate for this server is invalid. You might be connecting to a server that is pretending to be <<server_url>> which could put your confidential information at risk Everything works as expected when the plugin is loaded either at login screen or for authorizing an operation that requires admin privileges while the user is logged in.
4
0
1k
May ’26
LAContext and its usage in context of Local Authentication
While working with Local Authentication framework, specifically LAContext class I found myself with few contradictions to documentation, and although I believe that those differences are rather positive than negative, either documentation is lacking behind or those APIs are not working as intended - which I believe is combination of both. 1. Local Authentication 1.1 Biometry type, and associated with it hash With introduction of LADomainState one can extract underlying biometry type along it's (current) state hash this way: @available(iOS 18, macOS 15, *) func postIOS18() { let context = LAContext() let biometryType = context.domainState.biometry.biometryType // (1) let biometryStateHash = context.domainState.biometry.stateHash // (2) } prior to receiving above APIs, we would retrieve such information something along those lines: func preIOS18() { let context = LAContext() let policy: LAPolicy // ... var error: NSError? _ = context.canEvaluatePolicy(policy, error: error) // (3) // ... (Handle error - if present) let biometryType = context.biometryType // (4) let biometryStateHash = context.evaluatedPolicyDomainState // (5) } However, moving let biometryType = context.biometryType (4) before call to canEvaluatePolicy (3) still yields correct biometry type. This is in contradiction to article from Local Authentication documentation page Optionally, Adjust Your User Interface to Accommodate Face ID. Furthermore, biometryType documentation does not mentions such requirement. Another difference is that call to canEvaluatePolicy (3) might return an error, eg. LAError(.biometryLockout) (if implemented correctly) preventing as from returning biometryStateHash (5) with nil value. This is not the case for new API, where the same call (2) will yield nil as a result - LADomainStateBiometry documentation does not mention it. In summary, here are some questions: Which API should be used to retrieve biometry type?, and why the "older way" has not been deprecated? Is is safe to assume that calls to biometryType and stateHash from LADomainStateBiometry will produce meaningful results without prior call to canEvaluatePolicy? Should I assume that call to biometryType found on LAContext instance will always return biometryType without prior call to canEvaluatePolicy?, or perhaps those are only side effects of changes made to accommodate LADomainState, and prior to them (pre-iOS 18) we must call canEvaluatePolicy to get meaningful value. Are the stateHash properties found on LADomainState, LADomainStateBiometry and LADomainStateCompanion will return nil upon encountering any error under the hood? (which would be equivalent of below code, prior to iOS 18) func biometryStateHash() -> Data? { let context = LAContext() if #available(iOS 18, macOS 15, *) { _ = context.canEvaluatePolicy(policy, error: nil) return context.evaluatedPolicyDomainState } else { return context.domainState.biometry.stateHash } } 1.2 Deprecation of evaluatedDomainState There is a forum post LAContext.evaluatedPolicyDomainState change between major OS versions mentioning missing documentation (fixed), however there's still information missing of how they correlate to each other. From my findings, the deprecated evaluatedDomainState property value matches those of LADomainState stateHash (when no companion device is present), and LADomainStateBiometry stateHash (all the time). Are those assumptions correct? 1.3 LAContext (authenticated) session lifespan Theres is little information about it state when authenticated by the user. Documentation on LAContext does not mention this behavior, while there are hints that once authenticated, and context is reused, any farther calls will not prompt user with UI. The problem is that this behavior is little, to no documented. Here are few examples I have found: Logging a User into Your App with Face ID or Touch ID (code sample) contains comment // Get a fresh context for each login. If you use the same context on multiple attempts //  (by commenting out the next line), then a previously successful authentication //  causes the next policy evaluation to succeed without testing biometry again. //  That's usually not what you want. Recent forum post, where such approach is mentioned by Quinn 'The Eskimo!' "At the API level, one option you have is to create an LAContext and pass it in to each SecItemCopyMatching call via kSecUseAuthenticationContext." WWDC22 Streamline local authorization flows session "By binding the LAContext to our private key reference, we ensure that executing the signature operation will not trigger another authentication, while allowing the operation to continue without unnecessary prompts. These binding also means that no additional user interactions will be required for future signatures until the LAContext is invalidated." Furthermore this is complicated by the touchIDAuthenticationAllowableReuseDuration property from LAContext instance which states that "The default value is 0, meaning that no previous biometric unlock can be reused." which is in direct contradiction to what I have experienced while working with LAContext and sources mentioned above. While digging on this, whether this behavior is intended or not, I came across a post (I would love to share it, but the domain is not permitted) that shared the same findings (and concerns) regarding LAContext behavior as me. The author also provided a FB9984036 feedback number - although no further update was made on that topic. So my questions are: Is it safe to reuse LAContext (authenticated) instance? How long such instance is considered authenticated?, is it a time duration or perhaps it stays in authenticated state until explicitly invalidated using invalidate method. (its invalidated for sure when app is terminated, but this was to be expected :)) How does,touchIDAuthenticationAllowableReuseDuration work, and how does it correlate to "reusability" of the authenticated LAContext instance? In what scenarios, touchIDAuthenticationAllowableReuseDuration should be used and what is its expected behavior? (I have tried it both on iOS and macOS; from my perspective API this does not "work")
2
0
477
May ’26
How much practical benefit is there to XPC-based privilege separation?
"Privilege separation" is one of the "two main reasons to use XPC services" given by https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPSystemStartup/Chapters/CreatingXPCServices.html — With traditional applications, if an application becomes compromised through a buffer overflow or other security vulnerability, the attacker gains the ability to do anything that the user can do. To mitigate this risk, Mac OS X provides sandboxing—limiting what types of operations a process can perform. […] Each XPC service has its own sandbox, so XPC services can make it easier to implement proper privilege separation. The idea (iiuc) being that if the main process is compromised, the spicier operations have been separated out to a separate process space, and this improves the security of the system. But if the main process is compromised, and that main process is trusted by the more-privileged XPC service, is not the system still compromised in practice? That is rather than the exploit being: exploit some vulnerability gain arbitrary code execution do something naughty isn't the same still possible with just one extra step: exploit vulnerability arbitrary execution ask the XPC service nicely… …to do something naughty?
3
0
311
May ’26
LAContext and its usage in context of Local Authentication
While working with Local Authentication framework, specifically LAContext class I found myself with few contradictions to documentation, and although I believe that those differences are rather positive than negative, either documentation is lacking behind or those APIs are not working as intended - which I believe is combination of both. 1. Local Authentication 1.1 Biometry type, and associated with it hash With introduction of LADomainState one can extract underlying biometry type along it's (current) state hash this way: @available(iOS 18, macOS 15, *) func postIOS18() { let context = LAContext() let biometryType = context.domainState.biometry.biometryType // (1) let biometryStateHash = context.domainState.biometry.stateHash // (2) } prior to receiving above APIs, we would retrieve such information something along those lines: func preIOS18() { let context = LAContext() let policy: LAPolicy // ... var error: NSError? _ = context.canEvaluatePolicy(policy, error: error) // (3) // ... (Handle error - if present) let biometryType = context.biometryType // (4) let biometryStateHash = context.evaluatedPolicyDomainState // (5) } However, moving let biometryType = context.biometryType (4) before call to canEvaluatePolicy (3) still yields correct biometry type. This is in contradiction to article from Local Authentication documentation page Optionally, Adjust Your User Interface to Accommodate Face ID. Furthermore, biometryType documentation does not mentions such requirement. Another difference is that call to canEvaluatePolicy (3) might return an error, eg. LAError(.biometryLockout) (if implemented correctly) preventing as from returning biometryStateHash (5) with nil value. This is not the case for new API, where the same call (2) will yield nil as a result - LADomainStateBiometry documentation does not mention it. In summary, here are some questions: Which API should be used to retrieve biometry type?, and why the "older way" has not been deprecated? Is is safe to assume that calls to biometryType and stateHash from LADomainStateBiometry will produce meaningful results without prior call to canEvaluatePolicy? Should I assume that call to biometryType found on LAContext instance will always return biometryType without prior call to canEvaluatePolicy?, or perhaps those are only side effects of changes made to accommodate LADomainState, and prior to them (pre-iOS 18) we must call canEvaluatePolicy to get meaningful value. Are the stateHash properties found on LADomainState, LADomainStateBiometry and LADomainStateCompanion will return nil upon encountering any error under the hood? (which would be equivalent of below code, prior to iOS 18) func biometryStateHash() -> Data? { let context = LAContext() if #available(iOS 18, macOS 15, *) { _ = context.canEvaluatePolicy(policy, error: nil) return context.evaluatedPolicyDomainState } else { return context.domainState.biometry.stateHash } } 1.2 Deprecation of evaluatedDomainState There is a forum post LAContext.evaluatedPolicyDomainState change between major OS versions mentioning missing documentation (fixed), however there's still information missing of how they correlate to each other. From my findings, the deprecated evaluatedDomainState property value matches those of LADomainState stateHash (when no companion device is present), and LADomainStateBiometry stateHash (all the time). Are those assumptions correct? 1.3 LAContext (authenticated) session lifespan Theres is little information about it state when authenticated by the user. Documentation on LAContext does not mention this behavior, while there are hints that once authenticated, and context is reused, any farther calls will not prompt user with UI. The problem is that this behavior is little, to no documented. Here are few examples I have found: Logging a User into Your App with Face ID or Touch ID (code sample) contains comment // Get a fresh context for each login. If you use the same context on multiple attempts //  (by commenting out the next line), then a previously successful authentication //  causes the next policy evaluation to succeed without testing biometry again. //  That's usually not what you want. Recent forum post, where such approach is mentioned by Quinn 'The Eskimo!' "At the API level, one option you have is to create an LAContext and pass it in to each SecItemCopyMatching call via kSecUseAuthenticationContext." WWDC22 Streamline local authorization flows session "By binding the LAContext to our private key reference, we ensure that executing the signature operation will not trigger another authentication, while allowing the operation to continue without unnecessary prompts. These binding also means that no additional user interactions will be required for future signatures until the LAContext is invalidated." Furthermore this is complicated by the touchIDAuthenticationAllowableReuseDuration property from LAContext instance which states that "The default value is 0, meaning that no previous biometric unlock can be reused." which is in direct contradiction to what I have experienced while working with LAContext and sources mentioned above. While digging on this, whether this behavior is intended or not, I came across a post (I would love to share it, but the domain is not permitted) that shared the same findings (and concerns) regarding LAContext behavior as me. The author also provided a FB9984036 feedback number - although no further update was made on that topic. So my questions are: Is it safe to reuse LAContext (authenticated) instance? How long such instance is considered authenticated?, is it a time duration or perhaps it stays in authenticated state until explicitly invalidated using invalidate method. (its invalidated for sure when app is terminated, but this was to be expected :)) How does touchIDAuthenticationAllowableReuseDuration work, and how does it correlate to "reusability" of the authenticated LAContext instance? In what scenarios touchIDAuthenticationAllowableReuseDuration should be used and what is its expected behavior? (I have tried it both on iOS and macOS; from my perspective API this does not "work")
1
0
438
May ’26
Protecting sensitive data in memory.
I am developing a library called MemoryCryptor for macOS. Its purpose is to protect sensitive data of the calling process (including launchd daemons), e.g. user passwords and other secrets, from being written to disk or read directly by debuggers or malware. This is a mandatory security requirement from our internal Security Team. On Windows we rely on DPAPI, which stores a per‑process cryptographic key outside the calling process’s address space, ensuring that key material and ciphertext never coexist in the same memory space. I have evaluated the following macOS options, but each presents limitations for our threat model: Secure Enclave (CryptoKit.framework). Keys generated using the Secure Enclave are not bound to the creating app. The dataRepresentation of a PrivateKey resides in the caller’s memory, allowing another process that can read a memory dump on the same machine to decrypt the data. Keychain API. Keys are always loaded into the calling process’s address space before any cryptographic operation, exposing them to memory‑dump attacks. Separate helper via XPC. While this could isolate key material, it requires full control of IPC implementation - plaintext may remain in the implementation's internal buffers. Given these constraints, are there any macOS‑native mechanisms or recommended architectures that allow us to keep cryptographic keys completely out of the calling process’s memory while still performing encryption/decryption on behalf of that process? Any guidance, best‑practice references, or alternative APIs would be greatly appreciated. Thank you for your assistance.
2
0
315
May ’26
Keychain Group
Dear Apple Developer Support Team, I would like to inquire whether there is a stable and official method to obtain the correct Team ID. When my app attempts to store data in the Keychain on a physical device, the retrieved Team ID is an unknown one and does not match the Team ID of my developer certificate. This issue consistently results in Keychain access failure with error code -34018. Could you please advise the root cause and provide a reliable solution to fix this Team ID mismatch and resolve the -34018 Keychain error? NSDictionary *query = [NSDictionary dictionaryWithObjectsAndKeys: kSecClassGenericPassword, kSecClass, @"bundleSeedID", kSecAttrAccount, @"", kSecAttrService, (id)kCFBooleanTrue, kSecReturnAttributes, nil]; CFDictionaryRef result = nil; OSStatus status = SecItemCopyMatching((CFDictionaryRef)query, (CFTypeRef *)&result); if (status == errSecItemNotFound) status = SecItemAdd((CFDictionaryRef)query, (CFTypeRef *)&result); if (status != errSecSuccess) return nil; NSString *accessGroup = [(__bridge NSDictionary *)result objectForKey:kSecAttrAccessGroup]; NSArray *components = [accessGroup componentsSeparatedByString:@"."]; NSString *bundleSeedID = [[components objectEnumerator] nextObject]; CFRelease(result); return bundleSeedID;
5
0
967
May ’26
AutoFill extension loading woes
I'm trying to diagnose some issues with my AutoFill credential provider not loading on macOS. As far as I can tell I have all the entitlements and provisioning profiles correct, and ASSettingsHelper.requestToTurnOnCredentialProviderExtension() returns true with the Credential Provider showing up enabled in System Settings. However all other attempts to call into AuthenticationServices fail, and ASCredentialIdentityStore.shared.getState() always returns false for state.isEnabled Looking at the logs I don't see anything that stands out but I am not sure I've got the correct filter on the logs. I see discovery taking place 2026-05-29 08:43:09.389967-0700 0xd7d00 Default 0x83c0b1 26490 0 CredentialProviderExtensionHelper: (PlugInKit) [com.apple.PlugInKit:discovery] [d 88616305-672E-4143-81A6-832522BCD790] <PKHost:0x7e6c24900> Beginning discovery for flags: 0, point: com.apple.authentication-services-credential-provider-ui 2026-05-29 08:43:09.390070-0700 0xd7d00 Info 0x83c0b1 26490 0 CredentialProviderExtensionHelper: (PlugInKit) [com.apple.PlugInKit:discovery] [d 88616305-672E-4143-81A6-832522BCD790] <PKHost:0x7e6c24900> Query: { "LS:ExtensionPlatforms" = ( 1, 6, 2 ); NSExtensionPointName = "com.apple.authentication-services-credential-provider-ui"; NSUserElection = 1; } 2026-05-29 08:43:09.392893-0700 0xd79ee Debug 0x83c0b1 487 0 pkd: (PlugInKit) [com.apple.PlugInKit:sandbox] issued file extension for [/Applications/test.app/Contents/PlugIns/testIDCredentialProvider.appex] 2026-05-29 08:43:09.392936-0700 0xd79ee Debug 0x83c0b1 487 0 pkd: (PlugInKit) [com.apple.PlugInKit:ls] [u C85BFC1E-25E1-4917-A1D8-0123013482EE] [com.myapp.test.App.testid-credential-provider(7.35)] info [CFBundleIdentifier] => [com.myapp.test.App.testid-credential-provider] 2026-05-29 08:43:09.392947-0700 0xd79ee Debug 0x83c0b1 487 0 pkd: (PlugInKit) [com.apple.PlugInKit:sandbox] issued mach extension for [com.myapp.test.App.testid-credential-provider] And I see it being discovered correctly: 2026-05-29 08:43:09.394535-0700 0xd7d00 Default 0x83c0b2 26490 0 CredentialProviderExtensionHelper: (ExtensionFoundation) [com.apple.extensionkit:NSExtension] discovered extensions: attributes { "LS:ExtensionPlatforms" = ( 1, 6, 2 ); NSExtensionPointName = "com.apple.authentication-services-credential-provider-ui"; NSUserElection = 1; }, extensionSet {( <EXConcreteExtension: 0x7e71b41c0> {id = com.myapp.test.App.testid-credential-provider} )} I don't see any errors related to security or provisioning that I can tell. Any tricks I can use to see why I can't use my Credential Provider?
Replies
4
Boosts
0
Views
858
Activity
Jun ’26
PCC VRE: 403 Forbidden when downloading SW Release 41303
Is anyone else seeing 403 errors for PCC VRE when trying to pull assets for Release 41303? My pccvre audit of the Transparency Log passes (valid root digests for 41385), but the download fails consistently on specific CDN URLs: Failed to download SW release asset... response: 403 I’ve verified csrutil allow-research-guests is active and the license is accepted. Release 41385 seems fine, but 41303 is a brick wall. Is this a known pull-back or a CDN permissions sync issue?
Replies
1
Boosts
0
Views
550
Activity
Jun ’26
canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics) returns LAError.biometryNotAvailable despite Face ID being configured
We have encountered an issue reported by one of our users involving the Local Authentication framework. In our biometric authentication flow, we first check biometric availability using: let context = LAContext() var error: NSError? let canEvaluate = context.canEvaluatePolicy( .deviceOwnerAuthenticationWithBiometrics, error: &error ) For this particular user, canEvaluatePolicy repeatedly returned false with the error LAError.biometryNotAvailable (observed 7 times in our logs). What makes this unexpected is that: The user had Face ID configured and actively using it on the device. The user reported that they had not changed their Face ID enrollment. The user reported that they had not changed their device passcode. We are not aware of any MDM restrictions applied to the device. The issue appears to have been transient, as it was reported only for this user. We are trying to better understand under what conditions iOS may return LAError.biometryNotAvailable even when Face ID is configured on the device. Some questions we have: Are there known scenarios where Face ID is enrolled but canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics) can temporarily return LAError.biometryNotAvailable? Can iOS return this error during transient system states (e.g., Face ID subsystem restart, device startup, system update, thermal conditions, etc.)? Is there any recommended diagnostic information we should collect to help identify the root cause when this occurs in production? Environment: iOS version: 26.4.2 Device model: iPhone 14 Pro Max LocalAuthentication framework Face ID authentication Any insights into possible causes of this behavior would be appreciated.
Replies
1
Boosts
0
Views
575
Activity
Jun ’26
How to make app appear in Input Monitoring permissions list (like Accessibility does automatically)?
My app needs both Accessibility and Input Monitoring permissions. Accessibility works as expected — calling AXIsProcessTrusted() automatically adds the app to System Settings > Privacy & Security > Accessibility, and the user just needs to toggle it on. Input Monitoring doesn't behave the same way. I'm calling CGRequestListenEventAccess() and creating a CGEvent.tapCreate(.listenOnly), but the app doesn't reliably appear in the Input Monitoring list. The user opens the pane and sees nothing to enable. What I've tried: CGRequestListenEventAccess() — shows the system prompt once per install, but doesn't always add the app to the list CGEvent.tapCreate(tap: .cgSessionEventTap, place: .headInsertEventTap, options: .listenOnly, ...) — returns nil before Accessibility is granted; after Accessibility is granted, the tap succeeds but the app still may not appear in the Input Monitoring list 3. Calling both after Accessibility is confirmed, with a delay before opening the Settings pane The flow: User grants Accessibility (app appears automatically via AXIsProcessTrusted()) App creates a listen-only CGEventTap (succeeds) App opens x-apple.systempreferences:com.apple.preference.security?Privacy_ListenEvent User sees the Input Monitoring pane but the app is not listed Environment: macOS 15 (Sequoia), signed and notarized app, correct bundle ID, Hardened Runtime with com.apple.security.device.audio-input-monitoring entitlement not set (not applicable — this is for audio, not HID). Question: Is there an API equivalent to AXIsProcessTrusted() that reliably registers an app in the Input Monitoring list? Or is there a specific entitlement, Info.plist key, or sequence of calls required on macOS 14+/15 to ensure the app appears?
Replies
1
Boosts
0
Views
1.1k
Activity
May ’26
How to muse app appear in Input Monitoring permissions list (like Accessibility does automatically)?
My app needs both Accessibility and Input Monitoring permissions. Accessibility works as expected - calling AXIsProcesstrusted() automatically adds the app to System Settings > Privacy & Security > Accessibility, and the user just needs to toggle it on. Input Monitoring doesn't behave the same way. I'm calling CGRequestListenEventAccess() and creating a CGEvent.tapCreate(.listenOnly), but the app doesn't reliably appear in the Input Monitoring list. The user opens the pane and sees nothing to enable. What I've tried: CGRequestListenEventAccess() — shows the system prompt once per install, but doesn't always add the app to the list CGEvet.tapCreate(tsp: .cgSessionEventTap, place: .headInsertEventTap, options: listenOnly, ...) — returns nil before Accessibility is granted; after Accessibility is granted, the tap succeeds but the app still may not appear in the Input Monitoring list Calling both after Accessibility is confirmed, with a delay before opening the Settings pane The flow: User grants Accessibility (app appears automatically via AXIsProcessTrusted()) App creates a listen-only CGEventTap (succeeds) App opens x-apple.systempreferences:com.apple.preferences.security?Privacy_ListenEvent User sees the Input Monitoring pane but the app is not listed Environment: macOS 15, signed and notarized app, correct bundle ID, Hardened Runtime with com.apple.security.device.audio-input-monitoring entitlement not set (not applicable). Is there an API equivalent to AXIsProcessTrusted() that reliably registers an app in the Input Monitoring list? Or is there a specific entitlement, Info.plist key, or sequence of calls required on macOS 14+/15 to ensure the app appears?
Replies
1
Boosts
0
Views
1.1k
Activity
May ’26
current security support for OS
Hi, is there official information about iOS and iPadOS versions which no longer get security updates/support. I only know of an unofficial site "endoflife.com" and by their data there are no updates for iOS v18 but where can I verify that this information is legit. Our strict policy only allows that we deploy our app for OS version which still get security updates. Regards
Replies
2
Boosts
0
Views
1.2k
Activity
May ’26
QuickLookAR shares the actual USDZ model instead of the original website URL — critical copyright and data leak issue on iOS 26
QuickLookAR shares the actual USDZ model instead of the original website URL — critical copyright and data leak issue on iOS 26 Since iOS 26, QuickLookAR (or ARQuickLookPreviewItem) no longer preserves the original web URL when sharing a model. Instead of sending the link to the hosted file, the system directly shares the actual USDZ model file with the recipient. This is a critical regression and a severe breach of intellectual property protection, as it exposes proprietary 3D models that must never be distributed outside of the controlled web environment. In earlier iOS versions (tested up to iOS 18), QuickLookAR correctly handled sharing — the share sheet would send the website link where the model is hosted, not the file itself. Starting with iOS 26, this behavior has changed and completely breaks the intended secure flow for AR experiences. Our project relies on allowing users to view models in AR via QuickLook, without ever transferring the underlying 3D assets. Now, the share operation forces full file sharing, giving end users unrestricted access to the model file, which can be copied, rehosted, or reverse-engineered. This issue critically affects production environments and prevents us from deploying our AR-based solutions. Implement a standard QuickLookAR preview with a USDZ file hosted on your web server (e.g., via ARQuickLookPreviewItem). 2. Open the AR view on iOS 26. 3. Tap the Share icon from QuickLookAR. 4. Send via any messenger (Telegram, WhatsApp, etc.). 5. Observe that the actual .usdz model is sent instead of the original website URL. ⸻ Expected behavior: QuickLookAR should share only the original URL (as in iOS 17–18), not the file itself. This ensures that intellectual property and licensed 3D models remain protected and controlled by the content owner. ⸻ Actual behavior: QuickLookAR shares the entire USDZ file, leaking the model content outside of the intended environment. ⸻ Impact: • Violation of copyright and confidential data policies • Loss of control over proprietary 3D assets • Breaking change for all existing web-based AR integrations • Critical blocker for AR production deployment ⸻ Environment: • iOS 26.0 and 26.1 (tested on iPhone 14, iPhone 15) • Safari + QuickLookAR integration • Works correctly on iOS 17 / iOS 18 ⸻ Notes: This regression appears to have been introduced in the latest iOS 26 system handling of QuickLookAR sharing. Please escalate this issue to the ARKit / QuickLook engineering team as it directly affects compliance, IP protection, and usability of AR features across production applications. Additional Notes / Verification: Please test this behavior yourself using the CheckAR test model on my website: https://admixreality.com/ios26/ • If the login page appears, click “Check AR” and then “View in Your Space”. • On iOS 18 and earlier, sharing correctly sends the website URL. • On iOS 26, sharing sends the actual USDZ model file. This clearly demonstrates the regression and the security/IP issue.
Replies
9
Boosts
0
Views
1.6k
Activity
May ’26
Sharing ScreenTime data to a custom server
With the ScreenTime API Apple talks a lot about their focus on privacy and the data not leaving the device. Does that mean there would be a problem with an app where the users ScreenTime data is shared to a custom backend? Could this potentially cause an app to be rejected from the AppStore?
Replies
4
Boosts
2
Views
1.3k
Activity
May ’26
Platform SSO duplicate registration notifications after cancelled user registration during Setup Assistant / after login
We are implementing a Platform SSO extension on macOS and are seeing repeated registration notifications from AppSSOAgent for the same unresolved registration state. We are trying to understand whether this is expected Platform SSO behavior, or whether our extension should be returning a different registration result for a cancelled user-registration flow. Scenario 1: Setup Assistant / preboot cancellation Device registration succeeds during setup. User registration starts. The user closes/cancels the registration web auth UI. Setup completes and the user reaches the desktop. Two “registration required” notifications are posted a few seconds apart, before the user clicks anything. In AppSSOAgent logs, we see two separate cycles like: resetRegistrationWithCompletion handleUserRegistrationForUser:repair:newPasswordUser:newSmartCardUser:notified:profile: Sending registration notification Adding notification request ... then again roughly 10–12 seconds later, before any user action. In some runs, even if the user clicks the first notification and registration is already in progress, another notification still appears. If the first registration attempt does not complete successfully, registration does not finish and the user must click the second notification and repeat the registration flow. After acting on the second notification, registration may then succeed. Scenario 2: login / repair window already open In another run after logout/login, while the registration window is already open, AppSSOAgent posts another registration notification. Additional detail: In some runs, our extension logs show the web auth flow failing with: breaking calling recursion for caller with bundleIdentifier: ... no extension WebAuthenticationSession error 1 But the duplicate-notification behavior is specifically interesting when AppSSOAgent posts a second notification before any new desktop click/retry. We also see AppSSOAgent logs such as: Removing 1 delivered notifications with identifiers (...) Removing 1 pending notification requests with identifiers (...) which suggests the same Platform SSO registration notification can exist in both delivered and pending state before being reposted. Questions After a user cancels Platform SSO user registration UI during Setup Assistant, what is the expected ASAuthorizationProviderExtensionRegistrationResult the extension should return? (.failed, .userInterfaceRequired, something else?) Is it expected for AppSSOAgent to run multiple resetRegistrationWithCompletion / handleUserRegistrationForUser... cycles for the same incomplete registration state and post duplicate registration notifications before any user action? Is there any documented meaning for the retry timing gaps (for example ~3 seconds in some runs, ~11 seconds in others)? If the registration UI is cancelled by the user, is there a recommended way for the extension to prevent AppSSOAgent from re-posting multiple notifications for the same unresolved registration state? We want to understand whether the duplicate notifications are expected Apple-side Platform SSO behavior for incomplete registration, or whether the extension is expected to signal cancellation differently.
Replies
0
Boosts
0
Views
440
Activity
May ’26
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.
Replies
5
Boosts
0
Views
1.1k
Activity
May ’26
App Transfer Impact on DeviceCheck Token/keyid
Hello, I was planning to transfer an app to a different Apple Developer account and had a question regarding DeviceCheck behavior after the transfer. Currently, the app uses the DeviceCheck service with a DeviceCheck key associated with the transferring account. We are specifically interested in the period immediately after the app transfer, but before the app has been updated under the recipient account. Could you clarify the following: Will DeviceCheck validations continue to function after the app transfer using the existing DeviceCheck key and "iss" value associated with the transferor account? Or will DeviceCheck requests begin failing until a new DeviceCheck key is generated under the recipient account and our backend is updated to use the new "iss" value? Any guidance on the expected transition behavior would be greatly appreciated. Thank you.
Replies
1
Boosts
0
Views
713
Activity
May ’26
Platform SSO user registration never starts after successful device registration during Setup Assistant
I’m testing a macOS Platform SSO extension deployed through Jamf, and I’m seeing an issue where device registration completes successfully during Setup Assistant, but user registration never gets triggered. Current Platform SSO profile settings: Authentication mode:Secure Enclave Enable registration during setup:Enabled Create first user during Setup:Enabled New user creation authentication method:Password Observed behavior: The Platform SSO extension is discovered and loaded. Device registration starts and completes successfully. My extension’s device registration completion path is reached. registrationDidCompleteis called. The device configuration appears to be updated. After that, I expect Platform SSO to call the user registration flow, but my extension’sbeginUserRegistration(...)is never invoked. The strange part is that this only seems blocked at the user-registration handoff. Device registration during Setup Assistant works reliably.
Replies
2
Boosts
0
Views
618
Activity
May ’26
App Review Guidelines 2.5.1 / 2.5.2 — official guidance on screen capture protection for sensitive content
Hi all, We are developing an iOS app that includes private user-to-user chats, commercial offer details with monetary value, and customer identification data. In line with OWASP MASVS-PLATFORM-3 requirements regarding unintentional sensitive data exposure, we need to protect these specific screens from screenshots and screen recording. We have carefully reviewed the relevant App Review Guidelines (2.5.1 on public APIs, 2.5.2 on self-contained bundles, 5.1.1 on privacy) and the related Human Interface Guidelines. From this analysis we have observed the following: iOS does not expose a public API to globally disable screen capture (no direct equivalent of Android's FLAG_SECURE). The SwiftUI .privacySensitive() modifier is effective for Lock Screen widgets and Always-On Display, but it does not appear to prevent screenshots or screen recording of an app's main UI while in the foreground. A number of widely distributed App Store apps (banking, authenticator, secure messaging) implement some form of screenshot protection on sensitive screens. Several established open-source libraries leverage the system behavior of UITextField with isSecureTextEntry as a wrapping container for arbitrary views, in order to achieve pixel-level protection for sensitive content. We would appreciate clarification on the following points: For privacy-driven protection of sensitive screens (private chats, customer data, monetized offers), is there an officially recommended approach we may have missed? Are there public APIs intended specifically for this use case beyond .privacySensitive()? Is the practice of leveraging UITextField with isSecureTextEntry as a wrapping container for arbitrary views considered an acceptable use of public APIs under Guideline 2.5.1, or does it carry App Review risk? Are there official recommendations or documentation for apps handling sensitive personal data that wish to align with industry standards such as OWASP MASVS-PLATFORM-3 for screenshot and screen recording leakage prevention? The intended use is strictly limited to a small number of screens marked as containing sensitive data (private messages, deal details, customer information). The protection would be selective and clearly communicated to the user via in-app messaging, not global to the app. Thanks in advance for any clarification, including pointers to existing documentation or threads we may have missed. Deployment target: iOS 15+
Replies
5
Boosts
0
Views
1.2k
Activity
May ’26
Platform SSO registration dialogs remain after later success
We’re investigating a Platform SSO registration issue on macOS and wanted to check whether others have seen similar behavior or know whether this is expected system behavior. Scenario: Our extension implements ASAuthorizationProviderExtensionRegistrationHandler for device and user registration. On failure we complete with ASAuthorizationProviderExtensionRegistrationResult.failed, and on success we complete with .success. What we’re seeing: If registration fails multiple times, macOS shows multiple system dialogs saying: Registration failed and will automatically retry in a few minutes. If we do not close those earlier failure dialogs and then start another registration that succeeds, the old failure dialogs remain visible and do not dismiss automatically. They have to be closed manually one by one. From our side, these appear to be system-owned Platform SSO dialogs, not app-owned windows. We only return the registration result via the handler completion. Any guidance on whether macOS is expected to reconcile/dismiss earlier failure dialogs after a later success would also be helpful.
Replies
5
Boosts
0
Views
1.3k
Activity
May ’26
SFAuthorizationPluginView
I’ve developed an authorization plug-in with a mechanism that runs an SFAuthorizationPluginView subclass and I’m facing a couple issues: - Glitch after successful login After setting kAuthorizationResultAllow in the context the user is successfully logged in and brought to the desktop but the login controls remain onscreen for a few seconds after login is complete, resulting in them being visible at the same time as the dock, menu bar and desktop.
 I’ve also tried what’s mentioned here https://developer.apple.com/forums/thread/780212 but without any luck. It’s also worth mentioning that the deinit() in my SFAuthorizationPluginView subclass never gets called when the plugin it’s loaded at the login stage but it does get called the plugin is used to re-authenticate the user after they locked their screen. - update() doesn't trigger the plugin to call view(for:) I’m trying to update the UI elements out of my control (like buttons and user avatar images) in order to have them placed at the proper position on the screen after a resize of my inner NSView. To do that I call update() but it appears that does not trigger the plugin to call view(for:) and update system UI elements placement. Is this the expected behavior? - setButton not working as expected 
I’m trying to disable the login button by calling the setButton(_:enabled:) passing a SFButtonTypeLogin as inButtonType, as suggested here: https://developer.apple.com/forums/thread/777432. When the method is called at the login screen it has no effect on the button (the one with the forward-arrow icon) but when it’s called by the plugin loaded at the ‘unlock screen’ stage it successfully disable the ‘OK’ button. - Certificate issue When trying to run a network request from the plugin loaded in the ‘unlock screen’ scenario, I always get this type of error: The certificate for this server is invalid. You might be connecting to a server that is pretending to be <<server_url>> which could put your confidential information at risk Everything works as expected when the plugin is loaded either at login screen or for authorizing an operation that requires admin privileges while the user is logged in.
Replies
4
Boosts
0
Views
1k
Activity
May ’26
LAContext and its usage in context of Local Authentication
While working with Local Authentication framework, specifically LAContext class I found myself with few contradictions to documentation, and although I believe that those differences are rather positive than negative, either documentation is lacking behind or those APIs are not working as intended - which I believe is combination of both. 1. Local Authentication 1.1 Biometry type, and associated with it hash With introduction of LADomainState one can extract underlying biometry type along it's (current) state hash this way: @available(iOS 18, macOS 15, *) func postIOS18() { let context = LAContext() let biometryType = context.domainState.biometry.biometryType // (1) let biometryStateHash = context.domainState.biometry.stateHash // (2) } prior to receiving above APIs, we would retrieve such information something along those lines: func preIOS18() { let context = LAContext() let policy: LAPolicy // ... var error: NSError? _ = context.canEvaluatePolicy(policy, error: error) // (3) // ... (Handle error - if present) let biometryType = context.biometryType // (4) let biometryStateHash = context.evaluatedPolicyDomainState // (5) } However, moving let biometryType = context.biometryType (4) before call to canEvaluatePolicy (3) still yields correct biometry type. This is in contradiction to article from Local Authentication documentation page Optionally, Adjust Your User Interface to Accommodate Face ID. Furthermore, biometryType documentation does not mentions such requirement. Another difference is that call to canEvaluatePolicy (3) might return an error, eg. LAError(.biometryLockout) (if implemented correctly) preventing as from returning biometryStateHash (5) with nil value. This is not the case for new API, where the same call (2) will yield nil as a result - LADomainStateBiometry documentation does not mention it. In summary, here are some questions: Which API should be used to retrieve biometry type?, and why the "older way" has not been deprecated? Is is safe to assume that calls to biometryType and stateHash from LADomainStateBiometry will produce meaningful results without prior call to canEvaluatePolicy? Should I assume that call to biometryType found on LAContext instance will always return biometryType without prior call to canEvaluatePolicy?, or perhaps those are only side effects of changes made to accommodate LADomainState, and prior to them (pre-iOS 18) we must call canEvaluatePolicy to get meaningful value. Are the stateHash properties found on LADomainState, LADomainStateBiometry and LADomainStateCompanion will return nil upon encountering any error under the hood? (which would be equivalent of below code, prior to iOS 18) func biometryStateHash() -> Data? { let context = LAContext() if #available(iOS 18, macOS 15, *) { _ = context.canEvaluatePolicy(policy, error: nil) return context.evaluatedPolicyDomainState } else { return context.domainState.biometry.stateHash } } 1.2 Deprecation of evaluatedDomainState There is a forum post LAContext.evaluatedPolicyDomainState change between major OS versions mentioning missing documentation (fixed), however there's still information missing of how they correlate to each other. From my findings, the deprecated evaluatedDomainState property value matches those of LADomainState stateHash (when no companion device is present), and LADomainStateBiometry stateHash (all the time). Are those assumptions correct? 1.3 LAContext (authenticated) session lifespan Theres is little information about it state when authenticated by the user. Documentation on LAContext does not mention this behavior, while there are hints that once authenticated, and context is reused, any farther calls will not prompt user with UI. The problem is that this behavior is little, to no documented. Here are few examples I have found: Logging a User into Your App with Face ID or Touch ID (code sample) contains comment // Get a fresh context for each login. If you use the same context on multiple attempts //  (by commenting out the next line), then a previously successful authentication //  causes the next policy evaluation to succeed without testing biometry again. //  That's usually not what you want. Recent forum post, where such approach is mentioned by Quinn 'The Eskimo!' "At the API level, one option you have is to create an LAContext and pass it in to each SecItemCopyMatching call via kSecUseAuthenticationContext." WWDC22 Streamline local authorization flows session "By binding the LAContext to our private key reference, we ensure that executing the signature operation will not trigger another authentication, while allowing the operation to continue without unnecessary prompts. These binding also means that no additional user interactions will be required for future signatures until the LAContext is invalidated." Furthermore this is complicated by the touchIDAuthenticationAllowableReuseDuration property from LAContext instance which states that "The default value is 0, meaning that no previous biometric unlock can be reused." which is in direct contradiction to what I have experienced while working with LAContext and sources mentioned above. While digging on this, whether this behavior is intended or not, I came across a post (I would love to share it, but the domain is not permitted) that shared the same findings (and concerns) regarding LAContext behavior as me. The author also provided a FB9984036 feedback number - although no further update was made on that topic. So my questions are: Is it safe to reuse LAContext (authenticated) instance? How long such instance is considered authenticated?, is it a time duration or perhaps it stays in authenticated state until explicitly invalidated using invalidate method. (its invalidated for sure when app is terminated, but this was to be expected :)) How does,touchIDAuthenticationAllowableReuseDuration work, and how does it correlate to "reusability" of the authenticated LAContext instance? In what scenarios, touchIDAuthenticationAllowableReuseDuration should be used and what is its expected behavior? (I have tried it both on iOS and macOS; from my perspective API this does not "work")
Replies
2
Boosts
0
Views
477
Activity
May ’26
How much practical benefit is there to XPC-based privilege separation?
"Privilege separation" is one of the "two main reasons to use XPC services" given by https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPSystemStartup/Chapters/CreatingXPCServices.html — With traditional applications, if an application becomes compromised through a buffer overflow or other security vulnerability, the attacker gains the ability to do anything that the user can do. To mitigate this risk, Mac OS X provides sandboxing—limiting what types of operations a process can perform. […] Each XPC service has its own sandbox, so XPC services can make it easier to implement proper privilege separation. The idea (iiuc) being that if the main process is compromised, the spicier operations have been separated out to a separate process space, and this improves the security of the system. But if the main process is compromised, and that main process is trusted by the more-privileged XPC service, is not the system still compromised in practice? That is rather than the exploit being: exploit some vulnerability gain arbitrary code execution do something naughty isn't the same still possible with just one extra step: exploit vulnerability arbitrary execution ask the XPC service nicely… …to do something naughty?
Replies
3
Boosts
0
Views
311
Activity
May ’26
LAContext and its usage in context of Local Authentication
While working with Local Authentication framework, specifically LAContext class I found myself with few contradictions to documentation, and although I believe that those differences are rather positive than negative, either documentation is lacking behind or those APIs are not working as intended - which I believe is combination of both. 1. Local Authentication 1.1 Biometry type, and associated with it hash With introduction of LADomainState one can extract underlying biometry type along it's (current) state hash this way: @available(iOS 18, macOS 15, *) func postIOS18() { let context = LAContext() let biometryType = context.domainState.biometry.biometryType // (1) let biometryStateHash = context.domainState.biometry.stateHash // (2) } prior to receiving above APIs, we would retrieve such information something along those lines: func preIOS18() { let context = LAContext() let policy: LAPolicy // ... var error: NSError? _ = context.canEvaluatePolicy(policy, error: error) // (3) // ... (Handle error - if present) let biometryType = context.biometryType // (4) let biometryStateHash = context.evaluatedPolicyDomainState // (5) } However, moving let biometryType = context.biometryType (4) before call to canEvaluatePolicy (3) still yields correct biometry type. This is in contradiction to article from Local Authentication documentation page Optionally, Adjust Your User Interface to Accommodate Face ID. Furthermore, biometryType documentation does not mentions such requirement. Another difference is that call to canEvaluatePolicy (3) might return an error, eg. LAError(.biometryLockout) (if implemented correctly) preventing as from returning biometryStateHash (5) with nil value. This is not the case for new API, where the same call (2) will yield nil as a result - LADomainStateBiometry documentation does not mention it. In summary, here are some questions: Which API should be used to retrieve biometry type?, and why the "older way" has not been deprecated? Is is safe to assume that calls to biometryType and stateHash from LADomainStateBiometry will produce meaningful results without prior call to canEvaluatePolicy? Should I assume that call to biometryType found on LAContext instance will always return biometryType without prior call to canEvaluatePolicy?, or perhaps those are only side effects of changes made to accommodate LADomainState, and prior to them (pre-iOS 18) we must call canEvaluatePolicy to get meaningful value. Are the stateHash properties found on LADomainState, LADomainStateBiometry and LADomainStateCompanion will return nil upon encountering any error under the hood? (which would be equivalent of below code, prior to iOS 18) func biometryStateHash() -> Data? { let context = LAContext() if #available(iOS 18, macOS 15, *) { _ = context.canEvaluatePolicy(policy, error: nil) return context.evaluatedPolicyDomainState } else { return context.domainState.biometry.stateHash } } 1.2 Deprecation of evaluatedDomainState There is a forum post LAContext.evaluatedPolicyDomainState change between major OS versions mentioning missing documentation (fixed), however there's still information missing of how they correlate to each other. From my findings, the deprecated evaluatedDomainState property value matches those of LADomainState stateHash (when no companion device is present), and LADomainStateBiometry stateHash (all the time). Are those assumptions correct? 1.3 LAContext (authenticated) session lifespan Theres is little information about it state when authenticated by the user. Documentation on LAContext does not mention this behavior, while there are hints that once authenticated, and context is reused, any farther calls will not prompt user with UI. The problem is that this behavior is little, to no documented. Here are few examples I have found: Logging a User into Your App with Face ID or Touch ID (code sample) contains comment // Get a fresh context for each login. If you use the same context on multiple attempts //  (by commenting out the next line), then a previously successful authentication //  causes the next policy evaluation to succeed without testing biometry again. //  That's usually not what you want. Recent forum post, where such approach is mentioned by Quinn 'The Eskimo!' "At the API level, one option you have is to create an LAContext and pass it in to each SecItemCopyMatching call via kSecUseAuthenticationContext." WWDC22 Streamline local authorization flows session "By binding the LAContext to our private key reference, we ensure that executing the signature operation will not trigger another authentication, while allowing the operation to continue without unnecessary prompts. These binding also means that no additional user interactions will be required for future signatures until the LAContext is invalidated." Furthermore this is complicated by the touchIDAuthenticationAllowableReuseDuration property from LAContext instance which states that "The default value is 0, meaning that no previous biometric unlock can be reused." which is in direct contradiction to what I have experienced while working with LAContext and sources mentioned above. While digging on this, whether this behavior is intended or not, I came across a post (I would love to share it, but the domain is not permitted) that shared the same findings (and concerns) regarding LAContext behavior as me. The author also provided a FB9984036 feedback number - although no further update was made on that topic. So my questions are: Is it safe to reuse LAContext (authenticated) instance? How long such instance is considered authenticated?, is it a time duration or perhaps it stays in authenticated state until explicitly invalidated using invalidate method. (its invalidated for sure when app is terminated, but this was to be expected :)) How does touchIDAuthenticationAllowableReuseDuration work, and how does it correlate to "reusability" of the authenticated LAContext instance? In what scenarios touchIDAuthenticationAllowableReuseDuration should be used and what is its expected behavior? (I have tried it both on iOS and macOS; from my perspective API this does not "work")
Replies
1
Boosts
0
Views
438
Activity
May ’26
Protecting sensitive data in memory.
I am developing a library called MemoryCryptor for macOS. Its purpose is to protect sensitive data of the calling process (including launchd daemons), e.g. user passwords and other secrets, from being written to disk or read directly by debuggers or malware. This is a mandatory security requirement from our internal Security Team. On Windows we rely on DPAPI, which stores a per‑process cryptographic key outside the calling process’s address space, ensuring that key material and ciphertext never coexist in the same memory space. I have evaluated the following macOS options, but each presents limitations for our threat model: Secure Enclave (CryptoKit.framework). Keys generated using the Secure Enclave are not bound to the creating app. The dataRepresentation of a PrivateKey resides in the caller’s memory, allowing another process that can read a memory dump on the same machine to decrypt the data. Keychain API. Keys are always loaded into the calling process’s address space before any cryptographic operation, exposing them to memory‑dump attacks. Separate helper via XPC. While this could isolate key material, it requires full control of IPC implementation - plaintext may remain in the implementation's internal buffers. Given these constraints, are there any macOS‑native mechanisms or recommended architectures that allow us to keep cryptographic keys completely out of the calling process’s memory while still performing encryption/decryption on behalf of that process? Any guidance, best‑practice references, or alternative APIs would be greatly appreciated. Thank you for your assistance.
Replies
2
Boosts
0
Views
315
Activity
May ’26
Keychain Group
Dear Apple Developer Support Team, I would like to inquire whether there is a stable and official method to obtain the correct Team ID. When my app attempts to store data in the Keychain on a physical device, the retrieved Team ID is an unknown one and does not match the Team ID of my developer certificate. This issue consistently results in Keychain access failure with error code -34018. Could you please advise the root cause and provide a reliable solution to fix this Team ID mismatch and resolve the -34018 Keychain error? NSDictionary *query = [NSDictionary dictionaryWithObjectsAndKeys: kSecClassGenericPassword, kSecClass, @"bundleSeedID", kSecAttrAccount, @"", kSecAttrService, (id)kCFBooleanTrue, kSecReturnAttributes, nil]; CFDictionaryRef result = nil; OSStatus status = SecItemCopyMatching((CFDictionaryRef)query, (CFTypeRef *)&result); if (status == errSecItemNotFound) status = SecItemAdd((CFDictionaryRef)query, (CFTypeRef *)&result); if (status != errSecSuccess) return nil; NSString *accessGroup = [(__bridge NSDictionary *)result objectForKey:kSecAttrAccessGroup]; NSArray *components = [accessGroup componentsSeparatedByString:@"."]; NSString *bundleSeedID = [[components objectEnumerator] nextObject]; CFRelease(result); return bundleSeedID;
Replies
5
Boosts
0
Views
967
Activity
May ’26