Hi,
In our app we are using DeviceCheck (App Attest) in a production environment iOS. The service works correctly for most users, but a user reported failure in a flow that use device check service. This failure is not intermittently, it is constant.
We are unable to reproduce this failure and we are believing that this failure occurred by new version ios 26.3 because for others users using early versions the service is normally.
Environment
iOS 26.3
Real device
App Attest capability enabled
Correct App ID, Team ID and App Attest entitlement
Production environment
Characteristics:
appears constantly
affects only unique user
-Don't resolves after time or reinstall
not reproducible on our test devices
NSError contains no additional diagnostic info (Error Domain=com.apple.devicecheck.error Code=3 "(null)")
We saw about this error code 3 in this post 812308, but it's not our case because the ios version in this case is not iOS 17.0 or earlier.
Please, help us any guidance for solution. Thank you
General
RSS for tagPrioritize user privacy and data security in your app. Discuss best practices for data handling, user consent, and security measures to protect user information.
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
I'm trying to export and re-import a P-256 private key that was originally generated via SecKeyCreateRandomKey(), but I keep running into roadblocks. The key is simply exported via SecItemExport() with format formatWrappedPKCS8, and I did set a password just to be sure.
Do note that I must use the file-based keychain, as the data protection keychain requires a restricted entitlement and I'm not going to pay a yearly fee just to securely store some private keys for a personal project. The 7-day limit for unsigned/self-signed binaries isn't feasible either.
Here's pretty much everything I could think of trying:
Simply using SecItemImport() does import the key, but I cannot set kSecAttrLabel and more importantly: kSecAttrApplicationTag. There just isn't any way to pass these attributes upfront, so it's always imported as Imported Private Key with an empty comment. Keys don't support many attributes to begin with and I need something that's unique to my program but shared across all the relevant key entries, otherwise it's impossible to query for only my program's keys. kSecAttrLabel is already used for something else and is always unique, which really only leaves kSecAttrApplicationTag. I've already accepted that this can be changed via Keychain Access, as this attribute should end up as the entry's comment. At least, that's how it works with SecKeyCreateRandomKey() and SecItemCopyMatching(). I'm trying to get that same behaviour for imports.
Running SecItemUpdate() afterwards to set these 2 attributes doesn't work either, as now the kSecAttrApplicationTag is suddenly used for the entry's label instead of the comment. Even setting kSecAttrComment (just to be certain) doesn't change the comment. I think kSecAttrApplicationTag might be a creation-time attribute only, and since SecItemImport() already created a SecKey I will never be able to set this. It likely falls back to updating the label because it needs to target something that is still mutable?
Using SecItemImport() with a nil keychain (i.e. create a transient key), then persisting that with SecItemAdd() via kSecValueRef does allow me to set the 2 attributes, but now the ACL is lost. Or more precise: the ACL does seem to exist as any OS prompts do show the label I originally set for the ACL, but in Keychain Access it shows as Allow all applications to access this item. I'm looking to enable Confirm before allowing access and add my own program to the Always allow access by these applications list. Private keys outright being open to all programs is of course not acceptable, and I can indeed access them from other programs without any prompts.
Changing the ACL via SecKeychainItemSetAccess() after SecItemAdd() doesn't seem to do anything. It apparently succeeds but nothing changes. I also reopened Keychain Access to make sure it's not a UI "caching" issue.
Creating a transient key first, then getting the raw key via SecKeyCopyExternalRepresentation() and passing that to SecItemAdd() via kSecValueData results in The specified attribute does not exist. This error only disappears if I remove almost all of the attributes. I can pass only kSecValueData, kSecClass and kSecAttrApplicationTag, but then I get The specified item already exists in the keychain errors. I found a doc that explains what determines uniqueness, so here are the rest of the attributes I'm using for SecItemAdd():
kSecClass: not mentioned as part of the primary key but still required, otherwise you'll get One or more parameters passed to a function were not valid.
kSecAttrLabel: needed for my use case and not part of the primary key either, but as I said this results in The specified attribute does not exist.
kSecAttrApplicationLabel: The specified attribute does not exist. As I understand it this should be the SHA1 hash of the public key, passed as Data. Just omitting it would certainly be an option if the other attributes actually worked, but right now I'm passing it to try and construct a truly unique primary key.
kSecAttrApplicationTag: The specified item already exists in the keychain.
kSecAttrKeySizeInBits: The specified attribute does not exist.
kSecAttrEffectiveKeySize: The specified attribute does not exist.
kSecAttrKeyClass: The specified attribute does not exist.
kSecAttrKeyType: The specified attribute does not exist.
It looks like only kSecAttrApplicationTag is accepted, but still ignored for the primary key. Even entering something that is guaranteed to be unique still results in The specified item already exists in the keychain, so I think might actually be targeting literally any key. I decided to create a completely new keychain and import it there (which does succeed), but the key is completely broken. There's no Kind and Usage at the top of Keychain Access and the table view just below it shows symmetric key instead of private. The kSecAttrApplicationTag I'm passing is still being used as the label instead of the comment and there's no ACL. I can't even delete this key because Keychain Access complains that A missing value was detected. It seems like the key doesn't really contain anything unique for its primary key, so it will always match any existing key.
Using SecKeyCreateWithData() and then using that key as the kSecValueRef for SecItemAdd() results in A required entitlement isn't present. I also have to add kSecUseDataProtectionKeychain: false to SecItemAdd() (even though that should already be the default) but then I get The specified item is no longer valid. It may have been deleted from the keychain. This occurs even if I decrypt the PKCS8 manually instead of via SecItemImport(), so it's at least not like it's detecting the transient key somehow. No combination of kSecAttrIsPermanent, kSecUseDataProtectionKeychain and kSecUseKeychain on either SecKeyCreateWithData() or SecItemAdd() changes anything.
I also tried PKCS12 despite that it always expects an "identity" (key + cert), while I only have (and need) a private key. Exporting as formatPKCS12 and importing it with itemTypeAggregate (or itemTypeUnknown) does import the key, and now it's only missing the kSecAttrApplicationTag as the original label is automatically included in the PKCS12. The outItems parameter contains an empty list though, which sort of makes sense because I'm not importing a full "identity". I can at least target the key by kSecAttrLabel for SecItemUpdate(), but any attempt to update the comment once again changes the label so it's not really any better than before.
SecPKCS12Import() doesn't even import anything at all, even though it does return errSecSuccess while also passing kSecImportExportKeychain explicitly.
Is there literally no way?
I have a binary executable which needs to be given Accessibility Permissions so it can inject keypresses and mouse moves. This was always possible up to macOS 15 - when the first keypress arrived the Accessibility Permissions window would open and allow me to add the executable. However this no longer works in macOS 26: the window still opens, I navigate to the executable file and select it but it doesn't appear in the list. No error message appears.
I'm guessing that this may be due to some tightening of security in Tahoe but I need to figure out what to change with my executable to allow it to work.
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.
We're experiencing crashes in our production iOS app related to Apple's DeviceCheck framework. The crash occurs in DCAnalytics internal performance tracking, affecting some specific versions of iOS 18 (18.4.1, 18.5.0).
Crash Signature
CoreFoundation: -[__NSDictionaryM setObject:forKeyedSubscript:] + 460
DeviceCheck: -[DCAnalytics sendPerformanceForCategory:eventType:] + 236
Observed Patterns
Scenario 1 - Token Generation:
Crashed: com.appQueue
EXC_BAD_ACCESS KERN_INVALID_ADDRESS 0x0000000000000010
DeviceCheck: -[DCDevice generateTokenWithCompletionHandler:]
Thread: Background dispatch queue
Scenario 2 - Support Check:
Crashed: com.apple.main-thread
EXC_BAD_ACCESS KERN_INVALID_ADDRESS 0x0000000000000008
DeviceCheck: -[DCDevice _isSupportedReturningError:]
DeviceCheck: -[DCDevice isSupported]
Thread: Main thread
Root Cause Analysis
The DCAnalytics component within DeviceCheck attempts to insert a nil value into an NSMutableDictionary when recording performance metrics, indicating missing nil validation before dictionary operations.
Reproduction Context
Crashes occur during standard DeviceCheck API usage:
Calling DCDevice.isSupported property
Calling DCDevice.generateToken(completionHandler:) (triggered by Firebase App Check SDK)
Both operations invoke internal analytics that fail with nil insertion attempts.
Concurrency Considerations
We've implemented sequential access guards around DeviceCheck token generation to prevent race conditions, yet crashes persist. This suggests the issue likely originates within the DeviceCheck framework's internal implementation rather than concurrent access from our application code.
Note: Scenario 2 occurs through Firebase SDK's App Check integration, which internally uses DeviceCheck for attestation.
Request
Can Apple engineering confirm if this is a known issue with DeviceCheck's analytics subsystem? Is there a recommended workaround to disable DCAnalytics or ensure thread-safe DeviceCheck API usage?
Any guidance on preventing these crashes would be appreciated.
Since around March 4, 2025 off and on, we've been receiving 500 errors back from the validate_device_token endpoint on development and production. Today (March 6) we are constantly getting 500 error back.
https://api.development.devicecheck.apple.com/v1/validate_device_token
This was working previously before then. No change has happened on our end since then.
This is a critical piece for our infrastructure.
Thanks in advance.
-Matt
It seems it is not possible to give a CLI app (non .app bundle) full disk access in macOS 26.1. This seems like a bug and if not that is a breaking change. Anybody seeing the same problem?
Our application needs full disk access for a service running as a LaunchDaemon. The binary is located in a /Library subfolder.
iOS18.1.1 macOS15.1.1 xcode16.1 Error Domain=com.apple.AuthenticationServices.AuthorizationError Code=1004 "Unable to verify webcredentials association of ********** with domain ******************. Please try again in a few seconds."
Our domain must query with VPN, so I set webcredentials:qa.ejeokvv.com?mode=developer
following:
"If you use a private web server, which is unreachable from the public internet, while developing your app, enable the alternate mode feature to bypass the CDN and connect directly to your server. To do this, add a query string to your associated domains entitlement, as shown in the following example:
:?mode=
"
but it still not working, even after I set mode=developer.
Please help!!!!
Topic:
Privacy & Security
SubTopic:
General
Tags:
Passkeys in iCloud Keychain
Authentication Services
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!
I have been able to save and remove ASPasskeyCredentialIdentities in the ASCredentialIdentityStore. But after saving a ASPasskeyCredentialIdentity, when I retrieve the current identities stored, it always returns an empty list. I check to make sure the store is enabled. I am using this method which is available starting with iOS 17.4:
extension ASCredentialIdentityStore {
public func credentialIdentities(forService serviceIdentifier: ASCredentialServiceIdentifier? = nil, credentialIdentityTypes: ASCredentialIdentityStore.IdentityTypes = []) async -> [any ASCredentialIdentity]
}
I have called it like this:
store.credentialIdentities(forService: nil, credentialIdentityTypes: .passkey)
And this:
store.credentialIdentities()
Has anyone got this to work?
My app has been rejected by App Store review because the sign in with Apple functionality is not working properly. I'm able to reproduce the issue on my end but I don't understand why it's happening.
I have two other apps that implement the same OAuth flow in an identical manner, and those apps have no issues signing in with Apple.
I've copied my OAuth flow to a fresh project to see if that would make a difference, and it gives me the exact same error. In the simulator I get "invalid_request, invalid web redirect URL", and on-device the FaceID authentication fails with a very non-specific "Sign Up Not Completed" error.
I'm completely out of ideas here, so any guidance would be appreciated. Thanks!
How can my password manager app redirect users to the “AutoFill Passwords & Passkeys” settings page?
Hi all,
I’m building a password manager app for iOS. The app implements an ASCredentialProviderExtension and has the entitlement com.apple.developer.authentication-services.autofill-credential-provider.
From a UX perspective, I’d like to help users enable my app under:
Settings → General → AutoFill & Passwords
What I’ve observed:
Calling UIApplication.openSettingsURLString only opens my app’s own Settings page, not the AutoFill list.
Some apps (e.g. Google Authenticator) appear to redirect users directly into the AutoFill Passwords & Passkeys screen when you tap “Enable AutoFill.”
1Password goes even further: when you tap “Enable” in 1Password App, it shows a system pop-up, prompts for Face ID, and then enables 1Password as the AutoFill provider without the user ever leaving the app.
Questions:
Is there a public API or entitlement that allows apps to deep-link users directly to the AutoFill Passwords & Passkeys screen?
Is there a supported API to programmatically request that my app be enabled as an AutoFill provider (similar to what 1Password seems to achieve)?
If not, what is the recommended approach for guiding users through this flow?
Thanks in advance!
Topic:
Privacy & Security
SubTopic:
General
Tags:
Wallet
Authentication Services
Passkeys in iCloud Keychain
Managed Settings
I'm a bit confused about if using App Attest is possible in enterprise builds. It shows up under identifiers in the apple dev portal and I can add it to my provisioning file and entitlements file. But if I go to keys I cannot create a key for it.
This page implies it can be used for enterprise builds:
After distributing your app through TestFlight, the App Store, or the Apple Developer Enterprise Program, your app ignores the entitlement you set and uses the production environment.
We have a crash on DCDevice.current.isSupported
We want to try to make a serial queue to generate tokens but the side effect would be the same token would be used on multiple server API requests that are made within a few ms of each other?
Is this safe or will the Apple server immediately reject the same token being reused?
Can you share how long tokens are safe to use for?
Here is the code we want to try
final actor DeviceTokenController: NSObject {
static var shared: DeviceTokenController = .init()
private var tokenGenerationTask: Task<Data?, Never>?
var ephemeralDeviceToken: Data? {
get async {
// Re-using the token for short periods of time
if let existingTask = tokenGenerationTask {
return await existingTask.value
}
let task = Task<Data?, Never> {
guard DCDevice.current.isSupported else { return nil }
do {
return try await DCDevice.current.generateToken()
} catch {
Log("Failed to generate ephemeral device token", error)
return nil
}
}
tokenGenerationTask = task
let result = await task.value
tokenGenerationTask = nil
return result
}
}
}
Hi,
My MACOS app has sensitive content and dont want user to take screenshot or to record the screen.
I tries window.sharingType=none. With this user can still record the screen.
I know that user can record with external device. But we dont want him to record using screen capture.
Can you please tell me how to detect when screen recording is active in MACOs apps? or how to prevent screen recording in MACOs apps.
Thanks
I’m having an issue with my Credential Provider Extension for passkey registration. On the browser I click on registration, in IOS i can select my App for passkey registration with a continue button. Wenn I click the continue button the prepareInterface(forPasskeyRegistration:) function is called but the MainInterface is not shown —it only appears when I click the continue button a second time.
Here’s a simplified version of my prepareInterface method:
override func prepareInterface(forPasskeyRegistration registrationRequest: ASCredentialRequest) {
guard let request = registrationRequest as? ASPasskeyCredentialRequest,
let identity = request.credentialIdentity as? ASPasskeyCredentialIdentity else {
extensionContext.cancelRequest(withError: ASExtensionError(.failed))
return
}
self.identity = identity
self.request = request
log.info("prepareInterface called successfully")
}
In viewDidAppear, I trigger FaceID authentication and complete the registration process if register is true. However, the UI only shows after a second “Continue” tap.
Has anyone encountered this behavior or have suggestions on how to ensure the UI appears immediately after prepareInterface is called? Could it be a timing or lifecycle issue with the extension context?
Thanks for any insights!
On iOS 26, QuickLookAR (ARQuickLookPreviewItem) shares the actual .usdz file via the system Share Sheet instead of the original website URL.
This is a regression from iOS 17–18, where sharing correctly preserved and sent only the source URL.
Repro steps:
1. Open a web-hosted USDZ model in QuickLookAR (Safari).
2. Tap Share.
3. Share via any messenger.
4. The full .usdz file is sent.
Expected:
Share Sheet sends only the original URL.
Actual:
Share Sheet sends the USDZ file.
Impact:
Uncontrolled distribution of proprietary 3D assets.
Critical IP / data leak.
Blocks production AR deployments relying on QuickLook.
Environment:
iOS 26.0–26.1, iPhone 14 / 15.
Works as expected on iOS 17–18.
Test case:
https://admixreality.com/ios26/
Topic:
Privacy & Security
SubTopic:
General
Hi everyone,
I'm currently working on a native macOS app (built with SwiftUI) and I'm trying to implement Password AutoFill functionality so users can use their saved credentials from Keychain or third-party password managers.
I've gone through Apple's documentation, WWDC sessions, and sample code, but I've noticed that the resources primarily focus on iOS and web implementations. There's very limited guidance specifically for macOS.
I've set up:
Associated Domains entitlement with the webcredentials: service
The apple-app-site-association file on my server
TextField with .textContentType(.username) and SecureField with .textContentType(.password)
However, I'm still not seeing the expected AutoFill behavior on macOS like I would on iOS.
Has anyone successfully implemented Password AutoFill on a native macOS app? Are there any macOS-specific considerations or additional steps required that differ from iOS?
Any guidance, sample code, or pointers to documentation I might have missed would be greatly appreciated.
Why can’t sandboxed mac app store apps have full disk access available in the system settings for full disk access?
I discovered mac app store apps in release mode cannot access the ai auggie command line program and other command line programs like opengrep on your system. Debug builds fine.
I came up with a workaround: Since I have an ssh client built in for connecting to remote servers, why not connect to ssh on the same local machine… Ask the user for their username and password in a popup.
To do this, you have to enable remote login on your mac in system settings -> sharing.
In addition you must grant full disk access to cli ssh in system settings: add /usr/libexec/sshd-keygen-wrapper
It all works, but I don’t see the cli program in mac settings. To remove the cli program you must run a command line program to remove all full disk access support from all apps. No way to just undo ssh.
So my question is, even though I got CodeFrog all working for a mac app store release, should I not do it because it’s insecure or too complicated with the system settings? Should I instead sell the app off the store like Panic Nova?
Need some advice. I have not implemented in app purchases yet. Should I just have a reality check and sell the app off the store, or try for app store approval?
Bummer…
Maybe I’m ahead of my time, but perhaps Apple could review the source code for apps requesting full disk access and make sure there’s nothing fraudulent in them. Then, developer tools app store apps could be in the store with the user’s assurance that nothing is happening behind the scenes that is scary.
From: https://blog.greenrobot.com/2025/11/10/i-have-a-decision-to-make/
Related post:
https://developer.apple.com/forums/thread/806187
I submitted a code level tech support question for this. They directed me here.
Dear Apple Developer Support,
We are currently encountering a recurring issue with the DeviceCheck API across multiple devices in our production environment.
The following error is frequently returned:
com.apple.devicecheck.error 0 We would like to ask the following:
What are the possible underlying causes that could lead to this specific error code (0) in the DeviceCheck API?
Is there any known behavior or condition where Wi-Fi network configurations (e.g., DNS filtering, proxy settings, captive portals) could result in this error?
Are there known timeouts, connectivity expectations, or TLS-level requirements that the DeviceCheck API enforces which could fail silently under certain network conditions?
Is this error ever triggered locally (e.g., client library-level issues) or is it always from a failed communication with Apple’s servers?
Any technical clarification, documentation, or internal insight into this error code would be greatly appreciated. This would help us significantly narrow down root causes and better support our users