General:
Forums topic: Privacy & Security
Apple Platform Security support document
Developer > Security
Enabling enhanced security for your app documentation article
Creating enhanced security helper extensions documentation article
Security Audit Thoughts forums post
Cryptography:
Forums tags: Security, Apple CryptoKit
Security framework documentation
Apple CryptoKit framework documentation
Common Crypto man pages — For the full list of pages, run:
% man -k 3cc
For more information about man pages, see Reading UNIX Manual Pages.
On Cryptographic Key Formats forums post
SecItem attributes for keys forums post
CryptoCompatibility sample code
Keychain:
Forums tags: Security
Security > Keychain Items documentation
TN3137 On Mac keychain APIs and implementations
SecItem Fundamentals forums post
SecItem Pitfalls and Best Practices forums post
Investigating hard-to-reproduce keychain problems forums post
App ID Prefix Change and Keychain Access forums post
Smart cards and other secure tokens:
Forums tag: CryptoTokenKit
CryptoTokenKit framework documentation
Mac-specific resources:
Forums tags: Security Foundation, Security Interface
Security Foundation framework documentation
Security Interface framework documentation
BSD Privilege Escalation on macOS
Related:
Networking Resources — This covers high-level network security, including HTTPS and TLS.
Network Extension Resources — This covers low-level network security, including VPN and content filters.
Code Signing Resources
Notarisation Resources
Trusted Execution Resources — This includes Gatekeeper.
App Sandbox Resources
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
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
General:
Forums topic: Privacy & Security
Privacy Resources
Security Resources
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
Topic:
Privacy & Security
SubTopic:
General
Hi! I am trying to run the demo app(SampleEndpointApp) from the WWDC2020 presentation(link).
Here are the steps I followed in order to run the app:
I submitted a request for the Endpoint Security entitlement and got the approval from the Apple Support team.
Created an identifier and assigned Endpoint Security capability.
Updated the Bundle Identifier in ViewController.m and in the Extension target.
Built and copied the app bundle to /Application folder.
Ran the app, clicked "Install Extension" and got the confirmation message that everything went well.
Looking into the logs, I see the following :
(libEndpointSecurity.dylib) Failed to open service: 0xe00002d8: Caller lacks TCC authorization for Full Disk Access
I keep getting the same message even after granting SampleEndpointApp Full Disk Access in Privacy & Security.
System : macOS Sequoia 15.1.1
Could you please assist me with this issue?
Andrei
I'd like to implement unit tests that exercise keys made available via a persistent token interface. However, when attempting to list available tokens by passing kSecAttrAccessGroupToken as the kSecAttrAccessGroup to SecItemCopyMatching from a unit test, -34018 is returned. It succeeds without the kSecAttrAccessGroup, which makes sense given the unit test binary does not have com.apple.token Keychain Group. The Xcode UI indicates "Capabilities are not supported" for the unit test binary when attempting to add a Keychain Sharing capability to enable use of persistent tokens. This feels like a dead end but begs the question is there any way to implement unit tests to exercise a persistent token interface? It seems like the only path may be write unit tests that drive an independent app that handles the interactions with the persistent token.
Hey there,
I’m currently exploring the possibility of integrating Sign in with Apple into my iOS app and backend.
Regarding the iOS app, I’ve read that when a user is signed in, you always need to call getCredentialState on the app’s launch. Is this true? If so, how is it possible to sign the user out then?
I intend to incorporate SwiftData and CloudKit into my application. In light of this, I’m curious about your approach to user management. Specifically, I’m wondering if you would store the user’s data in a Redis database after successful authentication on the backend. Or, would you separate the user data and save it using SwiftData/ CloudKit?
We have an app that has failed during the app review for the Japanese market but has been accepted in several other markets successfully.
We need the user's name in native Katakana format as we need it to be displayed in our restaurant Point of Sale systems for workers to be able to read and understand.
We use 'Sign up with Apple', but when doing so, if this returns an anglicised given and family name, we have to request the customer supply their Katakana format name so that our in-store systems and staff can process and fulfil their orders.
When the App Review process automatically tests the app, it uses "Apple John" as a customer's name. Since this is not a Japanese name, we ask for it again in the correct format, or we cannot allow the user to register.
This contravenes Apple's rules, and thus, our app is rejected. If the Apple identity used belonged to a user more typical of the target market, it would work as required.
Does anyone else have this issue, and how did you work around it?
Tim
Topic:
Privacy & Security
SubTopic:
General
Tags:
Internationalization
Sign in with Apple
App Submission
In a project I was using Local Authentication to authenticate a user. When I got a request to support smartcard/PIV token authentication (which Local Authentication does not support), I had to switch to Authorization Services, which works pretty. There's only one issue I have. Local Authentication's evaluatePolicy:localizedReason:reply: requires a reason in the form "<appname>" is trying to <localized reason>. The app is currently translated into 41 languages and I would like to use the localized strings for the AuthorizationEnvironment of Authorization Services as well. The problem is that Local Authentication prefixes the localized string with something like "<appname>" is trying to and Authorization Services does not do this. Is there a way to get this prefix from somewhere so I can manually add it to the (partially) localized string? Any help would be highly appreciated.
Thank you,
Marc
Hi,
When calling generateAssertion on DCAppAttestService.shared, it gives invalidKey error when there was an update for an offloaded app.
The offloading and reinstall always works fine if it is the same version on app store that was offloaded from device,
but if there is an update and the app tries to reuse the keyID from previous installation for generateAssertion, attestation service rejects the key with error code 3 (invalid key) for a significant portion of our user.
In our internal testing it failed for more than a third of the update attempts.
STEPS TO REPRODUCE:
install v1 from app store
generate key using DCAppAttestService.shared.generateKey
Attest this key using DCAppAttestService.shared.attestKey
Send the attestation objection to our server and verify with apple servers
Generate assertions for network calls to backend using DCAppAttestService.shared.generateAssertion with keyID from step 2
Device offloads the app (manually triggered by user, or automatically by iOS)
A new version v2 is published to App Store
Use tries to open the app
Latest version is download from the App Store
App tries to use the keyID from step 2 to generate assertions
DCAppAttestService throws invalidKey error (Error Domain=com.apple.devicecheck.error Code=3)
Step 7 is critical here, if there is no new version of the app, the reinstalled v1 can reuse the key from step 2 without any issues
Is this behaviour expected?
Is there any way we can make sure the key is preserved between offloaded app updates?
Thanks
I was basically saving items into the Keychain with the following query dictionary:
let query: [String: Any] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrAccount as String: key,
kSecValueData as String: value,
kSecAttrAccessible as String: kSecAttrAccessibleAfterFirstUnlock
]
Where key is a String value and value is a Data that used to be a String.
I was getting the following error:
code: -25299
description: The specified item already exists in the keychain
After a lot of digging in I saw that I needed to add kSecAttrService to the dictionary and after that it all started working. The service value is a String value.
let query: [String: Any] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrService as String: service,
kSecAttrAccount as String: key,
kSecValueData as String: value,
kSecAttrAccessible as String: kSecAttrAccessibleAfterFirstUnlock
]
These were the articles that suggested adding the kSecAttrService parameter:
https://stackoverflow.com/a/11672200
https://stackoverflow.com/a/58233542
But in the same code base I found that other developers were saving using a dictionary similar to the one I first provided and it works:
var query: [String : Any] = [
kSecClass as String : kSecClassGenericPassword as String,
kSecAttrAccount as String : key,
kSecValueData as String : data
]
I don't know how to explain why my first implementation didn't work even though it was similar to what was already in the code base but the second approach worked well.
Regardless of the query dictionary, this is how I'm saving things:
static func save(value: Data, key: String, service: String) -> KeyChainOperationStatus {
logInfo("Save Value - started, key: \(key), service: \(service)")
let query: [String: Any] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrService as String: service,
kSecAttrAccount as String: key,
kSecValueData as String: value,
kSecAttrAccessible as String: kSecAttrAccessibleAfterFirstUnlock
]
// Remove any existing key
let cleanUpStatus = SecItemDelete(query as CFDictionary)
let cleanUpStatusDescription = SecCopyErrorMessageString(cleanUpStatus, nil)?.asString ?? "__cleanup_status_unavailable"
logInfo("Save Value - cleanup status: \(cleanUpStatus), description: \(cleanUpStatusDescription)")
guard cleanUpStatus == errSecSuccess || cleanUpStatus == errSecItemNotFound else {
logError("Save Value - Failed cleaning up KeyChain")
return .cleanupFailed(code: cleanUpStatus)
}
// Add the new key
let saveStatus = SecItemAdd(query as CFDictionary, nil)
let saveStatusDescription = SecCopyErrorMessageString(saveStatus, nil)?.asString ?? "__save_status_unavailable"
logInfo("Save Value - save status [\(saveStatus)] : \(saveStatusDescription)")
guard saveStatus == errSecSuccess else {
logError("Save Value - Failed saving new value into KeyChain")
return .savingFailed(code: saveStatus)
}
return .successs
}
Topic:
Privacy & Security
SubTopic:
General
Hi,
I know it's been discussed before, but I'm testing the Sign in with Apple feature, and I only get the user info on the first try.
Now, I know that you're supposed to go to the account settings, and look for the list of accounts that you used your Apple account to sign in with, and it used to work a few months back. But for the last few weeks I haven't been able to get the user info, even after deleting the entry from my Sign In With Apple app list.
Has there been a recent change to Apple security policy that prevents such a move from working ? Or am I doing something wrong ?
Thank you
I have a macOS package (.pkg) that checks for installed Java versions on the machine during the preinstall phase using a preinstall script. If the required Java version is not found, the script displays a message using osascript as shown below.
/usr/bin/osascript -e 'tell application "Finder"' -e 'activate' -e 'display dialog "Java Development Kit (JDK) 11 is required" buttons{"OK"} with title "Myprod Warning"' -e 'end tell'
So far, no issues have been observed with the installation of my package on all versions of macOS. However, on macOS 15.2, the installation is failing with a "Not authorized to send Apple events to Finder" error.
Could someone please help me understand what might be causing this issue and how to resolve it?
Topic:
Privacy & Security
SubTopic:
General
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?
During SmartCard pairing the PIN prompt enables the OK button only on user provides a PIN of 6 digits. Is there a way to submit the empty PIN in this flow, where the custom CTK is used here (the custom CTK would take care of the PIN from the custom ctk code). I was able to do an empty PIN submit once the I've paired the user successfully at login, unlock and other cli tools. Is there a way to do the same during the pairing?
Once the user has successfully paired with the SmartCard authentication with PIN, I was able to see most of the authentication flows was prompting for the PIN authentication like login, unlock, CLI tools like ssh, su etc., perhaps at few apps where it is still prompted with the Password instead of PIN examples, when I tried to launch Keychain Access app or Add a user from users&groups system setting.
Is this expected behaviour?
Hi,
I hope someone is able to help me with this query:
Is there a mandatory requirement to display a view before presenting the App Tracking Transparency modal to explain to the user why the app is asking for tracking? I see there are a few apps which do this, but I don't see any mention of this as a mandatory requirement within the app store review guidelines. The modal can be customised with a description detailing why the app is asking for tracking and I believe this may be sufficient to pass an app store review.
The guidelines also mention that the app must provide access to information about how and where the data will be used. We have these details in our privacy policy which is accessible from within the app. Is this sufficient or do we need a pre-modal view which contains a direct link the the privacy policy.
Any advice on this would be much appreciated.
转让app成功了之后,由于开发者账号更改,团队ID改变,导致获取不到原有的keychain中缓存的用户数据,所以在用户进行登录时,无法登录到原有的老账号,而是被识别成了一个新的用户。这种情况怎么解决。
I have something with a new individual on my team I've never seen before. They checked out our code repository from git and now anytime they try to open a .json file that is legitimately just a text file, GateKeeper tells them it cannot verify the integrity of this file and offers to have them throw this file away. I've seen this with binaries, and that makes sense. I removed the com.apple.quarantine extended attribute from all executable files in our source tree, but I've never seen GateKeeper prompt on text files. I could remove the extended attribute from all files in our source tree, but I fear the next time he pulls from git he'll get new ones flagged. Is there someway around this? I've never personally seen GateKeeper blocking text files.
I must be missing something. How can an iphone that is in lockdown mode, using ONLY data, no Bluetooth connected and only one singular iPhone have seven UNLISTED items on the local network in privacy and settings?
Our application uses Screen capture KIT API for screen recording.
But from Sequoia OS, we are getting additional permission dialog which states " is requesting to bypass the system private window picker and directly access your screen and audio".
It seems we need to add our app under "System settings -> Privacy & Security -> Remote Desktop" setting to avoid getting above additional dialogue in every few days.
Some places mention use of .plist file that if mention in this file, the app will request for this permission. But did not seem to work or we do not understand that properly yet.
Hi,
We are trying to open an application "xyz.app"
It worked fine until 15.1.1 versions. But facing issues with 15.2 and 15.3
The application is working fine when we navigate to xyz.app/Contents/MacOS/ and run applet in this directory.
But the error ""Not authorized to send Apple events to Finder"" occurs when we are trying to open the app directly.
Could someone please help me understand what might be causing this issue and how to resolve it?
Topic:
Privacy & Security
SubTopic:
General
Current Setup:
Using Secure Enclave with userPresence access control
Foreground keychain accessibility: whenPasscodeSetThisDeviceOnly
Security Requirement:
Our security group wants us to invalidate biometrics and require a username/password if a biometric item is added (potentially by a hostile 3rd party)
Need to upgrade from userPresence to biometricCurrentSet to ensure re-authentication when biometric credentials change.
Issue:
After implementing biometricCurrentSet, authentication cancels after two failed biometric attempts instead of falling back to passcode.
Current Detection Method:
User completes initial biometric authentication
Biometric changes occur (undetectable by app)
App attempts Secure Enclave access
Access denial triggers re-authentication requirement
Cannot revoke refresh token after access is denied
Security Concern:
Current implementation allows new biometric enrollments to access existing authenticated sessions without re-verification.
Question:
What's the recommended approach to:
Implement biometricCurrentSet while maintaining passcode fallback
Properly handle refresh token invalidation when biometric credentials change
Looking for guidance on best practices for implementing these security requirements while maintaining good UX.
Hello,
I have an application which uses a helper[1] to download[2] files. When files download is a DMG and user mounts the image to run the application from this DMG it doesn't pass Gatekeeper. It presents the "Application XYZ.app can't be opened.".
Same file downloaded via Safari shows a different dialog, the "XYZ.app is an app downloaded from the internet. Are you sure you want to open it?"
In the system log I see this line:
exec of /Volumes/SampleApp/SampleApp.app/Contents/MacOS/SampleApp denied since it was quarantined by Download\x20Helper and created without user consent, qtn-flags was 0x00000187
The application is running sandboxed and hardened, the main application has com.apple.security.files.downloads.read-write entitlement. Everything is signed by DeveloperID and passes all checks[3].
I tried to check the responsible process[4] of the helper. Then trivial stuff like download folder access in System Settings/Privacy & Security/Files & Folders. Everything seems to be fine.
For what it worths the value of quarantine attribute is following:
com.apple.quarantine: 0087;6723b80e;My App;
The Safari downloaded one posses:
com.apple.quarantine: 0083;6723b9fa;Safari;02162070-2561-42BE-B30B-19A0E94FE7CA
Also tried a few more ways and got to 0081 with Edge and 0082 with a sample app with similar setup. Not sure if that has any meaning.
What could I be doing wrong that Gatekeeper right away refuses to run the application from DMG instead of showing the dialog like in other cases?
[1] The executable is in application bundle located in Contents/Helpers/DownloadHelper.app in the main application bundle.
[2] Nothing fancy, curl + regular POSIX file operations
[3] codesign, syspolicy_check, spctl
[4] launchctl procinfo pid
I am currently unable to enable passkey in my app so I am having to tell my users to skip the prompts for using passkey. We have noticed that after a few times of this the OS will stop asking the user to register their passkey. The question is, how long does this last before the OS asks you to use passkey again? Is it permanent until you re-install the app? Just looking for a time frame if anyone knows.
Topic:
Privacy & Security
SubTopic:
General
Tags:
Passkeys in iCloud Keychain
Authentication Services