Security

RSS for tag

Secure the data your app manages and control access to your app using the Security framework.

Posts under Security tag

140 Posts

Post

Replies

Boosts

Views

Activity

SecItem: Fundamentals
I regularly help developers with keychain problems, both here on DevForums and for my Day Job™ in DTS. Many of these problems are caused by a fundamental misunderstanding of how the keychain works. This post is my attempt to explain that. I wrote it primarily so that Future Quinn™ can direct folks here rather than explain everything from scratch (-: If you have questions or comments about any of this, put them in a new thread and apply the Security tag so that I see it. Share and Enjoy — Quinn “The Eskimo!” @ Developer Technical Support @ Apple let myEmail = "eskimo" + "1" + "@" + "apple.com" SecItem: Fundamentals or How I Learned to Stop Worrying and Love the SecItem API The SecItem API seems very simple. After all, it only has four function calls, how hard can it be? In reality, things are not that easy. Various factors contribute to making this API much trickier than it might seem at first glance. This post explains the fundamental underpinnings of the keychain. For information about specific issues, see its companion post, SecItem: Pitfalls and Best Practices. Keychain Documentation Your basic starting point should be Keychain Items. If your code runs on the Mac, also read TN3137 On Mac keychain APIs and implementations. Read the doc comments in <Security/SecItem.h>. In many cases those doc comments contain critical tidbits. When you read keychain documentation [1] and doc comments, keep in mind that statements specific to iOS typically apply to iPadOS, tvOS, and watchOS as well (r. 102786959). Also, they typically apply to macOS when you target the data protection keychain. Conversely, statements specific to macOS may not apply when you target the data protection keychain. [1] Except TN3137, which is very clear about this (-: Caveat Mac Developer macOS supports two different keychain implementations: the original file-based keychain and the iOS-style data protection keychain. IMPORTANT If you’re able to use the data protection keychain, do so. It’ll make your life easier. See the Careful With that Shim, Mac Developer section of SecItem: Pitfalls and Best Practices for more about this. TN3137 On Mac keychain APIs and implementations explains this distinction. It also says: The file-based keychain is on the road to deprecation. This is talking about the implementation, not any specific API. The SecItem API can’t be deprecated because it works with both the data protection keychain and the file-based keychain. However, Apple has deprecated many APIs that are specific to the file-based keychain, for example, SecKeychainCreate. TN3137 also notes that some programs, like launchd daemons, can’t use the file-based keychain. If you’re working on such a program then you don’t have to worry about the deprecation of these file-based keychain APIs. You’re already stuck with the file-based keychain implementation, so using a deprecated file-based keychain API doesn’t make things worse. The Four Freedoms^H^H^H^H^H^H^H^H Functions The SecItem API contains just four functions: SecItemAdd(_:_:) SecItemCopyMatching(_:_:) SecItemUpdate(_:_:) SecItemDelete(_:) These directly map to standard SQL database operations: SecItemAdd(_:_:) maps to INSERT. SecItemCopyMatching(_:_:) maps to SELECT. SecItemUpdate(_:_:) maps to UPDATE. SecItemDelete(_:) maps to DELETE. You can think of each keychain item class (generic password, certificate, and so on) as a separate SQL table within the database. The rows of that table are the individual keychain items for that class and the columns are the attributes of those items. Note Except for the digital identity class, kSecClassIdentity, where the values are split across the certificate and key tables. See Digital Identities Aren’t Real in SecItem: Pitfalls and Best Practices. This is not an accident. The data protection keychain is actually implemented as an SQLite database. If you’re curious about its structure, examine it on the Mac by pointing your favourite SQLite inspection tool — for example, the sqlite3 command-line tool — at the keychain database in ~/Library/Keychains/UUU/keychain-2.db, where UUU is a UUID. WARNING Do not depend on the location and structure of this file. These have changed in the past and are likely to change again in the future. If you embed knowledge of them into a shipping product, it’s likely that your product will have binary compatibility problems at some point in the future. The only reason I’m mentioning them here is because I find it helpful to poke around in the file to get a better understanding of how the API works. For information about which attributes are supported by each keychain item class — that is, what columns are in each table — see the Note box at the top of Item Attribute Keys and Values. Alternatively, look at the Attribute Key Constants doc comment in <Security/SecItem.h>. Uniqueness A critical part of the keychain model is uniqueness. How does the keychain determine if item A is the same as item B? It turns out that this is class dependent. For each keychain item class there is a set of attributes that form the uniqueness constraint for items of that class. That is, if you try to add item A where all of its attributes are the same as item B, the add fails with errSecDuplicateItem. For more information, see the errSecDuplicateItem page. It has lists of attributes that make up this uniqueness constraint, one for each class. These uniqueness constraints are a major source of confusion, as discussed in the Queries and the Uniqueness Constraints section of SecItem: Pitfalls and Best Practices. Parameter Blocks Understanding The SecItem API is a classic ‘parameter block’ API. All of its inputs are dictionaries, and you have to know which properties to set in each dictionary to achieve your desired result. Likewise for when you read properties in output dictionaries. There are five different property groups: The item class property, kSecClass, determines the class of item you’re operating on: kSecClassGenericPassword, kSecClassCertificate, and so on. The item attribute properties, like kSecAttrAccessGroup, map directly to keychain item attributes. The search properties, like kSecMatchLimit, control how the system runs a query. The return type properties, like kSecReturnAttributes, determine what values the query returns. The value type properties, like kSecValueRef perform multiple duties, as explained below. There are other properties that perform a variety of specific functions. For example, kSecUseDataProtectionKeychain tells macOS to use the data protection keychain instead of the file-based keychain. These properties are hard to describe in general; for the details, see the documentation for each such property. Inputs Each of the four SecItem functions take dictionary input parameters of the same type, CFDictionary, but these dictionaries are not the same. Different dictionaries support different property groups: The first parameter of SecItemAdd(_:_:) is an add dictionary. It supports all property groups except the search properties. The first parameter of SecItemCopyMatching(_:_:) is a query and return dictionary. It supports all property groups. The first parameter of SecItemUpdate(_:_:) is a pure query dictionary. It supports all property groups except the return type properties. Likewise for the only parameter of SecItemDelete(_:). The second parameter of SecItemUpdate(_:_:) is an update dictionary. It supports the item attribute and value type property groups. Outputs Two of the SecItem functions, SecItemAdd(_:_:) and SecItemCopyMatching(_:_:), return values. These output parameters are of type CFTypeRef because the type of value you get back depends on the return type properties you supply in the input dictionary: If you supply a single return type property, except kSecReturnAttributes, you get back a value appropriate for that return type. If you supply multiple return type properties or kSecReturnAttributes, you get back a dictionary. This supports the item attribute and value type property groups. To get a non-attribute value from this dictionary, use the value type property that corresponds to its return type property. For example, if you set kSecReturnPersistentRef in the input dictionary, use kSecValuePersistentRef to get the persistent reference from the output dictionary. In the single item case, the type of value you get back depends on the return type property and the keychain item class: For kSecReturnData you get back the keychain item’s data. This makes most sense for password items, where the data holds the password. It also works for certificate items, where you get back the DER-encoded certificate. Using this for key items is kinda sketchy. If you want to export a key, called SecKeyCopyExternalRepresentation. Using this for digital identity items is nonsensical. For kSecReturnRef you get back an object reference. This only works for keychain item classes that have an object representation, namely certificates, keys, and digital identities. You get back a SecCertificate, a SecKey, or a SecIdentity, respectively. For kSecReturnPersistentRef you get back a data value that holds the persistent reference. Value Type Subtleties There are three properties in the value type property group: kSecValueData kSecValueRef kSecValuePersistentRef Their semantics vary based on the dictionary type. For kSecValueData: In an add dictionary, this is the value of the item to add. For example, when adding a generic password item (kSecClassGenericPassword), the value of this key is a Data value containing the password. This is not supported in a query dictionary. In an update dictionary, this is the new value for the item. For kSecValueRef: In add and query dictionaries, the system infers the class property and attribute properties from the supplied object. For example, if you supply a certificate object (SecCertificate, created using SecCertificateCreateWithData), the system will infer a kSecClass value of kSecClassCertificate and various attribute values, like kSecAttrSerialNumber, from that certificate object. This is not supported in an update dictionary. For kSecValuePersistentRef: For query dictionaries, this uniquely identifies the item to operate on. This is not supported in add and update dictionaries. Revision History 2025-05-28 Expanded the Caveat Mac Developer section to cover some subtleties associated with the deprecation of the file-based keychain. 2023-09-12 Fixed various bugs in the revision history. Added a paragraph explaining how to determine which attributes are supported by each keychain item class. 2023-02-22 Made minor editorial changes. 2023-01-28 First posted.
0
0
4.4k
May ’25
Entitlement values for the Enhanced Security and the Additional Runtime Platform Restrictions
I recently turned on the enhanced security options for my macOS app in Xcode 26.0.1 by adding the Enhanced Security capability in the Signing and Capabilities tab. Then, Xcode adds the following key-value sets (with some other key-values) to my app's entitlements file. <key>com.apple.security.hardened-process.enhanced-security-version</key> <integer>1</integer> <key>com.apple.security.hardened-process.platform-restrictions</key> <integer>2</integer> These values appear following the documentation about the enhanced security feature (Enabling enhanced security for your app) and the app works without any issues. However, when I submitted a new version to the Mac App Store, my submission was rejected, and I received the following message from the App Review team via the App Store Connect. Guideline 2.4.5(i) - Performance Your app incorrectly implements sandboxing, or it contains one or more entitlements with invalid values. Please review the included entitlements and sandboxing documentation and resolve this issue before resubmitting a new binary. Entitlement "com.apple.security.hardened-process.enhanced-security-version" value must be boolean and true. Entitlement "com.apple.security.hardened-process.platform-restrictions" value must be boolean and true. When I changed those values directly in the entitlements file based on this message, the app appears to still work. However, these settings are against the description in the documentation I mentioned above and against the settings Xcode inserted after changing the GUI setting view. So, my question is, which settings are actually correct to enable the Enhanced Security and the Additional Runtime Platform Restrictions?
5
0
1.1k
14m
App ID Prefix Change and Keychain Access
DTS regularly receives questions about how to preserve keychain items across an App ID change, and so I thought I’d post a comprehensive answer here for the benefit of all. If you have any questions or comments, please start a new thread here on the forums. Put it in the Privacy & Security > General subtopic and tag it with Security. Share and Enjoy — Quinn “The Eskimo!” @ Developer Technical Support @ Apple let myEmail = "eskimo" + "1" + "@" + "apple.com" App ID Prefix Change and Keychain Access The list of keychain access groups your app can access is determined by three entitlements. For the details, see Sharing Access to Keychain Items Among a Collection of Apps. If your app changes its App ID prefix, this list changes and you’re likely to lose access to existing keychain items. This situation crops up under two circumstances: When you migrate your app from using a unique App ID prefix to using your Team ID as its App ID prefix. When you transfer your app to another team. In both cases you have to plan carefully for this change. If you only learn about the problem after you’ve made the change, consider undoing the change to give you time to come up with a plan before continuing. Note On macOS, the information in this post only applies to the data protection keychain. For more information about the subtleties of the keychain on macOS, see On Mac Keychains. For more about App ID prefix changes, see Technote 2311 Managing Multiple App ID Prefixes and QA1726 Resolving the Potential Loss of Keychain Access warning. Migrate From a Unique App ID Prefix to Your Team ID Historically each app was assigned its own App ID prefix. This is no longer the case. Best practice is for apps to use their Team ID as their App ID prefix. This enables multiple neat features, including keychain item sharing and pasteboard sharing. If you have an app that uses a unique App ID prefix, consider migrating it to use your Team ID. This is a good thing in general, as long as you manage the migration process carefully. Your app’s keychain access group list is built from three entitlements: keychain-access-groups — For more on this, see Keychain Access Groups Entitlement. application-identifier (com.apple.application-identifier on macOS) com.apple.security.application-groups — For more on this, see App Groups Entitlement. Keycahin access groups from the third bullet are call app group identified keychain access groups, or AGI keychain access groups for short. IMPORTANT A macOS app can only use an AGI keychain access group if all of its entitlement claims are validated by a provisioning profile. See App Groups: macOS vs iOS: Working Towards Harmony for more about this concept. Keychain access groups from the first two bullets depend on the App ID prefix. If that changes, you lose access to any keychain items in those groups. WARNING Think carefully before using the keychain to store secrets that are the only way to access irreplaceable user data. While the keychain is very reliable, there are situations where a keychain item can be lost and it’s bad if it takes the user’s data with it. In some cases losing access to keychain items is not a big deal. For example, if your app uses the keychain to manage a single login credential, losing that is likely to be acceptable. The user can recover by logging in again. In other cases losing access to keychain items is unacceptable. For example, your app might manage access to dozens of different servers, each with unique login credentials. Your users will be grumpy if you require them to log in to all those servers again. In such situations you must carefully plan your migration. The key thing to understand is that an app group is tied to your team, not your App ID prefix, and thus your app retains access to AGI keychain access groups across an App ID prefix change. This suggests the following approach: Release a version of your app that moves keychain items from other keychain access groups to an AGI keychain access group. Give your users time to update to this new version, run it, and so move their keychain items. When you’re confident that the bulk of your users have done this, change your App ID prefix. The approach has one obvious caveat: It’s hard to judge how long to wait at step 2. Transfer Your App to Another Team Historically there was no supported way to maintain access to keychain items across an app transfer. That’s no longer the case, but you must still plan the transfer carefully. The overall approach is: Identify an app group ID to transfer. This could be an existing app group ID, but in many cases you’ll want to register a new app group ID solely for this purpose. Use the old team (the transferor) to release a version of your app that moves keychain items from other keychain access groups to the AGI keychain access group for this app group ID. Give your users time to update to this new version, run it, and so move their keychain items. When you’re confident that the bulk of your users have done this, initiate the app transfer. Once that’s complete, transfer the app group ID you selected in step 1. See App Store Connect Help > Transfer an app > Overview of app transfer > Apps using App Groups. Publish an update to your app from the new team (the transferee). When a user installs this version, it will have access to your app group, and hence your keychain items. WARNING Once you transfer the app group, the old team won’t be able to publish a new version of any app that uses this app group. That makes step 1 in the process critical. If you have an existing app group that’s used solely by the app being transferred — for example, an app group that you use to share state between the app and its app extensions — then choosing that app group ID makes sense. On the other hand, choosing the ID of an app group that’s share between this app and some unrelated app, one that’s not being transferred, would be bad, because any updates to that other app will lose access to the app group. There are some other significant caveats: The process doesn’t work for Mac apps because Mac apps that have ever used an app group can’t be transferred. See App Store Connect Help > Transfer an app > App transfer criteria. If and when that changes, you’ll need to choose an iOS-style app group ID for your AGI keychain access group. For more about the difference between iOS- and macOS-style app group IDs, see App Groups: macOS vs iOS: Working Towards Harmony. The current transfer process of app groups exposes a small window where some other team can ‘steal’ your app group ID. We have a bug on file to improve that process (r. 171616887). The process works best when transferring between two teams that are both under the control of the same entity. If that’s not the case, take steps to ensure that the old team transfers the app group in step 5. When you submit the app from the new team (step 6), App Store Connect will warn you about a potential loss of keychain access. That warning is talking about keychain items in normal keychain access groups. Items in an AGI keychain access group will still be accessible as long as you transfer the app group. Alternative Approaches for App Transfer In addition to the technique described in the previous section, there are a some alternative approaches you should at consider: Do nothing Do not transfer your app Get creative Do Nothing In this case the user loses all the secrets that your app stored in the keychain. This may be acceptable for certain apps. For example, if your app uses the keychain to manage a single login credential, losing that is likely to be acceptable. The user can recover by logging in again. Do Not Transfer Another option is to not transfer your app. Instead, ship a new version of the app from the new team and have the old app recommend that the user upgrade. There are a number of advantages to this approach. The first is that there’s absolutely no risk of losing any user data. The two apps are completely independent. The second advantage is that the user can install both apps on their device at the same time. This opens up a variety of potential migration paths. For example, you might ship an update to the old app with an export feature that saves the user’s state, including their secrets, to a suitably encrypted file, and then match that with an import facility on the new app. Finally, this approach offers flexible timing. The user can complete their migration at their leisure. However, there are a bunch of clouds to go with these silver linings: Your users might never migrate to the new app. If this is a paid app, or an app with in-app purchase, the user will have to buy things again. You lose the original app’s history, ratings, reviews, and so on. Get Creative Finally, you could attempt something creative. For example, you might: Publish a new version of the app that supports exporting the user’s state, including the secrets. Tell your users to do this, with a deadline. Transfer the app and then, when the deadline expires, publish the new version with an import feature. Frankly, this isn’t very practical. The problem is with step 2: There’s no good way to get all your users to do the export, and if they don’t do it before the deadline there’s no way to do it after. Revision History 2026-03-31 Rewrote the Transfer Your App to Another Team section to describe a new approach for preserving access to keychain items across app transfers. Moved the previous discussion into a new Alternative Approaches for App Transfer section. Clarified that a macOS program can now use an app group as a keychain access group as long as its entitlements are validated. Made numerous editorial changes. 2022-05-17 First posted.
0
0
8.5k
1d
Exploring Secure Enclave–backed biometric authorization between macOS and iPhone using public APIs (FaceBridge prototype)
Hi everyone, I’ve been working on an experimental prototype called FaceBridge that explores whether Secure Enclave–backed biometric authorization can be delegated between macOS and iPhone using only public Apple APIs. The goal of the project was to better understand the architectural boundaries of cross-device trust and approval flows that resemble Apple’s built-in Touch ID / Continuity authorization experiences. FaceBridge implements a local authorization pipeline where: macOS generates a signed authorization request the request is delivered to a trusted nearby iPhone over BLE / Network framework the iPhone verifies sender identity Face ID approval is requested using LocalAuthentication the iPhone signs the approval response using Secure Enclave–backed keys macOS validates the response and unlocks a protected action Security properties currently implemented: • Secure Enclave–backed signing identities per device • cryptographic device pairing and trust persistence • replay protection using nonce + timestamp binding • structured authorization request/response envelopes • signed responder identity verification • trusted-device registry model • local encrypted transport over BLE and local network This is intentionally not attempting to intercept or replace system-level Touch ID dialogs (App Store installs, Keychain prompts, loginwindow, etc.), but instead explores what is possible within application-level authorization boundaries using public APIs only. The project is open source: https://github.com/wesleysfavarin/facebridge Technical architecture write-up: https://medium.com/@wesleysfavarin/facebridge I’m particularly interested in feedback around: • recommended Secure Enclave identity lifecycle patterns • best practices for cross-device trust persistence • LocalAuthentication usage in delegated approval scenarios • whether similar authorization models are expected to become more formally supported across Apple platforms in the future Thanks in advance for any guidance or suggestions.
1
0
65
1d
Endpoint Security entitlement for open-source behavioral monitoring tool
Hi, I’m building a macOS tool that analyzes process behavior to detect autonomous / AI-like activity locally (process trees, file access patterns, and network usage). The system is fully user-space and runs locally in real time. I’m planning to use the Endpoint Security Framework for process and file event monitoring. This is an open-source project (non-enterprise), developed by a solo developer. My question: What are the realistic chances of getting Endpoint Security entitlements approved for this type of project? Are there specific requirements or common reasons for rejection I should be aware of? Thanks, sivan-rnd
2
0
130
5d
MFA MacOS At ScreenSaver (Lock Screen).
Hi , I did The MFA(2FA) of Email OTP For MacOS Login Screen using, Authorization Plugin, Using This git hub project. It is working For Login Screen , Im trying to Add The Same plugin for LockScreen but it is not working at lock Screen , Below is the reffrense theard For The issue , https://developer.apple.com/forums/thread/127614, please Share The Code that should Present the NSwindow at Screen Saver (Lock Screen) MacOS .
3
0
973
5d
Enterprise Install for a TLS Inspection proxy
I’m working on a product that includes TLS inspection capability. TLS inspection using a local MitM requires installing a trusted root certificate which is then used to create masquerade certificates to intercept and forward TLS traffic through the proxy. For manual installation the end user is required to authenticate as an administrator to modify the trust settings on our internal CA’s root certificate. My question concerns the options for enterprise deployment using an MDM. We want the generated root certificate to be unique to each endpoint so that if a private key is compromised it can’t be used to intercept traffic anywhere else. We can install a “certificate trust” configuration profile from the MDM but this requires a base64 encoded string of the root certificate. In effect the MDM needs to obtain the certificate from the endpoint and then send it back in the form of a configuration profile. I’m not aware that MDMs like Jamf can be configured to do this directly so we’re looking for any other mechanism to have macOS trust a locally generated certificate via MDM based on some non endpoint-unique criteria? One option might be to use an external CA with a trusted certificate to sign an intermediate endpoint certificate but this creates a significant risk if the external trusted certificate were ever compromised. Is this a common industry practice? So my question remains is there a better way to trust our per endpoint root certificate via MDM without needing to install a unique per endpoint configuration profile?
6
0
785
1w
Securing XPC Daemon Communication from Authorization Plugin
I'm working on securing communication between an Authorization Plugin and an XPC daemon, and I’d appreciate some guidance on best practices and troubleshooting. The current design which, I’ve implemented a custom Authorization Plugin for step-up authentication, which is loaded by Authorization Services at the loginwindow (inside SecurityAgent). This plugin acts as an XPC client and connects to a custom XPC daemon. Setup Details 1. XPC Daemon Runs as root (LaunchDaemon) Not sandboxed (my understanding is that root daemons typically don’t run sandboxed—please correct me if this is wrong) Mach service: com.roboInc.AuthXpcDaemon Bundle identifier: com.roboInc.OfflineAuthXpcDaemon 2. Authorization Plugin Bundle identifier: com.roboInc.AuthPlugin Loaded by SecurityAgent during login 3. Code Signing Both plugin and daemon are signed using a development certificate What I’m Trying to Achieve I want to secure the XPC communication so that: The daemon only accepts connections from trusted clients The plugin only connects to the legitimate daemon Communication is protected against unauthorized access The Issue I'm facing I attempted to validate code signatures using: SecRequirementCreateWithString SecCodeCopyGuestWithAttributes SecCodeCheckValidity However, validation consistently fails with: -67050 (errSecCSReqFailed) Could you please help here What is the recommended way to securely authenticate an Authorization Plugin (running inside SecurityAgent) to a privileged XPC daemon? Since the plugin runs inside SecurityAgent, how can the daemon reliably distinguish my plugin from other plugins? What is the correct approach to building a SecRequirement in this scenario? Any guidance, examples, or pointers would be greatly appreciated. Thanks in advance!
6
0
214
1w
Unlock with Touch ID suggested despite system.login.screensaver being configured with authenticate-session-owner rule
Hello, I’m working on a security agent plugin for Mac. The plugin provides a mechanism with custom UI via SFAuthorizationPluginView and a privileged mechanism with the business logic. The plugin needs to support unlocking the device, so I changed the authorize right to invoke my agent: <?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>class</key> <string>evaluate-mechanisms</string> <key>created</key> <real>731355374.33196402</real> <key>mechanisms</key> <array> <string>FooBar:loginUI</string> <string>builtin:reset-password,privileged</string> <string>FooBar:authenticate,privileged</string> <string>builtin:authenticate,privileged</string> </array> <key>modified</key> <real>795624943.31730103</real> <key>shared</key> <true/> <key>tries</key> <integer>10000</integer> <key>version</key> <integer>1</integer> </dict> </plist> I also changed the system.login.screensaver right to use authorize-session-owner: <?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>class</key> <string>rule</string> <key>comment</key> <string>The owner or any administrator can unlock the screensaver, set rule to "authenticate-session-owner-or-admin" to enable SecurityAgent.</string> <key>created</key> <real>731355374.33196402</real> <key>modified</key> <real>795624943.32567298</real> <key>rule</key> <array> <string>authenticate-session-owner</string> </array> <key>version</key> <integer>1</integer> </dict> </plist> I also set screenUnlockMode to 2, as was suggested in this thread: macOS Sonoma Lock Screen with SFAutorizationPluginView is not hiding the macOS desktop. In the Display Authorization plugin at screensaver unlock thread, Quinn said that authorization plugins are not able to use Touch ID. However, on a MacBook with at touch bar, when I lock the screen, close the lid, and then open it, the touch bar invites me to unlock with Touch ID. If I choose to do so, the screen unlocks and I can interact with the computer, but the plugin UI stays on screen and never goes away, and after about 30 seconds the screen locks back. I can reliably reproduce it on a MacBook Pro with M1 chip running Tahoe 26.1. Is this a known macOS bug? What can I do about it? Ideally, I would like to be able to integrate Touch ID into my plugin, but since that seems to be impossible, the next best thing would be to reliably turn it off completely. Thanks in advance.
2
0
364
1w
How to store certificate to `com.apple.token` keychain access group.
I’m developing an iOS application and aiming to install a PKCS#12 (.p12) certificate into the com.apple.token keychain access group so that Microsoft Edge for iOS, managed via MDM/Intune, can read and use it for client certificate authentication. I’m attempting to save to the com.apple.token keychain access group, but I’m getting error -34018 (errSecMissingEntitlement) and the item isn’t saved. This occurs on both a physical device and the simulator. I’m using SecItemAdd from the Security framework to store it. Is this the correct approach? https://developer.apple.com/documentation/security/secitemadd(::) I have added com.apple.token to Keychain Sharing. I have also added com.apple.token to the app’s entitlements. Here is the code I’m using to observe this behavior: public static func installToTokenGroup(p12Data: Data, password: String) throws -> SecIdentity { // First, import the P12 to get the identity let options: [String: Any] = [ kSecImportExportPassphrase as String: password ] var items: CFArray? let importStatus = SecPKCS12Import(p12Data as CFData, options as CFDictionary, &items) guard importStatus == errSecSuccess, let array = items as? [[String: Any]], let dict = array.first else { throw NSError(domain: NSOSStatusErrorDomain, code: Int(importStatus), userInfo: [NSLocalizedDescriptionKey: "Failed to import P12: \(importStatus)"]) } let identity = dict[kSecImportItemIdentity as String] as! SecIdentity let addQuery: [String: Any] = [ kSecClass as String: kSecClassIdentity, kSecValueRef as String: identity, kSecAttrLabel as String: kSecAttrAccessGroupToken, kSecAttrAccessible as String: kSecAttrAccessibleAfterFirstUnlock, kSecAttrAccessGroup as String: kSecAttrAccessGroupToken ] let status = SecItemAdd(addQuery as CFDictionary, nil) if status != errSecSuccess && status != errSecDuplicateItem { throw NSError(domain: NSOSStatusErrorDomain, code: Int(status), userInfo: [NSLocalizedDescriptionKey: "Failed to add to token group: \(status)"]) } return identity }
1
0
223
1w
SecureTransport PSK Support for TLS
We have successfully deployed our Qt C++ application on Windows and Android using OpenSSL with TLS Pre-Shared Key (PSK) authentication to connect to our servers. However, I understand that apps submitted to the App Store must use SecureTransport as the TLS backend on iOS. My understandiunig is that SecureTransport does not support PSK ciphersuites, which is critical for our security architecture. Questions: Does SecureTransport support TLS PSK authentication, or are there plans to add this feature? If PSK is not supported, what is Apple's recommended alternative for applications that require PSK-based authentication? Is there an approved exception process that would allow me to use OpenSSL for TLS connections on iOS while still complying with App Store guidelines? The application requires PSK for secure communication with our infrastructure, and we need guidance on how to maintain feature parity across all platforms while meeting App Store requirements
2
0
73
2w
The SecKeyCreateSignature method always prompts for the current user's login password.
I downloaded a P12 file (containing a private key) from the company server, and retrieved the private key from this P12 file using a password : private func loadPrivateKeyFromPKCS12(path: String, password: String) throws -> SecKey? { let p12Data: Data do { p12Data = try Data(contentsOf: fileURL) } catch let readError { ... } let options: [CFString: Any] = [ kSecImportExportPassphrase: password as CFString ] var items: CFArray? let status = SecPKCS12Import(p12Data as CFData, options as CFDictionary, &items) guard status == errSecSuccess else { throw exception } var privateKey: SecKey? let idd = identity as! SecIdentity let _ = SecIdentityCopyPrivateKey(idd, &privateKey) return privateKey } However, when I use this private key to call SecKeyCreateSignature for data signing, a dialog box always pops up to ask user to input the Mac admin password. What confuses me is that this private key is clearly stored in the local P12 file, and there should be no access to the keychain involved in this process. Why does the system still require the user's login password for signing? Is it possible to perform silent signing (without the system dialog popping up) in this scenario?
1
0
79
2w
Authorizing a process to access a Private Key pushed via MDM
I am developing a macOS system service (standalone binary running as a LaunchDaemon) that requires the ability to sign data using a private key which will be deployed via MDM. The Setup: Deployment: A .mobileconfig pushes a PKCS12 identity to the System Keychain. Security Requirement: For compliance and security reasons, we cannot set AllowAllAppsAccess to <true/>. The key must remain restricted. The Goal: I need to use the private key from the identity to be able to sign the data The Problem: The Certificate Payload does not support a TrustedApplications or AccessControl array to pre-authorize binary paths. As a result, when the process tries to use the private key for signing (SecKeyCreateSignature), it prompts the user to allow this operation which creates a disruption and is not desired. What i've tried so far: Manually adding my process to the key's ACL in keychain access obviously works and prevents any prompts but this is not an "automatable" solution. Using security tool in a script to attempt to modify the ACL in an automated way, but that also asks user for password and is not seamless. The Question: Is there a documented, MDM-compatible way to inject a specific binary path into the ACL of a private key? If not, is there a better way to achieve the end goal?
1
0
217
2w
QWAC validation
Hello there, Starting from iOS 18.4, support was included for QWAC Validation and QCStatements. Using the official QWAC Validator at: https://eidas.ec.europa.eu/efda/qwac-validation-tool I was able to check that the domain "eidas.ec.europa.eu" has a valid QWAC certificate. However, when trying to obtain the same result using the new API, I do not obtain the same result. Here is my sample playground code: import Foundation import Security import PlaygroundSupport PlaygroundPage.current.needsIndefiniteExecution = true @MainActor class CertificateFetcher: NSObject, URLSessionDelegate { private let url: URL init(url: URL) { self.url = url super.init() } func start() { let session = URLSession(configuration: .ephemeral, delegate: self, delegateQueue: nil) let task = session.dataTask(with: url) { data, response, error in if let error = error { print("Error during request: \(error)") } else { print("Request completed.") } } task.resume() } nonisolated func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -&gt; Void) { guard let trust = challenge.protectionSpace.serverTrust else { completionHandler(.cancelAuthenticationChallenge, nil) return } if let certificates = SecTrustCopyCertificateChain(trust) as? [SecCertificate] { self.checkQWAC(certificates: certificates) } let credential = URLCredential(trust: trust) completionHandler(.useCredential, credential) } nonisolated func checkQWAC(certificates: [SecCertificate]) { let policy = SecPolicyCreateSSL(true, nil) var trust: SecTrust? guard SecTrustCreateWithCertificates(certificates as CFArray, policy, &amp;trust) == noErr, let trust else { print("Unable to create SecTrust") return } var error: CFError? guard SecTrustEvaluateWithError(trust, &amp;error) else { print("Trust evaluation failed") return } guard let result = SecTrustCopyResult(trust) as? [String : Any] else { print("No result dictionary") return } let qwacStatus = result[kSecTrustQWACValidation as String] let qcStatements = result[kSecTrustQCStatements as String] print("QWAC Status: \(String(describing: qwacStatus))") print("QC Statements: \(String(describing: qcStatements))") } } let url = URL(string: "https://eidas.ec.europa.eu/")! let fetcher = CertificateFetcher(url: url) fetcher.start() Which prints: QWAC Status: nil QC Statements: nil Request completed. Am I making a mistake while using the Security framework? I would greatly appreciate any help or guidance you can provide.
6
0
281
3w
SecurityAgent taking focus for plugin in macOS 26.1
We have a custom SecurityAgentPlugin that is triggered by multiple authorizationdb entries. Some customers report that the SecurityAgent process takes window focus even though no UI or windows are displayed. Our plugin explicitly ignores the _securityAgent user and does not show any UI for that user. However, in macOS 26.1, it appears that the plugin still causes the SecurityAgent to take focus as soon as it is triggered. Is this a change in macOS 26.1 or a bug? Can we do anything to prevent "focus stealing"?
27
3
4.7k
3w
`cp` ( & friends ) silent loss of extended attributes & file flags
Since the introduction of the siblings / and /System/Volumes/Data architecture, some very basic, critical commands seems to have a broken behaviour ( cp, rsync, tar, cpio…). As an example, ditto which was introduced more than 10 years ago to integrate correctly all the peculiarity of HFS Apple filesystem as compared to the UFS Unix filesystem is not behaving correctly. For example, from man ditto: --rsrc Preserve resource forks and HFS meta-data. ditto will store this data in Carbon-compatible ._ AppleDouble files on filesystems that do not natively support resource forks. As of Mac OS X 10.4, --rsrc is default behavior. [...] --extattr Preserve extended attributes (requires --rsrc). As of Mac OS X 10.5, --extattr is the default. and nonetheless: # ls -@delO /private/var/db/ConfigurationProfiles/Store drwx------@ 5 root wheel datavault 160 Jan 20 2024 /private/var/db/ConfigurationProfiles/Store                            ********* com.apple.rootless 28 *************************** # mkdir tmp # ditto /private/var/db/ConfigurationProfiles tmp ditto: /Users/alice/Security/Admin/Apple/APFS/tmp/Settings: Operation not permitted ditto: /Users/alice/Security/Admin/Apple/APFS/tmp/Store: Operation not permitted # ls -@delO tmp/Store drwx------ 5 root wheel - 160 Aug 8 13:55 tmp/Store                            * # The extended attribute on copied directory Store is empty, the file flags are missing, not preserved as documented and as usual behaviour of ditto was since a long time ( macOS 10.5 ). cp, rsync, tar, cpio exhibit the same misbehaviour. But I was using ditto to be sure to avoid any incompatibility with the Apple FS propriaitary modifications. As a consequence, all backup scripts and applications are failing more or less silently, and provide corrupted copies of files or directories. ( I was here investigating why one of my security backup shell script was making corrupted backups, and only on macOS ). How to recover the standard behaviour --extattr working on modern macOS?
4
0
1.1k
Feb ’26
DTLS Handshake Fails When App Is in Background – Is This an iOS Limitation?
Hello, We are facing an issue with performing a DTLS handshake when our iOS application is in the background. Our app (Vocera Collaboration Suite – VCS) uses secure DTLS-encrypted communication for incoming VoIP calls. Problem Summary: When the app is in the background and a VoIP PushKit notification arrives, we attempt to establish a DTLS handshake over our existing socket. However, the handshake consistently fails unless the app is already in the foreground. Once the app is foregrounded, the same DTLS handshake logic succeeds immediately. Key Questions: Is performing a DTLS handshake while the app is in the background technically supported by iOS? Or is this an OS-level limitation by design? If not supported, what is the Apple-recommended alternative to establish secure DTLS communication for VoIP flows without bringing the app to the foreground? Any guidance or clarification from Apple engineers or anyone who has solved a similar problem would be greatly appreciated. Thank you.
5
0
344
Feb ’26
What should be enabled for Enhanced Security?
I am not very well versed in this area, so I would appreciate some guidance on what should be enabled or disabled. My app is an AppKit app. I have read the documentation and watched the video, but I find it hard to understand. When I added the Enhanced Security capability in Xcode, the following options were enabled automatically: Memory Safety Enable Enhanced Security Typed Allocator Runtime Protections Enable Additional Runtime Platform Restrictions Authenticate Pointers Enable Read-only Platform Memory The following options were disabled by default: Memory Safety Enable Hardware Memory Tagging Memory Tag Pure Data Prevent Receiving Tagged Memory Enable Soft Mode for Memory Tagging Should I enable these options? Is there anything I should consider disabling?
3
0
321
Feb ’26
Checksum of an ipa file
I am curious as to know if i calculate the checksum of an ipa file and upload the same to app store, and then after installing the app on my device, if i extract the ipa file and compare the checksum will it match? or will it vary from device to device, because of bitcode and app thinning slicing? Some banks have been showing ipa file checksums on their websites, and even inside their apps and showing messages like checksum matches! i was just curious as to know how would one go about validating this!? Or is this even possible, what about the checksum of the executable at runtime? Can we check this? will it match?
1
0
169
Feb ’26
iOS mTLS Client Certificate Authentication Fails in TestFlight with Error -25303
iOS mTLS Client Certificate Authentication Fails in TestFlight with Error -25303 Problem I'm building an iOS app that uses mTLS (client certificates received from server at runtime). Storing SecCertificate to keychain fails with error -25303 in both development and TestFlight builds, preventing SecIdentity creation needed for URLSession authentication. Environment: iOS 18.2, iPad Pro, TestFlight internal testing, keychain-access-groups properly configured Diagnostic Results Testing keychain operations shows an interesting pattern: ✅ Generic Password - Works: let addQuery: [CFString: Any] = [ kSecClass: kSecClassGenericPassword, kSecAttrAccount: "test", kSecValueData: "password".data(using: .utf8)! ] SecItemAdd(addQuery as CFDictionary, nil) // Returns: 0 (success) ✅ SecKey - Works: let addKeyQuery: [CFString: Any] = [ kSecClass: kSecClassKey, kSecValueRef: privateKey, kSecAttrApplicationTag: tag ] SecItemAdd(addKeyQuery as CFDictionary, nil) // Returns: 0 (success) ❌ SecCertificate - Fails: let addCertQuery: [CFString: Any] = [ kSecClass: kSecClassCertificate, kSecValueRef: certificate, // Created from server-provided PEM kSecAttrApplicationTag: tag ] SecItemAdd(addCertQuery as CFDictionary, nil) // Returns: -25303 Code Context Attempting to create SecIdentity for mTLS: private func createIdentity(fromCert certPEM: String, key keyPEM: String) throws -> SecIdentity { // 1. Parse PEM to DER and create SecCertificate - succeeds guard let certData = extractPEMData(from: certPEM, type: "CERTIFICATE"), let certificate = SecCertificateCreateWithData(nil, certData as CFData) else { throw CertificateError.invalidCertificate } // 2. Parse PEM key and create SecKey - succeeds guard let keyData = extractPEMData(from: keyPEM, type: "PRIVATE KEY"), let privateKey = SecKeyCreateWithData(keyData as CFData, attrs as CFDictionary, &error) else { throw CertificateError.invalidKey } // 3. Add key to keychain - SUCCEEDS (errSecSuccess) let tempTag = UUID().uuidString.data(using: .utf8)! SecItemAdd([ kSecClass: kSecClassKey, kSecValueRef: privateKey, kSecAttrApplicationTag: tempTag ] as CFDictionary, nil) // ✅ Works // 4. Add certificate to keychain - FAILS (-25303) let status = SecItemAdd([ kSecClass: kSecClassCertificate, kSecValueRef: certificate, kSecAttrApplicationTag: tempTag ] as CFDictionary, nil) // ❌ Fails with -25303 guard status == errSecSuccess else { throw CertificateError.keychainError(status) } // 5. Would query for SecIdentity (never reached) // ... } Network Behavior When mTLS fails, console shows: Connection: asked for TLS Client Certificates Connection: received response for client certificates (-1 elements) Connection: providing TLS Client Identity (-1 elements) Task received response, status 403 The -1 elements indicates no certificates were provided. Entitlements <key>keychain-access-groups</key> <array> <string>$(AppIdentifierPrefix)com.ellin.tshios</string> </array> Keychain Sharing capability is enabled. What I've Tried Both kSecValueRef and kSecValueData approaches - same error Various kSecAttrAccessible values - same error Different keychain access groups - same error TestFlight build (vs dev build) - same error PKCS#12 creation - requires complex ASN.1/DER encoding, no iOS API Questions Is error -25303 expected when adding SecCertificate in development/TestFlight builds? Will App Store distribution resolve this? Or is there a fundamental limitation? Why does SecKey succeed but SecCertificate fails with identical entitlements? Is there an alternative to create SecIdentity without keychain access? Constraints Certificates come from server at runtime (cannot bundle) Need SecIdentity for URLSession client certificate authentication Server provides PEM format certificates Tested on: Simulator (dev), iPad Pro (dev), iPad Pro (TestFlight) - all fail Any insights appreciated - specifically whether this is a provisioning profile limitation that App Store distribution would resolve.
3
0
276
Feb ’26
SecItem: Fundamentals
I regularly help developers with keychain problems, both here on DevForums and for my Day Job™ in DTS. Many of these problems are caused by a fundamental misunderstanding of how the keychain works. This post is my attempt to explain that. I wrote it primarily so that Future Quinn™ can direct folks here rather than explain everything from scratch (-: If you have questions or comments about any of this, put them in a new thread and apply the Security tag so that I see it. Share and Enjoy — Quinn “The Eskimo!” @ Developer Technical Support @ Apple let myEmail = "eskimo" + "1" + "@" + "apple.com" SecItem: Fundamentals or How I Learned to Stop Worrying and Love the SecItem API The SecItem API seems very simple. After all, it only has four function calls, how hard can it be? In reality, things are not that easy. Various factors contribute to making this API much trickier than it might seem at first glance. This post explains the fundamental underpinnings of the keychain. For information about specific issues, see its companion post, SecItem: Pitfalls and Best Practices. Keychain Documentation Your basic starting point should be Keychain Items. If your code runs on the Mac, also read TN3137 On Mac keychain APIs and implementations. Read the doc comments in <Security/SecItem.h>. In many cases those doc comments contain critical tidbits. When you read keychain documentation [1] and doc comments, keep in mind that statements specific to iOS typically apply to iPadOS, tvOS, and watchOS as well (r. 102786959). Also, they typically apply to macOS when you target the data protection keychain. Conversely, statements specific to macOS may not apply when you target the data protection keychain. [1] Except TN3137, which is very clear about this (-: Caveat Mac Developer macOS supports two different keychain implementations: the original file-based keychain and the iOS-style data protection keychain. IMPORTANT If you’re able to use the data protection keychain, do so. It’ll make your life easier. See the Careful With that Shim, Mac Developer section of SecItem: Pitfalls and Best Practices for more about this. TN3137 On Mac keychain APIs and implementations explains this distinction. It also says: The file-based keychain is on the road to deprecation. This is talking about the implementation, not any specific API. The SecItem API can’t be deprecated because it works with both the data protection keychain and the file-based keychain. However, Apple has deprecated many APIs that are specific to the file-based keychain, for example, SecKeychainCreate. TN3137 also notes that some programs, like launchd daemons, can’t use the file-based keychain. If you’re working on such a program then you don’t have to worry about the deprecation of these file-based keychain APIs. You’re already stuck with the file-based keychain implementation, so using a deprecated file-based keychain API doesn’t make things worse. The Four Freedoms^H^H^H^H^H^H^H^H Functions The SecItem API contains just four functions: SecItemAdd(_:_:) SecItemCopyMatching(_:_:) SecItemUpdate(_:_:) SecItemDelete(_:) These directly map to standard SQL database operations: SecItemAdd(_:_:) maps to INSERT. SecItemCopyMatching(_:_:) maps to SELECT. SecItemUpdate(_:_:) maps to UPDATE. SecItemDelete(_:) maps to DELETE. You can think of each keychain item class (generic password, certificate, and so on) as a separate SQL table within the database. The rows of that table are the individual keychain items for that class and the columns are the attributes of those items. Note Except for the digital identity class, kSecClassIdentity, where the values are split across the certificate and key tables. See Digital Identities Aren’t Real in SecItem: Pitfalls and Best Practices. This is not an accident. The data protection keychain is actually implemented as an SQLite database. If you’re curious about its structure, examine it on the Mac by pointing your favourite SQLite inspection tool — for example, the sqlite3 command-line tool — at the keychain database in ~/Library/Keychains/UUU/keychain-2.db, where UUU is a UUID. WARNING Do not depend on the location and structure of this file. These have changed in the past and are likely to change again in the future. If you embed knowledge of them into a shipping product, it’s likely that your product will have binary compatibility problems at some point in the future. The only reason I’m mentioning them here is because I find it helpful to poke around in the file to get a better understanding of how the API works. For information about which attributes are supported by each keychain item class — that is, what columns are in each table — see the Note box at the top of Item Attribute Keys and Values. Alternatively, look at the Attribute Key Constants doc comment in <Security/SecItem.h>. Uniqueness A critical part of the keychain model is uniqueness. How does the keychain determine if item A is the same as item B? It turns out that this is class dependent. For each keychain item class there is a set of attributes that form the uniqueness constraint for items of that class. That is, if you try to add item A where all of its attributes are the same as item B, the add fails with errSecDuplicateItem. For more information, see the errSecDuplicateItem page. It has lists of attributes that make up this uniqueness constraint, one for each class. These uniqueness constraints are a major source of confusion, as discussed in the Queries and the Uniqueness Constraints section of SecItem: Pitfalls and Best Practices. Parameter Blocks Understanding The SecItem API is a classic ‘parameter block’ API. All of its inputs are dictionaries, and you have to know which properties to set in each dictionary to achieve your desired result. Likewise for when you read properties in output dictionaries. There are five different property groups: The item class property, kSecClass, determines the class of item you’re operating on: kSecClassGenericPassword, kSecClassCertificate, and so on. The item attribute properties, like kSecAttrAccessGroup, map directly to keychain item attributes. The search properties, like kSecMatchLimit, control how the system runs a query. The return type properties, like kSecReturnAttributes, determine what values the query returns. The value type properties, like kSecValueRef perform multiple duties, as explained below. There are other properties that perform a variety of specific functions. For example, kSecUseDataProtectionKeychain tells macOS to use the data protection keychain instead of the file-based keychain. These properties are hard to describe in general; for the details, see the documentation for each such property. Inputs Each of the four SecItem functions take dictionary input parameters of the same type, CFDictionary, but these dictionaries are not the same. Different dictionaries support different property groups: The first parameter of SecItemAdd(_:_:) is an add dictionary. It supports all property groups except the search properties. The first parameter of SecItemCopyMatching(_:_:) is a query and return dictionary. It supports all property groups. The first parameter of SecItemUpdate(_:_:) is a pure query dictionary. It supports all property groups except the return type properties. Likewise for the only parameter of SecItemDelete(_:). The second parameter of SecItemUpdate(_:_:) is an update dictionary. It supports the item attribute and value type property groups. Outputs Two of the SecItem functions, SecItemAdd(_:_:) and SecItemCopyMatching(_:_:), return values. These output parameters are of type CFTypeRef because the type of value you get back depends on the return type properties you supply in the input dictionary: If you supply a single return type property, except kSecReturnAttributes, you get back a value appropriate for that return type. If you supply multiple return type properties or kSecReturnAttributes, you get back a dictionary. This supports the item attribute and value type property groups. To get a non-attribute value from this dictionary, use the value type property that corresponds to its return type property. For example, if you set kSecReturnPersistentRef in the input dictionary, use kSecValuePersistentRef to get the persistent reference from the output dictionary. In the single item case, the type of value you get back depends on the return type property and the keychain item class: For kSecReturnData you get back the keychain item’s data. This makes most sense for password items, where the data holds the password. It also works for certificate items, where you get back the DER-encoded certificate. Using this for key items is kinda sketchy. If you want to export a key, called SecKeyCopyExternalRepresentation. Using this for digital identity items is nonsensical. For kSecReturnRef you get back an object reference. This only works for keychain item classes that have an object representation, namely certificates, keys, and digital identities. You get back a SecCertificate, a SecKey, or a SecIdentity, respectively. For kSecReturnPersistentRef you get back a data value that holds the persistent reference. Value Type Subtleties There are three properties in the value type property group: kSecValueData kSecValueRef kSecValuePersistentRef Their semantics vary based on the dictionary type. For kSecValueData: In an add dictionary, this is the value of the item to add. For example, when adding a generic password item (kSecClassGenericPassword), the value of this key is a Data value containing the password. This is not supported in a query dictionary. In an update dictionary, this is the new value for the item. For kSecValueRef: In add and query dictionaries, the system infers the class property and attribute properties from the supplied object. For example, if you supply a certificate object (SecCertificate, created using SecCertificateCreateWithData), the system will infer a kSecClass value of kSecClassCertificate and various attribute values, like kSecAttrSerialNumber, from that certificate object. This is not supported in an update dictionary. For kSecValuePersistentRef: For query dictionaries, this uniquely identifies the item to operate on. This is not supported in add and update dictionaries. Revision History 2025-05-28 Expanded the Caveat Mac Developer section to cover some subtleties associated with the deprecation of the file-based keychain. 2023-09-12 Fixed various bugs in the revision history. Added a paragraph explaining how to determine which attributes are supported by each keychain item class. 2023-02-22 Made minor editorial changes. 2023-01-28 First posted.
Replies
0
Boosts
0
Views
4.4k
Activity
May ’25
Entitlement values for the Enhanced Security and the Additional Runtime Platform Restrictions
I recently turned on the enhanced security options for my macOS app in Xcode 26.0.1 by adding the Enhanced Security capability in the Signing and Capabilities tab. Then, Xcode adds the following key-value sets (with some other key-values) to my app's entitlements file. <key>com.apple.security.hardened-process.enhanced-security-version</key> <integer>1</integer> <key>com.apple.security.hardened-process.platform-restrictions</key> <integer>2</integer> These values appear following the documentation about the enhanced security feature (Enabling enhanced security for your app) and the app works without any issues. However, when I submitted a new version to the Mac App Store, my submission was rejected, and I received the following message from the App Review team via the App Store Connect. Guideline 2.4.5(i) - Performance Your app incorrectly implements sandboxing, or it contains one or more entitlements with invalid values. Please review the included entitlements and sandboxing documentation and resolve this issue before resubmitting a new binary. Entitlement "com.apple.security.hardened-process.enhanced-security-version" value must be boolean and true. Entitlement "com.apple.security.hardened-process.platform-restrictions" value must be boolean and true. When I changed those values directly in the entitlements file based on this message, the app appears to still work. However, these settings are against the description in the documentation I mentioned above and against the settings Xcode inserted after changing the GUI setting view. So, my question is, which settings are actually correct to enable the Enhanced Security and the Additional Runtime Platform Restrictions?
Replies
5
Boosts
0
Views
1.1k
Activity
14m
account privacy
i want to know if some one is using this to hack me
Replies
0
Boosts
0
Views
11
Activity
2h
App ID Prefix Change and Keychain Access
DTS regularly receives questions about how to preserve keychain items across an App ID change, and so I thought I’d post a comprehensive answer here for the benefit of all. If you have any questions or comments, please start a new thread here on the forums. Put it in the Privacy & Security > General subtopic and tag it with Security. Share and Enjoy — Quinn “The Eskimo!” @ Developer Technical Support @ Apple let myEmail = "eskimo" + "1" + "@" + "apple.com" App ID Prefix Change and Keychain Access The list of keychain access groups your app can access is determined by three entitlements. For the details, see Sharing Access to Keychain Items Among a Collection of Apps. If your app changes its App ID prefix, this list changes and you’re likely to lose access to existing keychain items. This situation crops up under two circumstances: When you migrate your app from using a unique App ID prefix to using your Team ID as its App ID prefix. When you transfer your app to another team. In both cases you have to plan carefully for this change. If you only learn about the problem after you’ve made the change, consider undoing the change to give you time to come up with a plan before continuing. Note On macOS, the information in this post only applies to the data protection keychain. For more information about the subtleties of the keychain on macOS, see On Mac Keychains. For more about App ID prefix changes, see Technote 2311 Managing Multiple App ID Prefixes and QA1726 Resolving the Potential Loss of Keychain Access warning. Migrate From a Unique App ID Prefix to Your Team ID Historically each app was assigned its own App ID prefix. This is no longer the case. Best practice is for apps to use their Team ID as their App ID prefix. This enables multiple neat features, including keychain item sharing and pasteboard sharing. If you have an app that uses a unique App ID prefix, consider migrating it to use your Team ID. This is a good thing in general, as long as you manage the migration process carefully. Your app’s keychain access group list is built from three entitlements: keychain-access-groups — For more on this, see Keychain Access Groups Entitlement. application-identifier (com.apple.application-identifier on macOS) com.apple.security.application-groups — For more on this, see App Groups Entitlement. Keycahin access groups from the third bullet are call app group identified keychain access groups, or AGI keychain access groups for short. IMPORTANT A macOS app can only use an AGI keychain access group if all of its entitlement claims are validated by a provisioning profile. See App Groups: macOS vs iOS: Working Towards Harmony for more about this concept. Keychain access groups from the first two bullets depend on the App ID prefix. If that changes, you lose access to any keychain items in those groups. WARNING Think carefully before using the keychain to store secrets that are the only way to access irreplaceable user data. While the keychain is very reliable, there are situations where a keychain item can be lost and it’s bad if it takes the user’s data with it. In some cases losing access to keychain items is not a big deal. For example, if your app uses the keychain to manage a single login credential, losing that is likely to be acceptable. The user can recover by logging in again. In other cases losing access to keychain items is unacceptable. For example, your app might manage access to dozens of different servers, each with unique login credentials. Your users will be grumpy if you require them to log in to all those servers again. In such situations you must carefully plan your migration. The key thing to understand is that an app group is tied to your team, not your App ID prefix, and thus your app retains access to AGI keychain access groups across an App ID prefix change. This suggests the following approach: Release a version of your app that moves keychain items from other keychain access groups to an AGI keychain access group. Give your users time to update to this new version, run it, and so move their keychain items. When you’re confident that the bulk of your users have done this, change your App ID prefix. The approach has one obvious caveat: It’s hard to judge how long to wait at step 2. Transfer Your App to Another Team Historically there was no supported way to maintain access to keychain items across an app transfer. That’s no longer the case, but you must still plan the transfer carefully. The overall approach is: Identify an app group ID to transfer. This could be an existing app group ID, but in many cases you’ll want to register a new app group ID solely for this purpose. Use the old team (the transferor) to release a version of your app that moves keychain items from other keychain access groups to the AGI keychain access group for this app group ID. Give your users time to update to this new version, run it, and so move their keychain items. When you’re confident that the bulk of your users have done this, initiate the app transfer. Once that’s complete, transfer the app group ID you selected in step 1. See App Store Connect Help > Transfer an app > Overview of app transfer > Apps using App Groups. Publish an update to your app from the new team (the transferee). When a user installs this version, it will have access to your app group, and hence your keychain items. WARNING Once you transfer the app group, the old team won’t be able to publish a new version of any app that uses this app group. That makes step 1 in the process critical. If you have an existing app group that’s used solely by the app being transferred — for example, an app group that you use to share state between the app and its app extensions — then choosing that app group ID makes sense. On the other hand, choosing the ID of an app group that’s share between this app and some unrelated app, one that’s not being transferred, would be bad, because any updates to that other app will lose access to the app group. There are some other significant caveats: The process doesn’t work for Mac apps because Mac apps that have ever used an app group can’t be transferred. See App Store Connect Help > Transfer an app > App transfer criteria. If and when that changes, you’ll need to choose an iOS-style app group ID for your AGI keychain access group. For more about the difference between iOS- and macOS-style app group IDs, see App Groups: macOS vs iOS: Working Towards Harmony. The current transfer process of app groups exposes a small window where some other team can ‘steal’ your app group ID. We have a bug on file to improve that process (r. 171616887). The process works best when transferring between two teams that are both under the control of the same entity. If that’s not the case, take steps to ensure that the old team transfers the app group in step 5. When you submit the app from the new team (step 6), App Store Connect will warn you about a potential loss of keychain access. That warning is talking about keychain items in normal keychain access groups. Items in an AGI keychain access group will still be accessible as long as you transfer the app group. Alternative Approaches for App Transfer In addition to the technique described in the previous section, there are a some alternative approaches you should at consider: Do nothing Do not transfer your app Get creative Do Nothing In this case the user loses all the secrets that your app stored in the keychain. This may be acceptable for certain apps. For example, if your app uses the keychain to manage a single login credential, losing that is likely to be acceptable. The user can recover by logging in again. Do Not Transfer Another option is to not transfer your app. Instead, ship a new version of the app from the new team and have the old app recommend that the user upgrade. There are a number of advantages to this approach. The first is that there’s absolutely no risk of losing any user data. The two apps are completely independent. The second advantage is that the user can install both apps on their device at the same time. This opens up a variety of potential migration paths. For example, you might ship an update to the old app with an export feature that saves the user’s state, including their secrets, to a suitably encrypted file, and then match that with an import facility on the new app. Finally, this approach offers flexible timing. The user can complete their migration at their leisure. However, there are a bunch of clouds to go with these silver linings: Your users might never migrate to the new app. If this is a paid app, or an app with in-app purchase, the user will have to buy things again. You lose the original app’s history, ratings, reviews, and so on. Get Creative Finally, you could attempt something creative. For example, you might: Publish a new version of the app that supports exporting the user’s state, including the secrets. Tell your users to do this, with a deadline. Transfer the app and then, when the deadline expires, publish the new version with an import feature. Frankly, this isn’t very practical. The problem is with step 2: There’s no good way to get all your users to do the export, and if they don’t do it before the deadline there’s no way to do it after. Revision History 2026-03-31 Rewrote the Transfer Your App to Another Team section to describe a new approach for preserving access to keychain items across app transfers. Moved the previous discussion into a new Alternative Approaches for App Transfer section. Clarified that a macOS program can now use an app group as a keychain access group as long as its entitlements are validated. Made numerous editorial changes. 2022-05-17 First posted.
Replies
0
Boosts
0
Views
8.5k
Activity
1d
Exploring Secure Enclave–backed biometric authorization between macOS and iPhone using public APIs (FaceBridge prototype)
Hi everyone, I’ve been working on an experimental prototype called FaceBridge that explores whether Secure Enclave–backed biometric authorization can be delegated between macOS and iPhone using only public Apple APIs. The goal of the project was to better understand the architectural boundaries of cross-device trust and approval flows that resemble Apple’s built-in Touch ID / Continuity authorization experiences. FaceBridge implements a local authorization pipeline where: macOS generates a signed authorization request the request is delivered to a trusted nearby iPhone over BLE / Network framework the iPhone verifies sender identity Face ID approval is requested using LocalAuthentication the iPhone signs the approval response using Secure Enclave–backed keys macOS validates the response and unlocks a protected action Security properties currently implemented: • Secure Enclave–backed signing identities per device • cryptographic device pairing and trust persistence • replay protection using nonce + timestamp binding • structured authorization request/response envelopes • signed responder identity verification • trusted-device registry model • local encrypted transport over BLE and local network This is intentionally not attempting to intercept or replace system-level Touch ID dialogs (App Store installs, Keychain prompts, loginwindow, etc.), but instead explores what is possible within application-level authorization boundaries using public APIs only. The project is open source: https://github.com/wesleysfavarin/facebridge Technical architecture write-up: https://medium.com/@wesleysfavarin/facebridge I’m particularly interested in feedback around: • recommended Secure Enclave identity lifecycle patterns • best practices for cross-device trust persistence • LocalAuthentication usage in delegated approval scenarios • whether similar authorization models are expected to become more formally supported across Apple platforms in the future Thanks in advance for any guidance or suggestions.
Replies
1
Boosts
0
Views
65
Activity
1d
Endpoint Security entitlement for open-source behavioral monitoring tool
Hi, I’m building a macOS tool that analyzes process behavior to detect autonomous / AI-like activity locally (process trees, file access patterns, and network usage). The system is fully user-space and runs locally in real time. I’m planning to use the Endpoint Security Framework for process and file event monitoring. This is an open-source project (non-enterprise), developed by a solo developer. My question: What are the realistic chances of getting Endpoint Security entitlements approved for this type of project? Are there specific requirements or common reasons for rejection I should be aware of? Thanks, sivan-rnd
Replies
2
Boosts
0
Views
130
Activity
5d
MFA MacOS At ScreenSaver (Lock Screen).
Hi , I did The MFA(2FA) of Email OTP For MacOS Login Screen using, Authorization Plugin, Using This git hub project. It is working For Login Screen , Im trying to Add The Same plugin for LockScreen but it is not working at lock Screen , Below is the reffrense theard For The issue , https://developer.apple.com/forums/thread/127614, please Share The Code that should Present the NSwindow at Screen Saver (Lock Screen) MacOS .
Replies
3
Boosts
0
Views
973
Activity
5d
Enterprise Install for a TLS Inspection proxy
I’m working on a product that includes TLS inspection capability. TLS inspection using a local MitM requires installing a trusted root certificate which is then used to create masquerade certificates to intercept and forward TLS traffic through the proxy. For manual installation the end user is required to authenticate as an administrator to modify the trust settings on our internal CA’s root certificate. My question concerns the options for enterprise deployment using an MDM. We want the generated root certificate to be unique to each endpoint so that if a private key is compromised it can’t be used to intercept traffic anywhere else. We can install a “certificate trust” configuration profile from the MDM but this requires a base64 encoded string of the root certificate. In effect the MDM needs to obtain the certificate from the endpoint and then send it back in the form of a configuration profile. I’m not aware that MDMs like Jamf can be configured to do this directly so we’re looking for any other mechanism to have macOS trust a locally generated certificate via MDM based on some non endpoint-unique criteria? One option might be to use an external CA with a trusted certificate to sign an intermediate endpoint certificate but this creates a significant risk if the external trusted certificate were ever compromised. Is this a common industry practice? So my question remains is there a better way to trust our per endpoint root certificate via MDM without needing to install a unique per endpoint configuration profile?
Replies
6
Boosts
0
Views
785
Activity
1w
Securing XPC Daemon Communication from Authorization Plugin
I'm working on securing communication between an Authorization Plugin and an XPC daemon, and I’d appreciate some guidance on best practices and troubleshooting. The current design which, I’ve implemented a custom Authorization Plugin for step-up authentication, which is loaded by Authorization Services at the loginwindow (inside SecurityAgent). This plugin acts as an XPC client and connects to a custom XPC daemon. Setup Details 1. XPC Daemon Runs as root (LaunchDaemon) Not sandboxed (my understanding is that root daemons typically don’t run sandboxed—please correct me if this is wrong) Mach service: com.roboInc.AuthXpcDaemon Bundle identifier: com.roboInc.OfflineAuthXpcDaemon 2. Authorization Plugin Bundle identifier: com.roboInc.AuthPlugin Loaded by SecurityAgent during login 3. Code Signing Both plugin and daemon are signed using a development certificate What I’m Trying to Achieve I want to secure the XPC communication so that: The daemon only accepts connections from trusted clients The plugin only connects to the legitimate daemon Communication is protected against unauthorized access The Issue I'm facing I attempted to validate code signatures using: SecRequirementCreateWithString SecCodeCopyGuestWithAttributes SecCodeCheckValidity However, validation consistently fails with: -67050 (errSecCSReqFailed) Could you please help here What is the recommended way to securely authenticate an Authorization Plugin (running inside SecurityAgent) to a privileged XPC daemon? Since the plugin runs inside SecurityAgent, how can the daemon reliably distinguish my plugin from other plugins? What is the correct approach to building a SecRequirement in this scenario? Any guidance, examples, or pointers would be greatly appreciated. Thanks in advance!
Replies
6
Boosts
0
Views
214
Activity
1w
Unlock with Touch ID suggested despite system.login.screensaver being configured with authenticate-session-owner rule
Hello, I’m working on a security agent plugin for Mac. The plugin provides a mechanism with custom UI via SFAuthorizationPluginView and a privileged mechanism with the business logic. The plugin needs to support unlocking the device, so I changed the authorize right to invoke my agent: <?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>class</key> <string>evaluate-mechanisms</string> <key>created</key> <real>731355374.33196402</real> <key>mechanisms</key> <array> <string>FooBar:loginUI</string> <string>builtin:reset-password,privileged</string> <string>FooBar:authenticate,privileged</string> <string>builtin:authenticate,privileged</string> </array> <key>modified</key> <real>795624943.31730103</real> <key>shared</key> <true/> <key>tries</key> <integer>10000</integer> <key>version</key> <integer>1</integer> </dict> </plist> I also changed the system.login.screensaver right to use authorize-session-owner: <?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>class</key> <string>rule</string> <key>comment</key> <string>The owner or any administrator can unlock the screensaver, set rule to "authenticate-session-owner-or-admin" to enable SecurityAgent.</string> <key>created</key> <real>731355374.33196402</real> <key>modified</key> <real>795624943.32567298</real> <key>rule</key> <array> <string>authenticate-session-owner</string> </array> <key>version</key> <integer>1</integer> </dict> </plist> I also set screenUnlockMode to 2, as was suggested in this thread: macOS Sonoma Lock Screen with SFAutorizationPluginView is not hiding the macOS desktop. In the Display Authorization plugin at screensaver unlock thread, Quinn said that authorization plugins are not able to use Touch ID. However, on a MacBook with at touch bar, when I lock the screen, close the lid, and then open it, the touch bar invites me to unlock with Touch ID. If I choose to do so, the screen unlocks and I can interact with the computer, but the plugin UI stays on screen and never goes away, and after about 30 seconds the screen locks back. I can reliably reproduce it on a MacBook Pro with M1 chip running Tahoe 26.1. Is this a known macOS bug? What can I do about it? Ideally, I would like to be able to integrate Touch ID into my plugin, but since that seems to be impossible, the next best thing would be to reliably turn it off completely. Thanks in advance.
Replies
2
Boosts
0
Views
364
Activity
1w
How to store certificate to `com.apple.token` keychain access group.
I’m developing an iOS application and aiming to install a PKCS#12 (.p12) certificate into the com.apple.token keychain access group so that Microsoft Edge for iOS, managed via MDM/Intune, can read and use it for client certificate authentication. I’m attempting to save to the com.apple.token keychain access group, but I’m getting error -34018 (errSecMissingEntitlement) and the item isn’t saved. This occurs on both a physical device and the simulator. I’m using SecItemAdd from the Security framework to store it. Is this the correct approach? https://developer.apple.com/documentation/security/secitemadd(::) I have added com.apple.token to Keychain Sharing. I have also added com.apple.token to the app’s entitlements. Here is the code I’m using to observe this behavior: public static func installToTokenGroup(p12Data: Data, password: String) throws -> SecIdentity { // First, import the P12 to get the identity let options: [String: Any] = [ kSecImportExportPassphrase as String: password ] var items: CFArray? let importStatus = SecPKCS12Import(p12Data as CFData, options as CFDictionary, &items) guard importStatus == errSecSuccess, let array = items as? [[String: Any]], let dict = array.first else { throw NSError(domain: NSOSStatusErrorDomain, code: Int(importStatus), userInfo: [NSLocalizedDescriptionKey: "Failed to import P12: \(importStatus)"]) } let identity = dict[kSecImportItemIdentity as String] as! SecIdentity let addQuery: [String: Any] = [ kSecClass as String: kSecClassIdentity, kSecValueRef as String: identity, kSecAttrLabel as String: kSecAttrAccessGroupToken, kSecAttrAccessible as String: kSecAttrAccessibleAfterFirstUnlock, kSecAttrAccessGroup as String: kSecAttrAccessGroupToken ] let status = SecItemAdd(addQuery as CFDictionary, nil) if status != errSecSuccess && status != errSecDuplicateItem { throw NSError(domain: NSOSStatusErrorDomain, code: Int(status), userInfo: [NSLocalizedDescriptionKey: "Failed to add to token group: \(status)"]) } return identity }
Replies
1
Boosts
0
Views
223
Activity
1w
SecureTransport PSK Support for TLS
We have successfully deployed our Qt C++ application on Windows and Android using OpenSSL with TLS Pre-Shared Key (PSK) authentication to connect to our servers. However, I understand that apps submitted to the App Store must use SecureTransport as the TLS backend on iOS. My understandiunig is that SecureTransport does not support PSK ciphersuites, which is critical for our security architecture. Questions: Does SecureTransport support TLS PSK authentication, or are there plans to add this feature? If PSK is not supported, what is Apple's recommended alternative for applications that require PSK-based authentication? Is there an approved exception process that would allow me to use OpenSSL for TLS connections on iOS while still complying with App Store guidelines? The application requires PSK for secure communication with our infrastructure, and we need guidance on how to maintain feature parity across all platforms while meeting App Store requirements
Replies
2
Boosts
0
Views
73
Activity
2w
The SecKeyCreateSignature method always prompts for the current user's login password.
I downloaded a P12 file (containing a private key) from the company server, and retrieved the private key from this P12 file using a password : private func loadPrivateKeyFromPKCS12(path: String, password: String) throws -> SecKey? { let p12Data: Data do { p12Data = try Data(contentsOf: fileURL) } catch let readError { ... } let options: [CFString: Any] = [ kSecImportExportPassphrase: password as CFString ] var items: CFArray? let status = SecPKCS12Import(p12Data as CFData, options as CFDictionary, &items) guard status == errSecSuccess else { throw exception } var privateKey: SecKey? let idd = identity as! SecIdentity let _ = SecIdentityCopyPrivateKey(idd, &privateKey) return privateKey } However, when I use this private key to call SecKeyCreateSignature for data signing, a dialog box always pops up to ask user to input the Mac admin password. What confuses me is that this private key is clearly stored in the local P12 file, and there should be no access to the keychain involved in this process. Why does the system still require the user's login password for signing? Is it possible to perform silent signing (without the system dialog popping up) in this scenario?
Replies
1
Boosts
0
Views
79
Activity
2w
Authorizing a process to access a Private Key pushed via MDM
I am developing a macOS system service (standalone binary running as a LaunchDaemon) that requires the ability to sign data using a private key which will be deployed via MDM. The Setup: Deployment: A .mobileconfig pushes a PKCS12 identity to the System Keychain. Security Requirement: For compliance and security reasons, we cannot set AllowAllAppsAccess to <true/>. The key must remain restricted. The Goal: I need to use the private key from the identity to be able to sign the data The Problem: The Certificate Payload does not support a TrustedApplications or AccessControl array to pre-authorize binary paths. As a result, when the process tries to use the private key for signing (SecKeyCreateSignature), it prompts the user to allow this operation which creates a disruption and is not desired. What i've tried so far: Manually adding my process to the key's ACL in keychain access obviously works and prevents any prompts but this is not an "automatable" solution. Using security tool in a script to attempt to modify the ACL in an automated way, but that also asks user for password and is not seamless. The Question: Is there a documented, MDM-compatible way to inject a specific binary path into the ACL of a private key? If not, is there a better way to achieve the end goal?
Replies
1
Boosts
0
Views
217
Activity
2w
QWAC validation
Hello there, Starting from iOS 18.4, support was included for QWAC Validation and QCStatements. Using the official QWAC Validator at: https://eidas.ec.europa.eu/efda/qwac-validation-tool I was able to check that the domain "eidas.ec.europa.eu" has a valid QWAC certificate. However, when trying to obtain the same result using the new API, I do not obtain the same result. Here is my sample playground code: import Foundation import Security import PlaygroundSupport PlaygroundPage.current.needsIndefiniteExecution = true @MainActor class CertificateFetcher: NSObject, URLSessionDelegate { private let url: URL init(url: URL) { self.url = url super.init() } func start() { let session = URLSession(configuration: .ephemeral, delegate: self, delegateQueue: nil) let task = session.dataTask(with: url) { data, response, error in if let error = error { print("Error during request: \(error)") } else { print("Request completed.") } } task.resume() } nonisolated func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -&gt; Void) { guard let trust = challenge.protectionSpace.serverTrust else { completionHandler(.cancelAuthenticationChallenge, nil) return } if let certificates = SecTrustCopyCertificateChain(trust) as? [SecCertificate] { self.checkQWAC(certificates: certificates) } let credential = URLCredential(trust: trust) completionHandler(.useCredential, credential) } nonisolated func checkQWAC(certificates: [SecCertificate]) { let policy = SecPolicyCreateSSL(true, nil) var trust: SecTrust? guard SecTrustCreateWithCertificates(certificates as CFArray, policy, &amp;trust) == noErr, let trust else { print("Unable to create SecTrust") return } var error: CFError? guard SecTrustEvaluateWithError(trust, &amp;error) else { print("Trust evaluation failed") return } guard let result = SecTrustCopyResult(trust) as? [String : Any] else { print("No result dictionary") return } let qwacStatus = result[kSecTrustQWACValidation as String] let qcStatements = result[kSecTrustQCStatements as String] print("QWAC Status: \(String(describing: qwacStatus))") print("QC Statements: \(String(describing: qcStatements))") } } let url = URL(string: "https://eidas.ec.europa.eu/")! let fetcher = CertificateFetcher(url: url) fetcher.start() Which prints: QWAC Status: nil QC Statements: nil Request completed. Am I making a mistake while using the Security framework? I would greatly appreciate any help or guidance you can provide.
Replies
6
Boosts
0
Views
281
Activity
3w
SecurityAgent taking focus for plugin in macOS 26.1
We have a custom SecurityAgentPlugin that is triggered by multiple authorizationdb entries. Some customers report that the SecurityAgent process takes window focus even though no UI or windows are displayed. Our plugin explicitly ignores the _securityAgent user and does not show any UI for that user. However, in macOS 26.1, it appears that the plugin still causes the SecurityAgent to take focus as soon as it is triggered. Is this a change in macOS 26.1 or a bug? Can we do anything to prevent "focus stealing"?
Replies
27
Boosts
3
Views
4.7k
Activity
3w
`cp` ( & friends ) silent loss of extended attributes & file flags
Since the introduction of the siblings / and /System/Volumes/Data architecture, some very basic, critical commands seems to have a broken behaviour ( cp, rsync, tar, cpio…). As an example, ditto which was introduced more than 10 years ago to integrate correctly all the peculiarity of HFS Apple filesystem as compared to the UFS Unix filesystem is not behaving correctly. For example, from man ditto: --rsrc Preserve resource forks and HFS meta-data. ditto will store this data in Carbon-compatible ._ AppleDouble files on filesystems that do not natively support resource forks. As of Mac OS X 10.4, --rsrc is default behavior. [...] --extattr Preserve extended attributes (requires --rsrc). As of Mac OS X 10.5, --extattr is the default. and nonetheless: # ls -@delO /private/var/db/ConfigurationProfiles/Store drwx------@ 5 root wheel datavault 160 Jan 20 2024 /private/var/db/ConfigurationProfiles/Store                            ********* com.apple.rootless 28 *************************** # mkdir tmp # ditto /private/var/db/ConfigurationProfiles tmp ditto: /Users/alice/Security/Admin/Apple/APFS/tmp/Settings: Operation not permitted ditto: /Users/alice/Security/Admin/Apple/APFS/tmp/Store: Operation not permitted # ls -@delO tmp/Store drwx------ 5 root wheel - 160 Aug 8 13:55 tmp/Store                            * # The extended attribute on copied directory Store is empty, the file flags are missing, not preserved as documented and as usual behaviour of ditto was since a long time ( macOS 10.5 ). cp, rsync, tar, cpio exhibit the same misbehaviour. But I was using ditto to be sure to avoid any incompatibility with the Apple FS propriaitary modifications. As a consequence, all backup scripts and applications are failing more or less silently, and provide corrupted copies of files or directories. ( I was here investigating why one of my security backup shell script was making corrupted backups, and only on macOS ). How to recover the standard behaviour --extattr working on modern macOS?
Replies
4
Boosts
0
Views
1.1k
Activity
Feb ’26
DTLS Handshake Fails When App Is in Background – Is This an iOS Limitation?
Hello, We are facing an issue with performing a DTLS handshake when our iOS application is in the background. Our app (Vocera Collaboration Suite – VCS) uses secure DTLS-encrypted communication for incoming VoIP calls. Problem Summary: When the app is in the background and a VoIP PushKit notification arrives, we attempt to establish a DTLS handshake over our existing socket. However, the handshake consistently fails unless the app is already in the foreground. Once the app is foregrounded, the same DTLS handshake logic succeeds immediately. Key Questions: Is performing a DTLS handshake while the app is in the background technically supported by iOS? Or is this an OS-level limitation by design? If not supported, what is the Apple-recommended alternative to establish secure DTLS communication for VoIP flows without bringing the app to the foreground? Any guidance or clarification from Apple engineers or anyone who has solved a similar problem would be greatly appreciated. Thank you.
Replies
5
Boosts
0
Views
344
Activity
Feb ’26
What should be enabled for Enhanced Security?
I am not very well versed in this area, so I would appreciate some guidance on what should be enabled or disabled. My app is an AppKit app. I have read the documentation and watched the video, but I find it hard to understand. When I added the Enhanced Security capability in Xcode, the following options were enabled automatically: Memory Safety Enable Enhanced Security Typed Allocator Runtime Protections Enable Additional Runtime Platform Restrictions Authenticate Pointers Enable Read-only Platform Memory The following options were disabled by default: Memory Safety Enable Hardware Memory Tagging Memory Tag Pure Data Prevent Receiving Tagged Memory Enable Soft Mode for Memory Tagging Should I enable these options? Is there anything I should consider disabling?
Replies
3
Boosts
0
Views
321
Activity
Feb ’26
Checksum of an ipa file
I am curious as to know if i calculate the checksum of an ipa file and upload the same to app store, and then after installing the app on my device, if i extract the ipa file and compare the checksum will it match? or will it vary from device to device, because of bitcode and app thinning slicing? Some banks have been showing ipa file checksums on their websites, and even inside their apps and showing messages like checksum matches! i was just curious as to know how would one go about validating this!? Or is this even possible, what about the checksum of the executable at runtime? Can we check this? will it match?
Replies
1
Boosts
0
Views
169
Activity
Feb ’26
iOS mTLS Client Certificate Authentication Fails in TestFlight with Error -25303
iOS mTLS Client Certificate Authentication Fails in TestFlight with Error -25303 Problem I'm building an iOS app that uses mTLS (client certificates received from server at runtime). Storing SecCertificate to keychain fails with error -25303 in both development and TestFlight builds, preventing SecIdentity creation needed for URLSession authentication. Environment: iOS 18.2, iPad Pro, TestFlight internal testing, keychain-access-groups properly configured Diagnostic Results Testing keychain operations shows an interesting pattern: ✅ Generic Password - Works: let addQuery: [CFString: Any] = [ kSecClass: kSecClassGenericPassword, kSecAttrAccount: "test", kSecValueData: "password".data(using: .utf8)! ] SecItemAdd(addQuery as CFDictionary, nil) // Returns: 0 (success) ✅ SecKey - Works: let addKeyQuery: [CFString: Any] = [ kSecClass: kSecClassKey, kSecValueRef: privateKey, kSecAttrApplicationTag: tag ] SecItemAdd(addKeyQuery as CFDictionary, nil) // Returns: 0 (success) ❌ SecCertificate - Fails: let addCertQuery: [CFString: Any] = [ kSecClass: kSecClassCertificate, kSecValueRef: certificate, // Created from server-provided PEM kSecAttrApplicationTag: tag ] SecItemAdd(addCertQuery as CFDictionary, nil) // Returns: -25303 Code Context Attempting to create SecIdentity for mTLS: private func createIdentity(fromCert certPEM: String, key keyPEM: String) throws -> SecIdentity { // 1. Parse PEM to DER and create SecCertificate - succeeds guard let certData = extractPEMData(from: certPEM, type: "CERTIFICATE"), let certificate = SecCertificateCreateWithData(nil, certData as CFData) else { throw CertificateError.invalidCertificate } // 2. Parse PEM key and create SecKey - succeeds guard let keyData = extractPEMData(from: keyPEM, type: "PRIVATE KEY"), let privateKey = SecKeyCreateWithData(keyData as CFData, attrs as CFDictionary, &error) else { throw CertificateError.invalidKey } // 3. Add key to keychain - SUCCEEDS (errSecSuccess) let tempTag = UUID().uuidString.data(using: .utf8)! SecItemAdd([ kSecClass: kSecClassKey, kSecValueRef: privateKey, kSecAttrApplicationTag: tempTag ] as CFDictionary, nil) // ✅ Works // 4. Add certificate to keychain - FAILS (-25303) let status = SecItemAdd([ kSecClass: kSecClassCertificate, kSecValueRef: certificate, kSecAttrApplicationTag: tempTag ] as CFDictionary, nil) // ❌ Fails with -25303 guard status == errSecSuccess else { throw CertificateError.keychainError(status) } // 5. Would query for SecIdentity (never reached) // ... } Network Behavior When mTLS fails, console shows: Connection: asked for TLS Client Certificates Connection: received response for client certificates (-1 elements) Connection: providing TLS Client Identity (-1 elements) Task received response, status 403 The -1 elements indicates no certificates were provided. Entitlements <key>keychain-access-groups</key> <array> <string>$(AppIdentifierPrefix)com.ellin.tshios</string> </array> Keychain Sharing capability is enabled. What I've Tried Both kSecValueRef and kSecValueData approaches - same error Various kSecAttrAccessible values - same error Different keychain access groups - same error TestFlight build (vs dev build) - same error PKCS#12 creation - requires complex ASN.1/DER encoding, no iOS API Questions Is error -25303 expected when adding SecCertificate in development/TestFlight builds? Will App Store distribution resolve this? Or is there a fundamental limitation? Why does SecKey succeed but SecCertificate fails with identical entitlements? Is there an alternative to create SecIdentity without keychain access? Constraints Certificates come from server at runtime (cannot bundle) Need SecIdentity for URLSession client certificate authentication Server provides PEM format certificates Tested on: Simulator (dev), iPad Pro (dev), iPad Pro (TestFlight) - all fail Any insights appreciated - specifically whether this is a provisioning profile limitation that App Store distribution would resolve.
Replies
3
Boosts
0
Views
276
Activity
Feb ’26