Security

RSS for tag

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

Posts under Security tag

200 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
5.1k
May ’25
Sandboxed app can't delete AppleDouble (._) files of quarantined files on exFAT, even with user-selected access.
My Mac App Store utility removes Mac metadata files (._* AppleDouble files and .DS_Store) from external drives formatted exFAT or FAT32. The app is sandboxed with com.apple.security.files.user-selected.read-write and com.apple.security.files.bookmarks.app-scope. The user grants access to the volume through NSOpenPanel. Deleting a ._ file works, except when its companion file carries com.apple.quarantine (for example, a file downloaded with Safari and copied to the drive with Finder). Then: let partner = volume + "/Nirvana.zip" // has com.apple.quarantine let appleDouble = volume + "/._Nirvana.zip" removexattr(partner, "com.apple.quarantine", XATTR_NOFOLLOW) // -1, errno 1 (EPERM) unlink(appleDouble) // -1, errno 1 (EPERM)The same unlink succeeds from Terminal (not sandboxed, without Full Disk Access). On exFAT the extended attributes live in the ._ file, so I assume the sandbox refuses because deleting it would remove the quarantine attribute. Tried, with no change: Full Disk Access granted to the app. Adding com.apple.security.files.user-selected.executable (verified in the built app with codesign -d --entitlements -). On a real drive (a music library), about 71% of the ._ files belong to quarantined files, so this is most of what users want removed. Is there a supported way for a sandboxed app to remove these files: an entitlement, an API, or an explicit user action? If not, can you confirm it's intended behavior, so I can explain it accurately to users? macOS 27.2, Xcode 27.2, Apple silicon. Focused sample project available (one source file). DTS case 23240704.
0
0
2
21m
macOS 27/APFS: Supported ACL Absence Verification When acl_get_fd_np Returns ENOENT
Subject: Supported fail-closed ACL absence verification on macOS 27.0.1 / APFS Environment: macOS 27.0.1, build 26A434; APFS; installed macOS 27.0 SDK. We need a supported, documented way to determine whether an existing filesystem object has no effective ACL entries, while rejecting genuine retrieval failures and unsupported or unavailable ACL evidence. We are seeking clarification of the public interface contract, not alleging an Apple defect. For existing directory and regular-file fixtures, pathname metadata and descriptor metadata identify the same object. Errno is cleared immediately before each native call and captured immediately afterward. ACL retrieval uses ACL_TYPE_EXTENDED: acl_get_file(path, ACL_TYPE_EXTENDED) acl_get_fd_np(fd, ACL_TYPE_EXTENDED) On fresh objects, both return NULL with ENOENT. Explicit one-entry fixture ACLs are retrieved successfully. Explicit zero-entry fixture ACLs can also yield NULL/ENOENT, while attribute queries return a serialized zero-entry ACL. The attribute queries use getattrlist() and descriptor-bound fgetattrlist(), requesting ATTR_CMN_RETURNED_ATTRS | ATTR_CMN_EXTENDED_SECURITY, with FSOPT_NOFOLLOW | FSOPT_REPORT_FULLSIZE and WITHOUT FSOPT_PACK_INVAL_ATTRS. Buffer lengths, variable-reference bounds and returned-attribute validity are checked. For the existing directories of interest, both calls succeed but omit the ATTR_CMN_EXTENDED_SECURITY returned bit. Explicit populated and zero-entry fixture records do set the bit. APFS reports valid VOL_CAP_INT_EXTENDED_SECURITY support; we do not assume that volume capability proves per-object ACL availability. On macOS 27.0.1, build 26A434, using APFS, which supported interface and documented conditions allow software to distinguish an absent ACL from unavailable or unsupported ACL evidence when descriptor-bound attribute queries succeed but omit ATTR_CMN_EXTENDED_SECURITY and native ACL getters return ENOENT for an existing object? Please clarify: Whether ENOENT has a supported ACL-absence interpretation, and under exactly which checked conditions. Whether an omitted extended-security attribute can establish ACL absence, rather than unavailable or unsupported evidence. How explicit zero-entry ACLs differ from absent ACL records through supported interfaces. How KAUTH_FILESEC_NOACL should be interpreted through supported APIs. How genuine retrieval failures, including permission, I/O, allocation and unsupported-operation errors, must remain distinguishable. Whether a supported descriptor-bound verification method exists that preserves fail-closed security checks and object identity binding; please identify its guarantees and limitations regarding pathname/ancestor changes and later operations. Whether relevant behavior is specific to this macOS/APFS version. Please identify the applicable public documentation or supported verification sequence. We do not want to modify permissions, synthesize ACLs on target objects, treat invalid-attribute defaults as real evidence, or accept ambiguous omission/ENOENT as success. Existing ownership, mode and confinement checks must remain separate mandatory checks. If no public API can make this distinction reliably, please state that limitation.
10
0
383
1d
Unexpected Core Foundation attribute types when inspecting an existing Secure Enclave-associated Keychain key on macOS
Hello Apple Developer community, I'm investigating an unexpected metadata representation returned by Apple's Security framework while inspecting an existing Secure Enclave-associated Keychain item on macOS. A read-only inspection using SecItemCopyMatching returns one matching key record with a successful status, a Secure Enclave token identifier (com.apple.setoken), and a 256-bit key size. However, direct Core Foundation type inspection reports: kSecAttrKeyType: CFNumber kSecAttrKeyClass: CFNumber kSecAttrSynchronizable: CFNumber The raw Core Foundation observations and bridged observations agree. Our current validator rejects these unexpected types and returns UNSUPPORTED_OR_INCOMPLETE_METADATA. We have deliberately stopped further key operations pending clarification. Questions: Can these CFNumber values legitimately appear in a dictionary returned by SecItemCopyMatching for Secure Enclave-associated key items on macOS? What returned value types should be expected for these three attributes, and are they dependent on the query or Keychain implementation? Is there an Apple-recommended way to normalize or validate these attributes without incorrectly accepting incompatible metadata? How should an application distinguish an existing Secure Enclave-backed key from an incomplete or unsupported Keychain record without performing a private-key operation? Are there relevant Security framework documentation references or known implementation differences we should consult? Our aim is to validate the existing record safely without regenerating, deleting, or using the private key. Thank you for your guidance.
5
0
396
2d
Can macOS restrict a signing key to one exact build of a system daemon?
Hi Apple Developer Technical Support, We have a locally signed macOS system daemon that an administrator starts manually. It needs to use a dedicated P-256 signing key in a file-based keychain. We want macOS to let only the exact approved build use that key, without a prompt. A different build signed with the same certificate should be denied. Apple’s published Security source shows that the keychain can identify some callers by their code directory hash (cdhash). Is setting a key’s partition list to that exact hash a supported way to enforce this restriction for a system daemon? If so, which macOS versions support it, and what API or Apple tool should we use to configure it? After setup, how can we verify that the intended key has the exact restriction in place, including whether any broader rule allows another process to sign with the key, export it, or change its access rules? If macOS doesn’t offer a supported way to set and verify this restriction, please confirm that limitation.
1
0
79
2d
Repeated login Keychain prompts and securityd crash after app upgrade on macOS 26.6.x
Overview We are investigating repeated "login" Keychain prompts affecting our macOS application on macOS 26.6.x. The issue appears after upgrading an existing installation. A clean uninstall/reinstall of the same version resolves it. Changing the affected Keychain item's Access Control from "Confirm before allowing access" to explicitly allowing our application/process also stops the prompts. On one affected machine, Apple Support observed a securityd crash followed by: SecKeyCreateSignature failed CSSMERR_DL_INVALID_DB_HANDLE Our code uses some legacy SecKeychain* APIs, so we are currently investigating whether this is related. Questions Were there any changes in macOS 26.6.x around securityd, Keychain ACL handling, or legacy SecKeychain* APIs that could explain this? Could an existing Keychain ACL become stale after an application upgrade, even when both versions are signed with the same Developer ID?
18
0
3.7k
5d
Secure Enclave: Supporting Signing-Only, Key-Agreement-Only, and Dual-Purpose Keys
Hello everyone, I'm trying to understand the actual limitations of the Secure Enclave (SEP) regarding cryptographic key capabilities, and more specifically how to generate and store the following key types in the keychain: Sign only: The key can only be used for digital signatures. Key agreement only: The key can only be used for key agreement operations. All operations: The key can be used for both signing and key agreement. I've noticed some apparent differences between Apple's Security framework and CryptoKit, and I'm trying to understand whether these differences reflect actual SEP limitations or simply framework-level restrictions. 1. Security framework: dual purpose keys I'm currently using SecKeyCreateRandomKey to generate Secure Enclave-backed keys. Here is the relevant code: NSDictionary *privateAttributes = @{ (__bridge id)kSecAttrIsPermanent : @YES, (__bridge id)kSecAttrAccessControl : ..., (__bridge id)kSecAttrApplicationTag : ..., // key agreement only (__bridge id)kSecAttrCanSign: @NO, (__bridge id)kSecAttrCanDerive: @YES }; NSMutableDictionary *attributes = [ @{ (__bridge id)kSecAttrKeyType : (__bridge id)kSecAttrKeyTypeECSECPrimeRandom, (__bridge id)kSecAttrTokenID : (__bridge id)kSecAttrTokenIDSecureEnclave, (__bridge id)kSecAttrKeySizeInBits : @256, (__bridge id)kSecPrivateKeyAttrs : privateAttributes } mutableCopy ]; CFErrorRef generationError = nullptr; SecKeyRef privateKey = SecKeyCreateRandomKey( (__bridge CFDictionaryRef)attributes, &generationError );However, when experimenting with these attributes, I encountered the following error: SecKeyCreateRandomKey failed: Error Domain=NSOSStatusErrorDomain Code=-50 "Failed to generate keypair" Underlying error: Error Domain=CryptoTokenKit Code=-8 "sepkey: sign requires '1' value when present"Using signing-only attributes results in the same kind of error. This makes me wonder whether the Security framework actually allows generating (and adding entries in the keyChain) only keys with both capabilities enabled. It is possible to create siging only key or key agreement only key with Security framework? 2. CryptoKit: Separate key types On the other hand, CryptoKit seems to expose two distinct Secure Enclave key types: P256.SecureEnclave.Signing.PrivateKey P256.SecureEnclave.KeyAgreement.PrivateKeyFrom the API design, it appears that CryptoKit only allows creating keys dedicated to one operation or the other. For example, a Signing.PrivateKey cannot be used for key agreement, and a KeyAgreement.PrivateKey cannot be used for signing. Is it possible to create both capabilities keys with CryptoKit framework? 3. Actual Secure Enclave limitations What are the actual cryptographic capability limitations imposed by the SEP itself? I'd particularly like to understand which restrictions originate from: The Secure Enclave hardware. Security and CryptoKit frameworks. Is there a documented way to generate and store in the keychain: A signing-only Secure Enclave key? A key-agreement-only Secure Enclave key? A Secure Enclave key supporting both operations? Thanks in advance, Idopte
1
0
64
5d
How can a macOS application establish that an open APFS file has no extended ACL?
On macOS 26.5.2 (build 25F84), which documented API and return conditions, if any, establish that a regular file on APFS has no extended access control list (ACL), using an already-open file descriptor? We tested three disposable regular files on an APFS volume reporting ACL support. For each file, we opened a read-only file descriptor and called: acl_get_fd_np(fd, ACL_TYPE_EXTENDED) fgetattrlist() requesting ATTR_CMN_RETURNED_ATTRS | ATTR_CMN_EXTENDED_SECURITY Before and after inspection, fstat() confirmed stable device, inode, mode, and change timestamp. Observed results: 1. Newly created file, no ACL explicitly assigned acl_get_fd_np() returned NULL with errno == ENOENT. fgetattrlist() succeeded but omitted ATTR_CMN_EXTENDED_SECURITY from the returned attribute mask. FSOPT_PACK_INVAL_ATTRS also left that bit clear. 2. File with an explicitly assigned empty ACL acl_get_fd_np() returned NULL with errno == ENOENT. fgetattrlist() returned the extended-security attribute with an ACL entry count of zero. 3. File with one explicit ACL entry acl_get_fd_np() returned a non-null ACL. fgetattrlist() returned the extended-security attribute with an ACL entry count of one. Apple's published XNU attribute-packing implementation appears to use the same omission branch when ACL metadata is unsupported or when the ACL pointer is null. My question: Is there a supported descriptor-based API sequence that reliably distinguishes: Genuine absence of an extended ACL Unavailable or unsupported per-file ACL metadata An ACL retrieval failure If so, which API, capability checks, return values, attribute bits, or error conditions should a caller rely on? Are there relevant APFS or macOS version limitations? If the public API cannot establish ACL absence unambiguously in this situation, confirmation of that limitation would also be helpful. Thank you for your guidance.
2
0
69
5d
Using Cryptokit.SecureEnclave API from a Launch Daemon
We are interested in using a hardware-bound key in a launch daemon. In a previous post, Quinn explicitly told me this is not possible to use an SE keypair outside of the system context and my reading of the Apple documentation also supports that. That said, we have gotten the following key-creation and persistence flow to work, so we have some questions as to how this fits in with the above. (1) In a launch daemon (running thus as root), we do: let key = SecureEnclave.P256.Signing.PrivateKey() (2) We then use key.dataRepresentation to store a reference to the key in the system keychain as a kSecClassGenericPassword. (3) When we want to use the key, we fetch the data representation from system keychain and we "rehydrate" the key using: SecureEnclave.P256.Signing.PrivateKey(dataRepresentation: data) (4) We then use the output of the above to sign whatever we want. My questions: in the above flow, are we actually getting a hardware-bound key from the Secure Enclave or is this working because it's actually defaulting to a non-hardware-backed key? if it is an SE key, is it that the Apple documentation stating that you can only use the SE with the Data Protection Keychain in the user context is outdated (or wrong)? does the above work, but is not an approach sanctioned by Apple? Any feedback on this would be greatly appreciated.
5
0
1.2k
5d
Import resulting certificate to associate with private key
On macOS I am creating a public/private key pair (ECDSA 256), will be secure enclave in the long run, just trying to baseline some functionality right now using file store (currently running in a system daemon). I can sign data using the private key with no problem, and export the public key. However, after generating a cert chain via CSR externally, I’m trying to figure out the proper incantation to import that cert/chain and have it recognized as matching the existing private key, but so far I can’t figure out the correct attributes to get it to pair up. Do you have any sample code that might have the right SecAddItem (or such) calls that would make this work as expected?
9
0
2.2k
5d
Supported data-only export of development source files carrying `com.apple.macl`
On macOS 26.7.1 with Xcode 26.6 on Apple silicon, a small set of ordinary development source/resource files and one project directory carry the private extended attribute com.apple.macl. We need to create a new APFS compilation-input tree, not a filesystem backup. The proposed implementation opens source and destination objects using descriptor-relative no-follow traversal and calls fcopyfile(sourceFD, destinationFD, NULL, COPYFILE_DATA), then independently verifies exact content hashes and applies an explicit destination mode and ACL policy. It does not request COPYFILE_XATTR, COPYFILE_ACL, or COPYFILE_STAT. Is omitting com.apple.macl supported for this data-only compilation export? Could preserving it transfer stale or inappropriate access authority to the destination? Which supported API or documented postconditions should establish the destination's correct security state? Is there an Apple-recommended procedure for exporting ordinary development source content without transferring private mandatory-access metadata? We are seeking an API and security contract, not an interpretation of the attribute's private bytes. No production paths, source code, private attribute values, credentials, datasets, or personal information are included.
2
0
150
1w
Sandboxed app cannot place File Provider placeholder file URLs on the pasteboard (sandbox error -20)
I'm building a sandboxed macOS app (Developer ID, App Sandbox enabled) with a File Provider extension that exposes on-demand placeholder files under  ~/Library/CloudStorage/<domain>/ . Expected: The app writes the placeholder file URLs to  NSPasteboard.general . The user presses ⌘V in Finder, and Finder fetches the contents on demand via  fetchContents . Observed: • Finder's own copy and paste of the same placeholders works, and  fetchContents  is called at paste time as expected. • When the sandboxed app writes the URLs to the pasteboard,  CFPasteboard  logs:  Sandbox extension creation failed ... (error -20) . The paste does not happen. • Writing  NSPasteboardItem  with  .fileURL  strings instead of  NSURL  objects produces the same error. • Adding  com.apple.security.temporary-exception.files.absolute-path.read-only  for the CloudStorage domain path fixes it. Questions: Is there a supported way for a sandboxed app to put File Provider placeholder URLs on the pasteboard without the temporary-exception entitlement? Is the temporary-exception entitlement acceptable for Mac App Store distribution, or is it only viable for Developer ID builds? Should the app grant itself access another way, for example through a security-scoped bookmark or by using  NSFileProviderManager  APIs?
4
0
273
1w
Pre-activation authorization and inactive connection cleanup for a launchd Mach service
I am evaluating the supported macOS C XPC lifecycle for a separately installed system-domain Mach service. This is a design/documentation question, not a reported crash or a tested OS-specific failure. Please identify applicable macOS/SDK versions and public API guarantees; no installed SDK capability is being assumed. The threat model includes an unprivileged process running as the worker's user. The OS and privileged administrator are trusted. Executables and role assignments would require independently protected approval. Matching a code signature alone is not intended to grant an issuer role. Two API boundaries affect whether the service can be authorized before activation: Binding an actual launch instance to protected enrollment. Is there a supported public API or enforceable launch-environment constraint that can distinguish an instance launched through an approved system-domain job/enrollment from direct invocation of the same approved executable? The required distinction is the actual job/executable launch transaction before service activation, not a process-provided label, PID/PPID lookup, copied install record, or signature alone. If launch constraints can enforce only a narrower property, what exactly is that property and its minimum supported version? If no public mechanism provides the stronger binding, confirmation of that limit would be useful. This question does not assume an XPC peer requirement can establish job origin or issuer authority. Disposing of a newly owned inactive connection after setup failure. Suppose xpc_connection_create_mach_service returns a caller-owned inactive client or listener, but preactivation policy setup then fails, for example xpc_connection_set_peer_code_signing_requirement returns an error. What is the documented safe cleanup sequence if transport activation has not been authorized? The xpc_connection_activate documentation warns that last-release of a created inactive connection is undefined. The cancellation documentation describes asynchronous unwinding, but I have not found an explicit exception for last-release of a never-activated, canceled object. Does a supported cancel/release sequence exist? If activation is required even for disposal, what effects can that cleanup activation cause and what guarantees apply? I am asking about a newly created owned object, not an incoming borrowed peer that a listener can reject by canceling and returning. Relevant references already consulted: https://developer.apple.com/documentation/xpc/xpc_connection_activate(_:) https://developer.apple.com/documentation/xpc/xpc_connection_cancel(_:) https://developer.apple.com/documentation/xpc/xpc_connection_set_event_handler(::) https://developer.apple.com/forums/thread/837286 (received-message checking versus initial outgoing delivery) An API reference, versioned contract, or explicit statement that either guarantee is unavailable would help determine the safe supported boundary. I am not requesting private APIs or a workaround that treats a caller assertion as authorization.
1
0
139
1w
Slow iCloud Keychain synchronization to macOS
Hi, are there any known issues with delayed iCloud Keychain synchronization to macOS? I have an app for iOS and macOS that supports creating, reading, updating, and deleting synchronizable Keychain items. Both versions are signed with the same Team ID, and all test devices are signed in to the same Apple Account. I’m observing a significant difference depending on the direction of synchronization: macOS → iOS: approximately 30 seconds. iOS → other iOS devices: approximately 30 seconds. iOS → macOS: approximately 30 minutes, with some variation. Changes eventually appear on the Macs, but incoming updates take much longer. Is this expected behavior, a known issue, or something that could be caused by my implementation? What diagnostics would help investigate it? Devices are on iOS 26 and macOS 26.
1
0
273
1w
Verify historical Keychain access groups of an existing iOS development installation
I am preparing a data-preserving, same-bundle-identifier update of my own development-signed iOS/iPadOS app (Target Keeper). Existing installations contain records that must be preserved. No update has been attempted, and no Keychain loss or entitlement incompatibility has been demonstrated. Environment: iOS/iPadOS 27.0.1 and Xcode 27.1. The original signed packages/archives for the installed older builds are no longer available. The proposed update has a valid Development signature and a profile covering the test devices. Its signed application identifier, Team identifier and Keychain groups have been inspected locally. The current and a retained later source snapshot use a bundle-derived service and a generic-password query without an explicit kSecAttrAccessGroup, with kSecAttrSynchronizable false and WhenUnlockedThisDeviceOnly accessibility. However, those source snapshots are not authenticated as the source used to produce the older installed binaries. I am therefore not assuming they prove the older effective groups or App ID prefix. I have read Sharing access to keychain items among a collection of apps, TN2415, QA1726, TN2311, and SecItem: Pitfalls and Best Practices: https://developer.apple.com/documentation/security/sharing-access-to-keychain-items-among-a-collection-of-apps https://developer.apple.com/library/archive/technotes/tn2415/_index.html https://developer.apple.com/library/archive/qa/qa1726/_index.html https://developer.apple.com/library/archive/technotes/tn2311/_index.html https://developer.apple.com/forums/thread/724013 These explain the access-group rules, first-group default and service/query distinctions. My remaining question is how to obtain authoritative evidence for the already-installed older app when its original signed package is missing. Is there a supported Xcode, Device Hub, devicectl or other Apple workflow to read/authenticate the effective application-identifier, Team and keychain-access-groups (including relevant App Groups) of an existing development installation without replacing it or extracting any Keychain values? If a local provisioning/install receipt can help, what establishes that it belongs to the installed binary rather than merely showing what a candidate profile permits? If no supported read-only method exists, what minimal controlled diagnostic does Apple recommend to qualify same-app Keychain continuity while preserving the original installation? Please distinguish methods requiring app launch/debugger attachment from genuinely read-only device-management inspection. Available app metadata and an exported app-data container have not supplied a signed entitlement list in the checks performed. Matching the candidate Team and bundle ID alone is not being treated as proof. A cross-bundle shipping migration is a separate problem and is not being attempted here. I am not asking to bypass code-signing or Keychain access controls, broaden access groups, uninstall the old app, or dump credentials. No passwords, certificates/private keys, device identifiers, backup files or application records are attached.
3
0
695
1w
Does SessionGetInfo provide authoritative current-session liveness for an ASID from a Mach audit token?
Environment: macOS 26.6.2 (25G83) Xcode 26.6 (17F113) macOS command-line process Security.framework SessionGetInfo ASID obtained from the kernel-provided audit token in a received Mach message I’m implementing a security-sensitive Mach IPC receiver. The receiver obtains the sender’s audit token from the Mach message trailer and derives the sender PID, effective UID, and audit session ID (ASID). The sender executable identity is validated separately. Given the ASID, SessionGetInfo can successfully return the corresponding SecuritySessionId and session attributes. The question is about the freshness and synchronization semantics of that lookup. At the point where the receiver authorizes a request, can a successful SessionGetInfo(asid, ...) result be treated as authoritative evidence that the corresponding login/audit session is still currently valid? In particular: What happens if the session logs out, terminates, or is revoked concurrently with the lookup? Can SessionGetInfo successfully return information for a session that is no longer current due to caching or propagation delay? Are there documented ordering or synchronization guarantees between session termination and subsequent SessionGetInfo calls from another process? Can the lookup block for an unbounded period if the underlying security service is unavailable? Is there a supported timeout or cancellation mechanism? Is there another supported public macOS API better suited to establishing authoritative current-session liveness for an ASID obtained from an audit token? The security requirement is fail-closed. I’m specifically trying to avoid private APIs, process-table heuristics, diagnostic launchctl output, or assumptions that the ASID encoded in a previously received audit token necessarily represents current session state. If the public API does not provide an authoritative liveness/freshness guarantee, confirmation of that limitation would also answer the design question. I also have a minimal 122-line Xcode sample that: creates and receives a Mach message, reads the kernel-provided audit trailer, extracts the ASID, calls SessionGetInfo, and prints the returned session ID and attributes. I can provide the sample project if useful.
16
0
600
1w
Supported memory-limit increase for an iOS Enhanced Security helper extension
We’re using an Enhanced Security helper extension with AppExtensionProcess and XPCSession to isolate native zero-knowledge proof generation from wallet and signing code. On an iPhone 15 Pro running iOS 26.6.2 (23G90), the helper terminates with: EXC_RESOURCE RESOURCE_TYPE_MEMORY: high watermark memory limit exceeded (limit=35 MB) Terminated due to memory issue Our current prover requires substantially more memory: its public proving key is approximately 402 MiB, and its witness workspace alone is approximately 69 MiB. The same proof engine has completed successfully in a standalone iOS app process. The helper currently processes only synthetic test inputs. We want to preserve the helper’s sandbox and Enhanced Security protections and use a configuration supported for App Store distribution. Is there a supported way to increase the memory limit for this specific helper extension type? Does com.apple.developer.kernel.increased-memory-limit apply to Enhanced Security helper extensions? If so, what provisioning, target configuration, and device/OS requirements apply?
4
1
334
1w
Title: Supported OS-enforced restriction of Keychain access while retaining App Sandbox and App Group UDS
I’m designing a small, controlled macOS test harness. Two separately signed, sandboxed applications communicate through a UNIX-domain socket in an App Group container. They run as non-root processes in a GUI user session. One application also launches a child that inherits its sandbox and an existing socket descriptor. Is there a documented, supported OS policy that preserves this IPC arrangement while preventing the test processes from retrieving, using or modifying credentials, including items in their own Data Protection Keychain access groups and reachable file-based keychains? The policy must also prevent creating credential stores/items outside the permitted test resources. Using a macOS-style TeamID-prefixed App Group avoids that group providing Keychain sharing, but does not establish denial of the remaining Keychain operations. Empty stores, avoiding API calls and relying on users refusing prompts are insufficient for this requirement. If a different execution context or isolation architecture is required, could you identify the supported mechanism and relevant documentation? I’m seeking platform guidance, without relying on private APIs or unsupported custom sandbox profiles.
3
0
325
2w
Is there a supported per-boot identifier that can't be reset or rolled back by a backup restore?
I'm looking for a documented, supported way for an iOS app to tell, on-device and without network access, that the device has restarted or been restored from a backup since a given point. The goal is to fail closed after either event. It is not to identify the device or user, and the value would never leave the device. I'm aware of the existing forum guidance (for example thread 110044 and thread 809339), which describes best-effort techniques. I'm asking whether a guaranteed mechanism exists. Specifically, does iOS provide a supported public API, or a documented combination of APIs, that offers all of the following: Unique per boot. A value guaranteed never to repeat across boots of the same device. This would cover every kind of restart: graceful shutdown, forced or watchdog reset, kernel panic, and power loss or battery depletion. Not resettable or rolled back. A value the app itself cannot reset, that deleting and reinstalling the app doesn't reset, and that restoring a backup can neither reset nor roll back to an earlier value. Changes on every same-device restore. A signal guaranteed to change observably whenever a backup is restored to the same physical device, from iCloud Backup or an encrypted Finder backup, with or without Erase All Content and Settings first. It must not be stored in, derived from, or rolled back by anything a backup restores. If no such API exists, it would help to know that too. And if some of these properties hold only as current implementation behavior rather than a documented guarantee, I'd appreciate knowing which. Thanks!
4
0
131
2w
macOS /etc/ssl/cert.pem still trusts the eMudhra roots: curl and python3 accept the compromised intermediates
Apple blocked the eight compromised eMudhra intermediate CAs (CVE-2026-111943) for Security.framework clients. But on macOS 27.0.1 (26A434), /usr/bin/curl and /usr/bin/python3 still accept certificates from them. These tools verify against /etc/ssl/cert.pem and do not check revocation. The file (dated Sep 24) still contains both roots that the compromised intermediates chain to: emSign ECC Root CA - G3 AAA Certificate Services To reproduce, with SSL_CERT_FILE and CURL_CA_BUNDLE not set: /usr/bin/curl -sS -o /dev/null -w '%{exitcode}\n' https://dv-g3b-emudhra.we-have-a-problem.com/ # 0 — the connection succeeds grep -E 'emSign ECC Root CA - G3|AAA Certificate Services' /etc/ssl/cert.pem # both roots are presentWith a CA bundle that does not have these roots (Homebrew ca-certificates), the same command fails with "unable to get local issuer certificate". So the system bundle is the cause. softwareupdate -l shows no update. Questions: Does Apple plan to update /etc/ssl/cert.pem for this, and will the security notes say so? Until then, is setting SSL_CERT_FILE to a separate bundle the recommended workaround for the system tools?
1
0
170
2w
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
5.1k
Activity
May ’25
Sandboxed app can't delete AppleDouble (._) files of quarantined files on exFAT, even with user-selected access.
My Mac App Store utility removes Mac metadata files (._* AppleDouble files and .DS_Store) from external drives formatted exFAT or FAT32. The app is sandboxed with com.apple.security.files.user-selected.read-write and com.apple.security.files.bookmarks.app-scope. The user grants access to the volume through NSOpenPanel. Deleting a ._ file works, except when its companion file carries com.apple.quarantine (for example, a file downloaded with Safari and copied to the drive with Finder). Then: let partner = volume + "/Nirvana.zip" // has com.apple.quarantine let appleDouble = volume + "/._Nirvana.zip" removexattr(partner, "com.apple.quarantine", XATTR_NOFOLLOW) // -1, errno 1 (EPERM) unlink(appleDouble) // -1, errno 1 (EPERM)The same unlink succeeds from Terminal (not sandboxed, without Full Disk Access). On exFAT the extended attributes live in the ._ file, so I assume the sandbox refuses because deleting it would remove the quarantine attribute. Tried, with no change: Full Disk Access granted to the app. Adding com.apple.security.files.user-selected.executable (verified in the built app with codesign -d --entitlements -). On a real drive (a music library), about 71% of the ._ files belong to quarantined files, so this is most of what users want removed. Is there a supported way for a sandboxed app to remove these files: an entitlement, an API, or an explicit user action? If not, can you confirm it's intended behavior, so I can explain it accurately to users? macOS 27.2, Xcode 27.2, Apple silicon. Focused sample project available (one source file). DTS case 23240704.
Replies
0
Boosts
0
Views
2
Activity
21m
is NSTextInputClient safe?
is NSTextInputClient safe? I have several apps that has autofill (app name) activity due to NSTextInputClient. I am wondering if my app has this activity will it be submittable to the app store?
Replies
1
Boosts
0
Views
195
Activity
14h
macOS 27/APFS: Supported ACL Absence Verification When acl_get_fd_np Returns ENOENT
Subject: Supported fail-closed ACL absence verification on macOS 27.0.1 / APFS Environment: macOS 27.0.1, build 26A434; APFS; installed macOS 27.0 SDK. We need a supported, documented way to determine whether an existing filesystem object has no effective ACL entries, while rejecting genuine retrieval failures and unsupported or unavailable ACL evidence. We are seeking clarification of the public interface contract, not alleging an Apple defect. For existing directory and regular-file fixtures, pathname metadata and descriptor metadata identify the same object. Errno is cleared immediately before each native call and captured immediately afterward. ACL retrieval uses ACL_TYPE_EXTENDED: acl_get_file(path, ACL_TYPE_EXTENDED) acl_get_fd_np(fd, ACL_TYPE_EXTENDED) On fresh objects, both return NULL with ENOENT. Explicit one-entry fixture ACLs are retrieved successfully. Explicit zero-entry fixture ACLs can also yield NULL/ENOENT, while attribute queries return a serialized zero-entry ACL. The attribute queries use getattrlist() and descriptor-bound fgetattrlist(), requesting ATTR_CMN_RETURNED_ATTRS | ATTR_CMN_EXTENDED_SECURITY, with FSOPT_NOFOLLOW | FSOPT_REPORT_FULLSIZE and WITHOUT FSOPT_PACK_INVAL_ATTRS. Buffer lengths, variable-reference bounds and returned-attribute validity are checked. For the existing directories of interest, both calls succeed but omit the ATTR_CMN_EXTENDED_SECURITY returned bit. Explicit populated and zero-entry fixture records do set the bit. APFS reports valid VOL_CAP_INT_EXTENDED_SECURITY support; we do not assume that volume capability proves per-object ACL availability. On macOS 27.0.1, build 26A434, using APFS, which supported interface and documented conditions allow software to distinguish an absent ACL from unavailable or unsupported ACL evidence when descriptor-bound attribute queries succeed but omit ATTR_CMN_EXTENDED_SECURITY and native ACL getters return ENOENT for an existing object? Please clarify: Whether ENOENT has a supported ACL-absence interpretation, and under exactly which checked conditions. Whether an omitted extended-security attribute can establish ACL absence, rather than unavailable or unsupported evidence. How explicit zero-entry ACLs differ from absent ACL records through supported interfaces. How KAUTH_FILESEC_NOACL should be interpreted through supported APIs. How genuine retrieval failures, including permission, I/O, allocation and unsupported-operation errors, must remain distinguishable. Whether a supported descriptor-bound verification method exists that preserves fail-closed security checks and object identity binding; please identify its guarantees and limitations regarding pathname/ancestor changes and later operations. Whether relevant behavior is specific to this macOS/APFS version. Please identify the applicable public documentation or supported verification sequence. We do not want to modify permissions, synthesize ACLs on target objects, treat invalid-attribute defaults as real evidence, or accept ambiguous omission/ENOENT as success. Existing ownership, mode and confinement checks must remain separate mandatory checks. If no public API can make this distinction reliably, please state that limitation.
Replies
10
Boosts
0
Views
383
Activity
1d
Unexpected Core Foundation attribute types when inspecting an existing Secure Enclave-associated Keychain key on macOS
Hello Apple Developer community, I'm investigating an unexpected metadata representation returned by Apple's Security framework while inspecting an existing Secure Enclave-associated Keychain item on macOS. A read-only inspection using SecItemCopyMatching returns one matching key record with a successful status, a Secure Enclave token identifier (com.apple.setoken), and a 256-bit key size. However, direct Core Foundation type inspection reports: kSecAttrKeyType: CFNumber kSecAttrKeyClass: CFNumber kSecAttrSynchronizable: CFNumber The raw Core Foundation observations and bridged observations agree. Our current validator rejects these unexpected types and returns UNSUPPORTED_OR_INCOMPLETE_METADATA. We have deliberately stopped further key operations pending clarification. Questions: Can these CFNumber values legitimately appear in a dictionary returned by SecItemCopyMatching for Secure Enclave-associated key items on macOS? What returned value types should be expected for these three attributes, and are they dependent on the query or Keychain implementation? Is there an Apple-recommended way to normalize or validate these attributes without incorrectly accepting incompatible metadata? How should an application distinguish an existing Secure Enclave-backed key from an incomplete or unsupported Keychain record without performing a private-key operation? Are there relevant Security framework documentation references or known implementation differences we should consult? Our aim is to validate the existing record safely without regenerating, deleting, or using the private key. Thank you for your guidance.
Replies
5
Boosts
0
Views
396
Activity
2d
Can macOS restrict a signing key to one exact build of a system daemon?
Hi Apple Developer Technical Support, We have a locally signed macOS system daemon that an administrator starts manually. It needs to use a dedicated P-256 signing key in a file-based keychain. We want macOS to let only the exact approved build use that key, without a prompt. A different build signed with the same certificate should be denied. Apple’s published Security source shows that the keychain can identify some callers by their code directory hash (cdhash). Is setting a key’s partition list to that exact hash a supported way to enforce this restriction for a system daemon? If so, which macOS versions support it, and what API or Apple tool should we use to configure it? After setup, how can we verify that the intended key has the exact restriction in place, including whether any broader rule allows another process to sign with the key, export it, or change its access rules? If macOS doesn’t offer a supported way to set and verify this restriction, please confirm that limitation.
Replies
1
Boosts
0
Views
79
Activity
2d
Repeated login Keychain prompts and securityd crash after app upgrade on macOS 26.6.x
Overview We are investigating repeated "login" Keychain prompts affecting our macOS application on macOS 26.6.x. The issue appears after upgrading an existing installation. A clean uninstall/reinstall of the same version resolves it. Changing the affected Keychain item's Access Control from "Confirm before allowing access" to explicitly allowing our application/process also stops the prompts. On one affected machine, Apple Support observed a securityd crash followed by: SecKeyCreateSignature failed CSSMERR_DL_INVALID_DB_HANDLE Our code uses some legacy SecKeychain* APIs, so we are currently investigating whether this is related. Questions Were there any changes in macOS 26.6.x around securityd, Keychain ACL handling, or legacy SecKeychain* APIs that could explain this? Could an existing Keychain ACL become stale after an application upgrade, even when both versions are signed with the same Developer ID?
Replies
18
Boosts
0
Views
3.7k
Activity
5d
Secure Enclave: Supporting Signing-Only, Key-Agreement-Only, and Dual-Purpose Keys
Hello everyone, I'm trying to understand the actual limitations of the Secure Enclave (SEP) regarding cryptographic key capabilities, and more specifically how to generate and store the following key types in the keychain: Sign only: The key can only be used for digital signatures. Key agreement only: The key can only be used for key agreement operations. All operations: The key can be used for both signing and key agreement. I've noticed some apparent differences between Apple's Security framework and CryptoKit, and I'm trying to understand whether these differences reflect actual SEP limitations or simply framework-level restrictions. 1. Security framework: dual purpose keys I'm currently using SecKeyCreateRandomKey to generate Secure Enclave-backed keys. Here is the relevant code: NSDictionary *privateAttributes = @{ (__bridge id)kSecAttrIsPermanent : @YES, (__bridge id)kSecAttrAccessControl : ..., (__bridge id)kSecAttrApplicationTag : ..., // key agreement only (__bridge id)kSecAttrCanSign: @NO, (__bridge id)kSecAttrCanDerive: @YES }; NSMutableDictionary *attributes = [ @{ (__bridge id)kSecAttrKeyType : (__bridge id)kSecAttrKeyTypeECSECPrimeRandom, (__bridge id)kSecAttrTokenID : (__bridge id)kSecAttrTokenIDSecureEnclave, (__bridge id)kSecAttrKeySizeInBits : @256, (__bridge id)kSecPrivateKeyAttrs : privateAttributes } mutableCopy ]; CFErrorRef generationError = nullptr; SecKeyRef privateKey = SecKeyCreateRandomKey( (__bridge CFDictionaryRef)attributes, &generationError );However, when experimenting with these attributes, I encountered the following error: SecKeyCreateRandomKey failed: Error Domain=NSOSStatusErrorDomain Code=-50 "Failed to generate keypair" Underlying error: Error Domain=CryptoTokenKit Code=-8 "sepkey: sign requires '1' value when present"Using signing-only attributes results in the same kind of error. This makes me wonder whether the Security framework actually allows generating (and adding entries in the keyChain) only keys with both capabilities enabled. It is possible to create siging only key or key agreement only key with Security framework? 2. CryptoKit: Separate key types On the other hand, CryptoKit seems to expose two distinct Secure Enclave key types: P256.SecureEnclave.Signing.PrivateKey P256.SecureEnclave.KeyAgreement.PrivateKeyFrom the API design, it appears that CryptoKit only allows creating keys dedicated to one operation or the other. For example, a Signing.PrivateKey cannot be used for key agreement, and a KeyAgreement.PrivateKey cannot be used for signing. Is it possible to create both capabilities keys with CryptoKit framework? 3. Actual Secure Enclave limitations What are the actual cryptographic capability limitations imposed by the SEP itself? I'd particularly like to understand which restrictions originate from: The Secure Enclave hardware. Security and CryptoKit frameworks. Is there a documented way to generate and store in the keychain: A signing-only Secure Enclave key? A key-agreement-only Secure Enclave key? A Secure Enclave key supporting both operations? Thanks in advance, Idopte
Replies
1
Boosts
0
Views
64
Activity
5d
How can a macOS application establish that an open APFS file has no extended ACL?
On macOS 26.5.2 (build 25F84), which documented API and return conditions, if any, establish that a regular file on APFS has no extended access control list (ACL), using an already-open file descriptor? We tested three disposable regular files on an APFS volume reporting ACL support. For each file, we opened a read-only file descriptor and called: acl_get_fd_np(fd, ACL_TYPE_EXTENDED) fgetattrlist() requesting ATTR_CMN_RETURNED_ATTRS | ATTR_CMN_EXTENDED_SECURITY Before and after inspection, fstat() confirmed stable device, inode, mode, and change timestamp. Observed results: 1. Newly created file, no ACL explicitly assigned acl_get_fd_np() returned NULL with errno == ENOENT. fgetattrlist() succeeded but omitted ATTR_CMN_EXTENDED_SECURITY from the returned attribute mask. FSOPT_PACK_INVAL_ATTRS also left that bit clear. 2. File with an explicitly assigned empty ACL acl_get_fd_np() returned NULL with errno == ENOENT. fgetattrlist() returned the extended-security attribute with an ACL entry count of zero. 3. File with one explicit ACL entry acl_get_fd_np() returned a non-null ACL. fgetattrlist() returned the extended-security attribute with an ACL entry count of one. Apple's published XNU attribute-packing implementation appears to use the same omission branch when ACL metadata is unsupported or when the ACL pointer is null. My question: Is there a supported descriptor-based API sequence that reliably distinguishes: Genuine absence of an extended ACL Unavailable or unsupported per-file ACL metadata An ACL retrieval failure If so, which API, capability checks, return values, attribute bits, or error conditions should a caller rely on? Are there relevant APFS or macOS version limitations? If the public API cannot establish ACL absence unambiguously in this situation, confirmation of that limitation would also be helpful. Thank you for your guidance.
Replies
2
Boosts
0
Views
69
Activity
5d
Using Cryptokit.SecureEnclave API from a Launch Daemon
We are interested in using a hardware-bound key in a launch daemon. In a previous post, Quinn explicitly told me this is not possible to use an SE keypair outside of the system context and my reading of the Apple documentation also supports that. That said, we have gotten the following key-creation and persistence flow to work, so we have some questions as to how this fits in with the above. (1) In a launch daemon (running thus as root), we do: let key = SecureEnclave.P256.Signing.PrivateKey() (2) We then use key.dataRepresentation to store a reference to the key in the system keychain as a kSecClassGenericPassword. (3) When we want to use the key, we fetch the data representation from system keychain and we "rehydrate" the key using: SecureEnclave.P256.Signing.PrivateKey(dataRepresentation: data) (4) We then use the output of the above to sign whatever we want. My questions: in the above flow, are we actually getting a hardware-bound key from the Secure Enclave or is this working because it's actually defaulting to a non-hardware-backed key? if it is an SE key, is it that the Apple documentation stating that you can only use the SE with the Data Protection Keychain in the user context is outdated (or wrong)? does the above work, but is not an approach sanctioned by Apple? Any feedback on this would be greatly appreciated.
Replies
5
Boosts
0
Views
1.2k
Activity
5d
Import resulting certificate to associate with private key
On macOS I am creating a public/private key pair (ECDSA 256), will be secure enclave in the long run, just trying to baseline some functionality right now using file store (currently running in a system daemon). I can sign data using the private key with no problem, and export the public key. However, after generating a cert chain via CSR externally, I’m trying to figure out the proper incantation to import that cert/chain and have it recognized as matching the existing private key, but so far I can’t figure out the correct attributes to get it to pair up. Do you have any sample code that might have the right SecAddItem (or such) calls that would make this work as expected?
Replies
9
Boosts
0
Views
2.2k
Activity
5d
Supported data-only export of development source files carrying `com.apple.macl`
On macOS 26.7.1 with Xcode 26.6 on Apple silicon, a small set of ordinary development source/resource files and one project directory carry the private extended attribute com.apple.macl. We need to create a new APFS compilation-input tree, not a filesystem backup. The proposed implementation opens source and destination objects using descriptor-relative no-follow traversal and calls fcopyfile(sourceFD, destinationFD, NULL, COPYFILE_DATA), then independently verifies exact content hashes and applies an explicit destination mode and ACL policy. It does not request COPYFILE_XATTR, COPYFILE_ACL, or COPYFILE_STAT. Is omitting com.apple.macl supported for this data-only compilation export? Could preserving it transfer stale or inappropriate access authority to the destination? Which supported API or documented postconditions should establish the destination's correct security state? Is there an Apple-recommended procedure for exporting ordinary development source content without transferring private mandatory-access metadata? We are seeking an API and security contract, not an interpretation of the attribute's private bytes. No production paths, source code, private attribute values, credentials, datasets, or personal information are included.
Replies
2
Boosts
0
Views
150
Activity
1w
Sandboxed app cannot place File Provider placeholder file URLs on the pasteboard (sandbox error -20)
I'm building a sandboxed macOS app (Developer ID, App Sandbox enabled) with a File Provider extension that exposes on-demand placeholder files under  ~/Library/CloudStorage/<domain>/ . Expected: The app writes the placeholder file URLs to  NSPasteboard.general . The user presses ⌘V in Finder, and Finder fetches the contents on demand via  fetchContents . Observed: • Finder's own copy and paste of the same placeholders works, and  fetchContents  is called at paste time as expected. • When the sandboxed app writes the URLs to the pasteboard,  CFPasteboard  logs:  Sandbox extension creation failed ... (error -20) . The paste does not happen. • Writing  NSPasteboardItem  with  .fileURL  strings instead of  NSURL  objects produces the same error. • Adding  com.apple.security.temporary-exception.files.absolute-path.read-only  for the CloudStorage domain path fixes it. Questions: Is there a supported way for a sandboxed app to put File Provider placeholder URLs on the pasteboard without the temporary-exception entitlement? Is the temporary-exception entitlement acceptable for Mac App Store distribution, or is it only viable for Developer ID builds? Should the app grant itself access another way, for example through a security-scoped bookmark or by using  NSFileProviderManager  APIs?
Replies
4
Boosts
0
Views
273
Activity
1w
Pre-activation authorization and inactive connection cleanup for a launchd Mach service
I am evaluating the supported macOS C XPC lifecycle for a separately installed system-domain Mach service. This is a design/documentation question, not a reported crash or a tested OS-specific failure. Please identify applicable macOS/SDK versions and public API guarantees; no installed SDK capability is being assumed. The threat model includes an unprivileged process running as the worker's user. The OS and privileged administrator are trusted. Executables and role assignments would require independently protected approval. Matching a code signature alone is not intended to grant an issuer role. Two API boundaries affect whether the service can be authorized before activation: Binding an actual launch instance to protected enrollment. Is there a supported public API or enforceable launch-environment constraint that can distinguish an instance launched through an approved system-domain job/enrollment from direct invocation of the same approved executable? The required distinction is the actual job/executable launch transaction before service activation, not a process-provided label, PID/PPID lookup, copied install record, or signature alone. If launch constraints can enforce only a narrower property, what exactly is that property and its minimum supported version? If no public mechanism provides the stronger binding, confirmation of that limit would be useful. This question does not assume an XPC peer requirement can establish job origin or issuer authority. Disposing of a newly owned inactive connection after setup failure. Suppose xpc_connection_create_mach_service returns a caller-owned inactive client or listener, but preactivation policy setup then fails, for example xpc_connection_set_peer_code_signing_requirement returns an error. What is the documented safe cleanup sequence if transport activation has not been authorized? The xpc_connection_activate documentation warns that last-release of a created inactive connection is undefined. The cancellation documentation describes asynchronous unwinding, but I have not found an explicit exception for last-release of a never-activated, canceled object. Does a supported cancel/release sequence exist? If activation is required even for disposal, what effects can that cleanup activation cause and what guarantees apply? I am asking about a newly created owned object, not an incoming borrowed peer that a listener can reject by canceling and returning. Relevant references already consulted: https://developer.apple.com/documentation/xpc/xpc_connection_activate(_:) https://developer.apple.com/documentation/xpc/xpc_connection_cancel(_:) https://developer.apple.com/documentation/xpc/xpc_connection_set_event_handler(::) https://developer.apple.com/forums/thread/837286 (received-message checking versus initial outgoing delivery) An API reference, versioned contract, or explicit statement that either guarantee is unavailable would help determine the safe supported boundary. I am not requesting private APIs or a workaround that treats a caller assertion as authorization.
Replies
1
Boosts
0
Views
139
Activity
1w
Slow iCloud Keychain synchronization to macOS
Hi, are there any known issues with delayed iCloud Keychain synchronization to macOS? I have an app for iOS and macOS that supports creating, reading, updating, and deleting synchronizable Keychain items. Both versions are signed with the same Team ID, and all test devices are signed in to the same Apple Account. I’m observing a significant difference depending on the direction of synchronization: macOS → iOS: approximately 30 seconds. iOS → other iOS devices: approximately 30 seconds. iOS → macOS: approximately 30 minutes, with some variation. Changes eventually appear on the Macs, but incoming updates take much longer. Is this expected behavior, a known issue, or something that could be caused by my implementation? What diagnostics would help investigate it? Devices are on iOS 26 and macOS 26.
Replies
1
Boosts
0
Views
273
Activity
1w
Verify historical Keychain access groups of an existing iOS development installation
I am preparing a data-preserving, same-bundle-identifier update of my own development-signed iOS/iPadOS app (Target Keeper). Existing installations contain records that must be preserved. No update has been attempted, and no Keychain loss or entitlement incompatibility has been demonstrated. Environment: iOS/iPadOS 27.0.1 and Xcode 27.1. The original signed packages/archives for the installed older builds are no longer available. The proposed update has a valid Development signature and a profile covering the test devices. Its signed application identifier, Team identifier and Keychain groups have been inspected locally. The current and a retained later source snapshot use a bundle-derived service and a generic-password query without an explicit kSecAttrAccessGroup, with kSecAttrSynchronizable false and WhenUnlockedThisDeviceOnly accessibility. However, those source snapshots are not authenticated as the source used to produce the older installed binaries. I am therefore not assuming they prove the older effective groups or App ID prefix. I have read Sharing access to keychain items among a collection of apps, TN2415, QA1726, TN2311, and SecItem: Pitfalls and Best Practices: https://developer.apple.com/documentation/security/sharing-access-to-keychain-items-among-a-collection-of-apps https://developer.apple.com/library/archive/technotes/tn2415/_index.html https://developer.apple.com/library/archive/qa/qa1726/_index.html https://developer.apple.com/library/archive/technotes/tn2311/_index.html https://developer.apple.com/forums/thread/724013 These explain the access-group rules, first-group default and service/query distinctions. My remaining question is how to obtain authoritative evidence for the already-installed older app when its original signed package is missing. Is there a supported Xcode, Device Hub, devicectl or other Apple workflow to read/authenticate the effective application-identifier, Team and keychain-access-groups (including relevant App Groups) of an existing development installation without replacing it or extracting any Keychain values? If a local provisioning/install receipt can help, what establishes that it belongs to the installed binary rather than merely showing what a candidate profile permits? If no supported read-only method exists, what minimal controlled diagnostic does Apple recommend to qualify same-app Keychain continuity while preserving the original installation? Please distinguish methods requiring app launch/debugger attachment from genuinely read-only device-management inspection. Available app metadata and an exported app-data container have not supplied a signed entitlement list in the checks performed. Matching the candidate Team and bundle ID alone is not being treated as proof. A cross-bundle shipping migration is a separate problem and is not being attempted here. I am not asking to bypass code-signing or Keychain access controls, broaden access groups, uninstall the old app, or dump credentials. No passwords, certificates/private keys, device identifiers, backup files or application records are attached.
Replies
3
Boosts
0
Views
695
Activity
1w
Does SessionGetInfo provide authoritative current-session liveness for an ASID from a Mach audit token?
Environment: macOS 26.6.2 (25G83) Xcode 26.6 (17F113) macOS command-line process Security.framework SessionGetInfo ASID obtained from the kernel-provided audit token in a received Mach message I’m implementing a security-sensitive Mach IPC receiver. The receiver obtains the sender’s audit token from the Mach message trailer and derives the sender PID, effective UID, and audit session ID (ASID). The sender executable identity is validated separately. Given the ASID, SessionGetInfo can successfully return the corresponding SecuritySessionId and session attributes. The question is about the freshness and synchronization semantics of that lookup. At the point where the receiver authorizes a request, can a successful SessionGetInfo(asid, ...) result be treated as authoritative evidence that the corresponding login/audit session is still currently valid? In particular: What happens if the session logs out, terminates, or is revoked concurrently with the lookup? Can SessionGetInfo successfully return information for a session that is no longer current due to caching or propagation delay? Are there documented ordering or synchronization guarantees between session termination and subsequent SessionGetInfo calls from another process? Can the lookup block for an unbounded period if the underlying security service is unavailable? Is there a supported timeout or cancellation mechanism? Is there another supported public macOS API better suited to establishing authoritative current-session liveness for an ASID obtained from an audit token? The security requirement is fail-closed. I’m specifically trying to avoid private APIs, process-table heuristics, diagnostic launchctl output, or assumptions that the ASID encoded in a previously received audit token necessarily represents current session state. If the public API does not provide an authoritative liveness/freshness guarantee, confirmation of that limitation would also answer the design question. I also have a minimal 122-line Xcode sample that: creates and receives a Mach message, reads the kernel-provided audit trailer, extracts the ASID, calls SessionGetInfo, and prints the returned session ID and attributes. I can provide the sample project if useful.
Replies
16
Boosts
0
Views
600
Activity
1w
Supported memory-limit increase for an iOS Enhanced Security helper extension
We’re using an Enhanced Security helper extension with AppExtensionProcess and XPCSession to isolate native zero-knowledge proof generation from wallet and signing code. On an iPhone 15 Pro running iOS 26.6.2 (23G90), the helper terminates with: EXC_RESOURCE RESOURCE_TYPE_MEMORY: high watermark memory limit exceeded (limit=35 MB) Terminated due to memory issue Our current prover requires substantially more memory: its public proving key is approximately 402 MiB, and its witness workspace alone is approximately 69 MiB. The same proof engine has completed successfully in a standalone iOS app process. The helper currently processes only synthetic test inputs. We want to preserve the helper’s sandbox and Enhanced Security protections and use a configuration supported for App Store distribution. Is there a supported way to increase the memory limit for this specific helper extension type? Does com.apple.developer.kernel.increased-memory-limit apply to Enhanced Security helper extensions? If so, what provisioning, target configuration, and device/OS requirements apply?
Replies
4
Boosts
1
Views
334
Activity
1w
Title: Supported OS-enforced restriction of Keychain access while retaining App Sandbox and App Group UDS
I’m designing a small, controlled macOS test harness. Two separately signed, sandboxed applications communicate through a UNIX-domain socket in an App Group container. They run as non-root processes in a GUI user session. One application also launches a child that inherits its sandbox and an existing socket descriptor. Is there a documented, supported OS policy that preserves this IPC arrangement while preventing the test processes from retrieving, using or modifying credentials, including items in their own Data Protection Keychain access groups and reachable file-based keychains? The policy must also prevent creating credential stores/items outside the permitted test resources. Using a macOS-style TeamID-prefixed App Group avoids that group providing Keychain sharing, but does not establish denial of the remaining Keychain operations. Empty stores, avoiding API calls and relying on users refusing prompts are insufficient for this requirement. If a different execution context or isolation architecture is required, could you identify the supported mechanism and relevant documentation? I’m seeking platform guidance, without relying on private APIs or unsupported custom sandbox profiles.
Replies
3
Boosts
0
Views
325
Activity
2w
Is there a supported per-boot identifier that can't be reset or rolled back by a backup restore?
I'm looking for a documented, supported way for an iOS app to tell, on-device and without network access, that the device has restarted or been restored from a backup since a given point. The goal is to fail closed after either event. It is not to identify the device or user, and the value would never leave the device. I'm aware of the existing forum guidance (for example thread 110044 and thread 809339), which describes best-effort techniques. I'm asking whether a guaranteed mechanism exists. Specifically, does iOS provide a supported public API, or a documented combination of APIs, that offers all of the following: Unique per boot. A value guaranteed never to repeat across boots of the same device. This would cover every kind of restart: graceful shutdown, forced or watchdog reset, kernel panic, and power loss or battery depletion. Not resettable or rolled back. A value the app itself cannot reset, that deleting and reinstalling the app doesn't reset, and that restoring a backup can neither reset nor roll back to an earlier value. Changes on every same-device restore. A signal guaranteed to change observably whenever a backup is restored to the same physical device, from iCloud Backup or an encrypted Finder backup, with or without Erase All Content and Settings first. It must not be stored in, derived from, or rolled back by anything a backup restores. If no such API exists, it would help to know that too. And if some of these properties hold only as current implementation behavior rather than a documented guarantee, I'd appreciate knowing which. Thanks!
Replies
4
Boosts
0
Views
131
Activity
2w
macOS /etc/ssl/cert.pem still trusts the eMudhra roots: curl and python3 accept the compromised intermediates
Apple blocked the eight compromised eMudhra intermediate CAs (CVE-2026-111943) for Security.framework clients. But on macOS 27.0.1 (26A434), /usr/bin/curl and /usr/bin/python3 still accept certificates from them. These tools verify against /etc/ssl/cert.pem and do not check revocation. The file (dated Sep 24) still contains both roots that the compromised intermediates chain to: emSign ECC Root CA - G3 AAA Certificate Services To reproduce, with SSL_CERT_FILE and CURL_CA_BUNDLE not set: /usr/bin/curl -sS -o /dev/null -w '%{exitcode}\n' https://dv-g3b-emudhra.we-have-a-problem.com/ # 0 — the connection succeeds grep -E 'emSign ECC Root CA - G3|AAA Certificate Services' /etc/ssl/cert.pem # both roots are presentWith a CA bundle that does not have these roots (Homebrew ca-certificates), the same command fails with "unable to get local issuer certificate". So the system bundle is the cause. softwareupdate -l shows no update. Questions: Does Apple plan to update /etc/ssl/cert.pem for this, and will the security notes say so? Until then, is setting SSL_CERT_FILE to a separate bundle the recommended workaround for the system tools?
Replies
1
Boosts
0
Views
170
Activity
2w