General:
Forums topic: Privacy & Security
Apple Platform Security support document
Developer > Security
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 Team, I want to perform bluetooth advertising (no need to pair) from a macOS machine even before the user login to the macOS(i.e before user provide password and submit). Is there a way to achieve this?
Topic:
Privacy & Security
SubTopic:
General
Tags:
IOBluetooth
External Accessory
macOS
Core Bluetooth
Help: Recover Photos from iPhone XS Max (A2101) After Updating from iOS 14.6 to 18.7.1
Hi everyone,
I accidentally restored my iPhone XS Max (model A2101) while trying to update from iOS 14.6 to iOS 18.7.1 via iTunes on Windows, and now all my photos are gone. I didn’t have any backup and I’m looking for ways to recover my data.
I’ve tried some recovery software, but they all ask for the encrypted iTunes backup password, which I don’t have. I want to scan the device directly without relying on a backup.
Has anyone successfully recovered photos in a situation like this? Any tools, tips, or services that could help would be much appreciated.
Thank you!
This is not a question but rather a small bit of documentation on how Accessory Setup Kit actually works. I spent a couple days figuring this out so I thought let's share my findings. The example app is very light and the documentation definitely has room for improvement so here are a couple important notes.
Findings:
If you're running > iOS 18 and add any property to your Info.plist file you're no longer able to scan for devices by using CBCentralManager.scanForPeriphals. This will no longer return discoverable devices. Below iOS 18 these properties in the Info.plist are ignored by the OS and you can safely use the "legacy" method of connecting to bluetooth devices.
If you're running > iOS 26 the removeAccessory will show a prompt to the user. If you're running < 26 you can silently remove the accessory and start each session with a clean state.
If you create CBCentralManager before you start the ASK session you'll not get the state = PoweredOn.
If you have 0 accessories connected to your application CBCentralManager will never enter the state = PoweredOn when you create the CBCentralManager. Pre-ASK this would be the trigger for iOS to ask the user permission. This is no longer necessary with ASK.
If you have have 1 or more accessories authorized to your app this will be returned in the session.accessories after the session has started. This is an important indicator to determine app behavior.
If you have 1 or more accessories CBCentralManager.scanForPeripherals will ONLY return previously authorized AND discoverable devices. Use this for when you want to connect to a previously authorized device.
If you have 1 or more accessories and the CBCentralManager.scanForPeripherals returns nothing you can (safely) assume the user attempts to onboard a new device.
So for my application I take the following steps:
Check for iOS version, if > iOS 18 start ASK session.
Are there previously authorized devices?
-- yes: run CBCentralManger.scanForPeripherals
-- no: show the picker
Did the scan return any devices?
-- yes: show UI to select device or connect with first available device in the list
-- no: show the picker
Feel free to add any of your findings and @Apple please update the documentation!
Hi everyone,
I’m looking for clarification on best practices for storing API keys in an iOS app — for example, keys used with RevenueCat, PostHog, AWS Rekognition, barcode scanners, and similar third-party services.
I understand that hard-coding API keys directly in the app’s source code is a bad idea, since they can be extracted from the binary. However, using a .plist file doesn’t seem secure either, as it’s still bundled with the app and can be inspected.
I’m wondering:
What are Apple’s recommended approaches for managing these kinds of keys?
Does Xcode Cloud offer a built-in or best-practice method for securely injecting environment variables or secrets at build time?
Would using an external service like AWS Secrets Manager or another server-side solution make sense for this use case?
Any insights or examples of how others are handling this securely within Apple’s ecosystem would be greatly appreciated.
Thanks for considering my questions!
— Paul
Topic:
Privacy & Security
SubTopic:
General
Since October 3rd, I've stopped receiving responses to the Private Access Tokens challenge.
I'm using this link: https://demo-issuer.private-access-tokens.fastly.com/.well-known/token-issuer-directory. I receive tokens from Fastly and return a header to the iOS app, but then I don't receive another authentication request from iOS.
The user has automatic verification enabled on their phone. The problem is global and affects all my mobile app users.
Has anyone encountered a similar problem and found a solution?
Topic:
Privacy & Security
SubTopic:
General
Hello,
When using ASWebAuthenticationSession with an HTTPS callback URL (Universal Link), I receive the following error:
Authorization error: The operation couldn't be completed.
Application with identifier jp.xxxx.yyyy.dev is not associated with domain xxxx-example.go.link.
Using HTTPS callbacks requires Associated Domains using the webcredentials service type for xxxx-example.go.link.
I checked Apple’s official documentation but couldn’t find any clear statement that webcredentials is required when using HTTPS callbacks in ASWebAuthenticationSession.
What I’d like to confirm:
Is webcredentials officially required when using HTTPS as a callback URL with ASWebAuthenticationSession?
If so, is there any official documentation or technical note that states this requirement?
Environment
iOS 18.6.2
Xcode 16.4
Any clarification or official references would be greatly appreciated.
Thank you.
Topic:
Privacy & Security
SubTopic:
General
Tags:
iOS
Security
Authentication Services
Universal Links
We are using Apple's PSSO to federate device login to out own IdP. We have developed our own extension app and deployed it using MDM. Things works fine but there are 2 issues that we are trying to get to the root cause -
On some devices after restarting we see an error message on the logic screen saying "The registration for this device is invalid and must be repaired"
And other error message is "SmartCard configuration is invalid for this account"
For the 1st we have figured out that this happens when the registration doesn't happen fully and the key is not tied to the user so when the disk needs to be decrypted at the FileVault screen the issue is raised.
For the "SmartCard configuration is invalid for this account" issue also one aspect is invalid registration but there has been other instances as well where the devices were registered completely but then also the the above error was raised. We verified the registration being completed by checking if the SmartCard is visible in the System Report containing the key.
Has anyone seen the above issues and any possible resolution around it?
FB18383742
Setup
🛠️ Xcode 16.4 (16F6)
📱 iPhone 13 mini (iOS 18.0.1)
⌚️ Apple Watch Series 10 (watchOS 11.3.1)
Observations
As AccessorySetupKit does not request "Core Bluetooth permissions", when a watchOS companion app is installed after having installed the iOS app, the toggle in the watch settings for Privacy & Security > Bluetooth is turned off and disabled
After removing the iPhone associated with the Apple Watch, Bluetooth works as expected in the watchOS app
Upon reinstalling the iOS app, there's a toggle for Bluetooth in the iOS ASK app's settings and the ASK picker cannot be presented 🤨
From ASK Documentation:
AccessorySetupKit is available for iOS and iPadOS. The accessory’s Bluetooth permission doesn’t sync to a companion watchOS app.
But this doesn't address not being able to use Core Bluetooth in a watch companion app at all 🥲
Reproducing the bug
Install the iOS + watchOS apps
Launch iOS app, tap "start scan", observe devices can be discovered (project is set up to find heart rate monitors)
Launch watchOS, tap allow on Bluetooth permission pop-up
watchOS app crashes 💥
Meanwhile, in the iOS app, there should be a log entry for 💗 CBCentralManager state: poweredOff and the ASK picker is no longer able to discover any devices
The state of the device permissions:
iOS app has no paired accessories or Bluetooth permission
watchOS app's Bluetooth permission shown as turned off & disabled
Remove the iOS app
Relaunch the watchOS app
Notice the CBCentralManager state is unauthorized
Remove and reinstall the watchOS app
Tap allow on Bluetooth permission pop-up
watchOS app does not crash and CBCentralManager state is poweredOn
The state of the watch permissions:
Bluetooth is turned on & the toggle is not disabled
Note that at this time the iOS app is not installed, there is no way to remove Bluetooth permission for the watch app.
Reinstall + launch the iOS app
Notice a warning in the log:
[##### WARNING #####] App has companion watch app that maybe affected if using CoreBluetooth framework. Please read developer documentation for AccessorySetupKit.
Notice a log entry for 💗 CBCentralManager state: poweredOn before tapping start scan
Tap start scan and observe another log entry:
Failed to show picker due to: The operation couldn’t be completed. (ASErrorDomain error 550.)
ASErrorDomain 550:
The picker can't be used because the app is in the background.
Is this the expected error? 🤔
The state of the iOS permissions:
The app's settings show a Bluetooth toggle normally associated with Core Bluetooth, but the app never showed a Core Bluetooth pop-up
The iOS ASK app now has Core Bluetooth permission 😵💫
Following up with Apple
This is a known bug that should be fixed in watchOS 26 when Bluetooth permissions for watch apps can be set independently of the iOS app. I've yet to test it with watchOS 26.
See repo for the same post with screenshots of the settings and demo code reproducing the bug:
https://github.com/superturboryan/AccessorySetupKit-CoreBluetooth-watchOS-Demo
I've been spending days trying to solve the memory leak in a small menu bar application I've wrote (SC Menu). I've used Instruments which shows the leaks and memory graph which shows unreleased allocations. This occurs when someone views a certificate on the smartcard.
Basically it opens a new window and displays the certificate, the same way Keychain Access displays a certificate. Whenever I create an SFCertificateView instance and set setDetailsDisclosed(true) - a memory leak happens. Instruments highlights that line.
import Cocoa
import SecurityInterface
class ViewCertsViewController: NSViewController {
var selectedCert: SecIdentity? = nil
override func viewDidLoad() {
super.viewDidLoad()
self.view = NSView(frame: NSRect(x: 0, y: 0, width: 500, height: 500))
self.view.wantsLayer = true
var secRef: SecCertificate? = nil
guard let selectedCert else { return }
let certRefErr = SecIdentityCopyCertificate(selectedCert, &secRef)
if certRefErr != errSecSuccess {
os_log("Error getting certificate from identity: %{public}@", log: OSLog.default, type: .error, String(describing: certRefErr))
return
}
let scrollView = NSScrollView()
scrollView.translatesAutoresizingMaskIntoConstraints = false
scrollView.borderType = .lineBorder
scrollView.hasHorizontalScroller = true
scrollView.hasVerticalScroller = true
let certView = SFCertificateView()
guard let secRef = secRef else { return }
certView.setCertificate(secRef)
certView.setDetailsDisclosed(true)
certView.setDisplayTrust(true)
certView.setEditableTrust(true)
certView.setDisplayDetails(true)
certView.setPolicies(SecPolicyCreateBasicX509())
certView.translatesAutoresizingMaskIntoConstraints = false
scrollView.documentView = certView
view.addSubview(scrollView)
// Layout constraints
NSLayoutConstraint.activate([
scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
scrollView.topAnchor.constraint(equalTo: view.topAnchor),
scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
// Provide certificate view a width and height constraint
certView.widthAnchor.constraint(equalTo: scrollView.widthAnchor),
certView.heightAnchor.constraint(greaterThanOrEqualToConstant: 500)
])
}
}
https://github.com/boberito/sc_menu/blob/dev_2.0/smartcard_menu/ViewCertsViewController.swift
Fairly simple.
Hello,
Thanks for the new video on Memory Integrity Enforcement!
Is the presented app's sample code available (so that we can play with it and find & fix the bug on our own, using Soft Mode)?
Thanks in advance!
Platforms: macOS 15.x (Sequoia), Intel-Based
App type: Endpoint Security (ES) client, notarized Developer ID app + LaunchDaemon
Goal: Boot-time ES client that runs on any Mac (managed or unmanaged)
Summary
Our ES client launches and functions when started manually (terminal), but when loaded as a LaunchDaemon it fails to initialize the ES connection with:
(libEndpointSecurity.dylib) Failed to open service: 0xe00002d8: Caller lacks TCC authorization for Full Disk Access
We can’t find a supported way to grant Full Disk Access (SystemPolicyAllFiles) to a system daemon on unmanaged Macs (no MDM). Local installation of a PPPC (TCC) profile is rejected as “must originate from a user-approved MDM server.”
We’re seeking confirmation: Is MDM now the only supported path for a boot-time ES daemon that requires FDA? If so, what’s Apple’s recommended approach for unmanaged Macs?
Environment & Artifacts
Binary (path placeholder):
/Library/Application Support///App/.app/Contents/MacOS/
Universal (x86_64 + arm64)
Notarized, hardened runtime; Developer ID Team <TEAM_ID>
Entitlements include:
com.apple.developer.endpoint-security.client (present)
Daemon plist (simplified; placeholders used):
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0"><dict>
<key>Label</key> <string>com.example.esd</string>
<key>Program</key>
<string>/Library/Application Support/<VENDOR>/<PRODUCT>/Platform/<daemon-exec></string>
<key>WorkingDirectory</key>
<string>/Library/Application Support/<VENDOR>/<PRODUCT>/Platform</string>
<key>RunAtLoad</key><true/>
<key>KeepAlive</key><true/>
</dict></plist>
Designated requirement (abridged & masked):
identifier "<BUNDLE_ID>" and anchor apple generic and certificate 1[...] and
certificate leaf[...] and certificate leaf[subject.OU] = "<TEAM_ID>"
What works
Launching the ES client manually (interactive shell) succeeds; ES events flow.
Signature, notarization, entitlements, Gatekeeper: all OK.
What fails (daemon)
launchctl print system/ shows it starts, but Console logs:
(libEndpointSecurity.dylib) Failed to open service: 0xe00002d8:Caller lacks TCC authorization for Full Disk Access
System TCC DB shows ES consent rows but no allow for TCCServiceSystemPolicyAllFiles for the daemon binary.
Installing a PPPC mobileconfig locally (system scope) is blocked as “must originate from a user-approved MDM server.”
Repro (minimal)
Install app bundle + LaunchDaemon plist above (placeholders).
Verify entitlements & notarization:
codesign -dvvv --entitlements :- ""
spctl --assess --type execute -vv ""
Start daemon & watch logs:
sudo launchctl bootstrap system "/Library/LaunchDaemons/.plist"
log stream --style compact --predicate 'process == "" OR subsystem == "com.apple.TCC"' --info
Observe FDA denial message only in daemon context.
Attempt to add FDA via PPPC profile (system scope) → rejected unless installed by user-approved MDM.
Questions for Apple
On macOS 14/15, is Full Disk Access for system daemons strictly MDM-only via PPPC (i.e., not installable locally)?
Under what conditions would libEndpointSecurity report a Full Disk Access denial at client initialization, given ES consent is distinct from FDA?
For unmanaged Macs needing boot-time ES processing, does Apple recommend a split: root LaunchDaemon (ES subscription; no protected file I/O) + per-user LaunchAgent (user-granted FDA) via XPC for on-demand disk access?
Would moving ES connection code into a System Extension change FDA requirements for unmanaged devices, or is FDA still governed by PPPC/MDM?
If behavior changed across releases, can Apple confirm the intended policy so vendors can document MDM requirements vs. unmanaged install paths?
What we’ve tried
Verified signature, notarization, hardened runtime, ES entitlement present.
Confirmed context difference: manual run OK; daemon fails.
Inspected system TCC: ES consent rows present; no FDA allow for daemon.
Tried installing system-scoped PPPC locally → blocked as “must originate from a user-approved MDM server.”
Considered LaunchAgent-only, but ES needs root; evaluating daemon+agent split to keep ES in root and put FDA-gated work in user space.
What we need
A definitive statement on the supported way to grant FDA to a system daemon on macOS 14/15.
If MDM PPPC is required, we’ll ship “daemon mode requires MDM” and provide a daemon+agent fallback for unmanaged devices.
If a compliant non-MDM path exists for daemon FDA on unmanaged Macs, please share exact steps.
Thanks! Happy to provide additional logs privately if helpful.
Hello,
I'm an application developer related to Apple system extensions. I developed an endpoint security system extension that can run normally before the 14.x system. However, after I upgraded to 15.x, I found that when I uninstalled and reinstalled my system extension, although the system extension was installed successfully, a system warning box would pop up when I clicked enable in the Settings, indicating a failure.
I conducted the following test. I reinstalled a brand-new MAC 15.x system. When I installed my applications, the system extensions could be installed successfully and enabled normally. However, when I uninstalled and reinstalled, my system extension couldn't be enabled properly and a system warning popped up as well. I tried disabling SIP and enabling System Extension Developers, but it still didn't work.
When the system warning box pops up, I can see some error log information through the console application, including an error related to
Failed to authorize right 'com.apple.system-extensions.admin' by client '/System/Library/ExtensionKit/Extensions/SettingsSystemExtensionController.appex' [2256] for authorization created by '/System/Library/ExtensionKit/Extensions/SettingsSystemExtensionController.appex' [2256] (3,0) (-60005) (engine 179)
as shown in the screenshot.
The same problem, mentioned in Cannot approve some extensions in MacOS Sequoia , but there is no solution
I’m using a custom Installer plug-in (InstallerPane) to collect sensitive user input (username/password) during install. After the payload is laid down, I need to send those values to a newly installed agent (LaunchAgent) to persist them.
What I tried
I expose an XPC Mach service from the agent and have the plug-in call it.
On the agent side I validate the XPC client using the audit token → SecCodeCopyGuestWithAttributes → SecCodeCheckValidity.
However, the client process is InstallerRemotePluginService-* (Apple’s view service that hosts all plug-ins), so the signature I see is Apple’s, not mine. I can’t distinguish which plug-in made the call.
Any suggestion on better approach ?
Hi,
I have a certificate, how can I display the certificate content in my Mac app just like Keychain Access app does. Can I popup the certificate content dialog just like Keychain Access app?
I have an app (currently not released on App Store) which runs on both iOS and macOS. The app has widgets for both iOS and macOS which uses user preference (set in app) into account while showing data. Before upgrading to macOS 15 (until Sonoma) widgets were working fine and app was launching correctly, but after upgrading to macOS 15 Sequoia, every time I launch the app it give popup saying '“Kontest” would like to access data from other apps. Keeping app data separate makes it easier to manage your privacy and security.' and also widgets do not get user preferences and throw the same type of error on Console application when using logging. My App group for both iOS and macOS is 'group.com.xxxxxx.yyyyy'. I am calling it as 'UserDefaults(suiteName: Constants.userDefaultsGroupID)!.bool(forKey: "shouldFetchAllEventsFromCalendar")'. Can anyone tell, what am I doing wrong here?
Hi,
is it somehow possible to access a key that was generated by the DCAppAttestService generateKey() function?
I need to be 100% sure that no actor from within or outside of my app can access the generated key with the DeviceCheck Framework. It would also be helpful to get some official resources to the topic.
Thank you in advance,
Mike
I am developing a daemon-based product that needs a cryptographic, non-spoofable proof of machine identity so a remote management server can grant permissions based on the physical machine.
I was thinking to create a signing key in the Secure Enclave and use a certificate signed by that key as the machine identity. The problem is that the Secure Enclave key I can create is only accessible from user context, while my product runs as a system daemon and must not rely on user processes or launchAgents.
Could you please advise on the recommended Apple-supported approaches for this use case ?
Specifically, Is there a supported way for a system daemon to generate and use an unremovable Secure Enclave key during phases like the pre-logon, that doesn't have non user context (only the my application which created this key/certificate will have permission to use/delete it)
If Secure Enclave access from a daemon is not supported, what Apple-recommended alternatives exist for providing a hardware-backed machine identity for system daemons?
I'd rather avoid using system keychain, as its contents may be removed or used by root privileged users.
The ideal solution would be that each Apple product, would come out with a non removable signing certificate, that represent the machine itself (lets say that the cetificate name use to represent the machine ID), and can be validated by verify that the root signer is "Apple Root CA"
I have an Autofill Passkey Provider working for Safari and Chrome via WebAuthn protocol. Unfortunately, Chrome will not offer my extension as a logon credential provider unless I add the credential to the ASCredentialIdentityStore.
I wonder what is the best way to access the ASCredentialIdentityStore from an AutoFill extension? I understand I cannot access it directly from the extension context, so what is the best way to trigger my container app to run, based on a new WebAuthn registration? The best I can think of so far is for the www site to provide an App Link to launch my container app as part of the registration ceremony.
Safari will offer my extension even without adding it to the ASCredentialIdentityStore, so I guess I should file a request with Chrome to work this way too, given difficulty of syncing ASCredentialIdentityStore with WebAuthn registration.
Hi! Is it possible to disable the option for users to 'Sign in with Another Device'? I encounter this message during the authentication process and I want to prevent it from appearing. I appreciate your help and look forward to your response.
Hello, I am currently implementing a biometric authentication registration flow using WebAuthn. I am using ASAuthorizationPlatformPublicKeyCredentialRegistrationRequest, and I would like to know if there is a way to hide the "Save to another device" option that appears during the registration process.
Specifically, I want to guide users to save the passkey only locally on their device, without prompting them to save it to iCloud Keychain or another device.
If there is a way to hide this option or if there is a recommended approach to achieve this, I would greatly appreciate your guidance.
Also, if this is not possible due to iOS version or API limitations, I would be grateful if you could share any best practices for limiting user options in this scenario.
If anyone has experienced a similar issue, your advice would be very helpful. Thank you in advance.