Prioritize user privacy and data security in your app. Discuss best practices for data handling, user consent, and security measures to protect user information.

All subtopics
Posts under Privacy & Security topic

Post

Replies

Boosts

Views

Activity

Privacy & Security Resources
General: Forums topic: Privacy & Security Privacy Resources Security Resources Share and Enjoy — Quinn “The Eskimo!” @ Developer Technical Support @ Apple let myEmail = "eskimo" + "1" + "@" + "apple.com"
0
0
501
Jul ’25
Clarification on Apple Sign-In Integration Across Multiple Applications
Dear Apple Support Team, I hope this message finds you well. Our tech team is currently working on integrating the Apple Sign-In feature, and we have a specific query where we would appreciate your guidance. Background Context: We have several applications across different brands and are aiming to implement a unified sign-up and sign-in experience. Currently, we are utilizing a shared website to enable single sign-in functionality across all these applications. Our Query: If we embed the same website in all of these applications and implement the Apple Sign-In within this website—using a dedicated Service ID that is configured with the App Store name and icon—will users consistently see the Apple Sign-In pop-up with the Service ID’s name and icon, regardless of which base application (e.g., App A, App B, etc.) the website is accessed from? We would like to ensure a seamless and consistent user experience and want to confirm that the branding within the Apple Sign-In prompt will reflect the Service ID’s configuration, rather than that of the hosting app. Looking forward to your guidance on this matter.
0
0
86
Apr ’25
Privacy Resources
General: Forums topic: Privacy & Security Forums tag: Privacy Developer > Security — This also covers privacy topics. App privacy details on the App Store UIKit > Protecting the User’s Privacy documentation Bundle Resources > Privacy manifest files documentation TN3181 Debugging an invalid privacy manifest technote TN3182 Adding privacy tracking keys to your privacy manifest technote TN3183 Adding required reason API entries to your privacy manifest technote TN3184 Adding data collection details to your privacy manifest technote TN3179 Understanding local network privacy technote Handling ITMS-91061: Missing privacy manifest forums post Share and Enjoy — Quinn “The Eskimo!” @ Developer Technical Support @ Apple let myEmail = "eskimo" + "1" + "@" + "apple.com"
0
0
212
Jul ’25
Received my first Digital Services Act spam
Like many/most developers, I gave Connect the info required to comply with the DSA. Perhaps unlike most, I always give unique email addresses so that I can easily track the source of abuse. Yesterday I finally had a phish come in to my DSA address claiming "Message blocked" and doing the standard click-to-login-for-details FOMO bait. So, yep, DSA just becomes yet another public database that malicious actors can use to target you. It would be really nice if Apple provided a way to supply our contact info only for legitimate business purposes. Mail Privacy Protection (or similar) for this would be a start.
1
0
77
Apr ’25
The Case for Sandboxing a Directly Distributed App
I’ve explained this point many times on the forums, so I figured I’d write it up properly once and for all. If you have questions or comments, start a new thread in Privacy & Security > General and add the App Sandbox tag. That way I’ll be sure to see it. Share and Enjoy — Quinn “The Eskimo!” @ Developer Technical Support @ Apple let myEmail = "eskimo" + "1" + "@" + "apple.com" The Case for Sandboxing a Directly Distributed App Many folks consider the App Sandbox to be a binary choice: “My app ships in the Mac App Store, so I must sandbox it.” “I directly distribute my app, so I’ll ignore the App Sandbox.” However, those are not your only options. In many cases it makes sense to sandbox a directly distributed app. Sandboxing your app has at least three benefits: It enables app container protection. See Trusted Execution Resources for a link to more info on that. If your app includes any app extensions, it simplifies your development experience because your app and its extensions run in a similar environment. It improves your app’s security (although the actual benefits vary based on the specifics of your app). Sandboxing some apps can be tricky because of the additional security limits applied by the sandbox. However, in a directly distributed app you have access to two techniques that are not available to Mac App Store apps: Temporary exception entitlements Non-sandboxed XPC services Temporary exception entitlements Use temporary exception entitlements to selectively disable specific sandbox security limits. Imagine, for example, that you’re creating a simple document-based app that’s generally compatible with the sandbox. However, that app needs to send an Apple event to Music to create a playlist. That Apple event is blocked by the sandbox. You don’t need to disable the entire App Sandbox just to get around this security limit. Instead, use the com.apple.security.temporary-exception.apple-events entitlement to open a small hole in the sandbox. There are temporary exception entitlements to disable most sandbox security limits. For more information about them, follow the link in App Sandbox Resources. IMPORTANT Don’t be alarmed by the temporary in temporary exception entitlements. That word makes sense when you view this from the Mac App Store perspective. Back in the early days of the Mac App Store, some apps were allowed to use temporary exception entitlements because of limitations in the App Sandbox. Once App Sandbox was sufficiently enhanced, these temporary exception entitlements were no longer allowed in the Mac App Store. However, there’s nothing temporary about the implementation of these entitlements. They work today and are expected to continue working in the future. Using them in a directly distributed app is not a problem. Non-sandboxed XPC services Not all sandbox security limits have a corresponding temporary exception entitlement. For example, the sandbox prevents you from sending a Unix signal to other processes, and there’s no temporary exception entitlement to allow that. If you run into such a limit, move that code to a non-sandboxed XPC service, then have the main app request that the XPC service perform the operation on its behalf. An XPC service can be useful even when there is a temporary exception entitlement to disable a specific sandbox security limit. Continuing the Apple event example from above, if you put the code that sends the Apple event into an XPC service, you only need to apply the temporary exception entitlement to that service, not to your app as a whole. Conclusion If you directly distribute your app, consider enabling the App Sandbox. It has some important benefits, and it might be more feasible than you think.
0
0
497
Mar ’25
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
App Sandbox Resources
General: Forums subtopic: Privacy & Security > General Forums tag: App Sandbox App Sandbox documentation App Sandbox Design Guide documentation — This is no longer available from Apple. There’s still some info in there that isn’t covered by the current docs but, with the latest updates, it’s pretty minimal (r. 110052019). Still, if you’re curious, you can consult an old copy [1]. App Sandbox Temporary Exception Entitlements archived documentation — To better understand the role of temporary exception entitlements, see this post. Embedding a command-line tool in a sandboxed app documentation Discovering and diagnosing App Sandbox violations (replaces the Viewing Sandbox Violation Reports forums post) Resolving App Sandbox Inheritance Problems forums post The Case for Sandboxing a Directly Distributed App forums post Implementing Script Attachment in a Sandboxed App forums post Share and Enjoy — Quinn “The Eskimo!” @ Developer Technical Support @ Apple let myEmail = "eskimo" + "1" + "@" + "apple.com" [1] For example, this one archived by the Wayback Machine.
0
0
2.9k
Jul ’25
XCode claims that tracking domains are not listed in the Privacy Manifest
Hi, Xcode Instruments shows multiple Points of Interest with the information that the framework is not listed in my Privacy Manifest. However, I have already included them in the Privacy Manifest under the privacy tracking domains. I have this problem with every tracking domain i listed in the Privacy Manifest's Privacy Tracking Domains. Did I make a mistake in my Privacy Manifest declaration?
0
0
171
May ’25
Questions about user impact and best practices for rotating the private key used for Sign in with Apple
Hi, We are operating a service that uses Sign in with Apple for user registration and login. As part of our security incident response and periodic security improvements, we are planning to rotate the private key used to generate the client secret (JWT) for Sign in with Apple. I have read the Human Interface Guidelines and the AuthenticationServices documentation, but I could not find a clear description of the behavior and user impact when rotating this private key. I would like to ask the following questions: Background: We issue a Sign in with Apple private key (with a Key ID) in our Apple Developer account. Our server uses this private key to generate the client secret (JWT). This is used for Sign in with Apple login on our web / mobile app. We are planning to invalidate the existing private key and switch to a newly issued one. Questions: Impact on existing logged-in sessions Will rotating the private key force already logged-in users (who previously signed in with Apple) to be logged out from our service? Can the user identifier (such as the "sub" claim) for existing Sign in with Apple users change due to key rotation? Recommended frequency and best practices Does Apple recommend rotating this private key only when it is compromised, or on a regular basis? If there are any official documents or examples that describe how to safely perform key rotation in production, we would appreciate a pointer. Impact on marketing / analytics We are using user IDs (linked via Sign in with Apple) for analytics and marketing attribution. Is there any expected impact on such use cases caused by rotating the private key? For example, is there any possibility that user identifiers change as a result of key rotation, or anything we should be careful about from a data linkage perspective? Our goal is to rotate the private key in a secure way without causing service downtime, mass logouts, or loss of account linkage. If there is already an official document that covers this, please let me know the URL. Thank you in advance.
0
0
129
Dec ’25
Outlook for Mac add-in - Passkeys
hello, My organization has an outlook add-in that requires auth into our platform. As Microsoft forces Auth on MacOS to use WKWebView https://learn.microsoft.com/en-us/office/dev/add-ins/concepts/browsers-used-by-office-web-add-ins, we are running into a situation that we cannot use passkeys as an auth method as we are unable to trigger WebAuthN flows. We’ve raised this in Microsoft side but they have deferred to Apple given WKWebView is Safari based. This is a big blocker for us to achieve a full passwordless future. Has anyone come across this situation? Thank you.
0
0
356
Aug ’25
Detecting iOS screen sharing
Hello, Is there any way to detect if the iOS screen is currently being shared via FaceTime or iPhone Mirroring? Our application relies on this information to help ensure that users are not accessing it from one location while physically being in another.
1
0
216
Jul ’25
Cannot update ASCredentialIdentityStore while device locked
Our product includes a background sync process that synchronizes credentials between devices. We need to update ASCredentialIdentityStore when credentials are changed, we have noticed that the ASCredentialIdentityStore.shared.saveCredentialIdentities() fails to run when the device is locked. Is it possible to update ASCredentialIdentityStore when the device is locked?
0
0
88
Apr ’25
Incorrect Branding and Messaging Displayed on "Call Customer Center" Feature
We’ve identified an issue in our app where, upon clicking the "Call Customer Center" button, users are unexpectedly shown a logo and message option on a native pop-up window. However, this wasn't the case before, and it should only display a phone number to dial, which was given inside our code. This is incorrect and misleading for our users, as: We are a Canadian-based service and have no affiliation with US messaging chat. The messaging feature was never enabled or intended for our app. Our app should only initiate a phone call to our customer support center — no messages or branding from third parties should appear
0
0
118
Jun ’25
Authentication using MSAL library in offline mode
Hi. We are trying to get the access token before calling any API. The app can go in bad network areas but the token acquisition keeps happening for the network call. The devices are managed devices which means it has some policies installed. We are using MSAL lib for the authentication and we are investigating from that angle too but the below error seems to be coming from apple authentication which needs our attention. ========================================== LaunchServices: store (null) or url (null) was nil: Error Domain=NSOSStatusErrorDomain Code=-54 "process may not map database" UserInfo={NSDebugDescription=process may not map database, _LSLine=68, _LSFunction=_LSServer_GetServerStoreForConnectionWithCompletionHandler} Attempt to map database failed: permission was denied. This attempt will not be retried. Failed to initialize client context with error Error Domain=NSOSStatusErrorDomain Code=-54 "process may not map database" UserInfo={NSDebugDescription=process may not map database, _LSLine=68, _LSFunction=_LSServer_GetServerStoreForConnectionWithCompletionHandler} Failed to get application extension record: Error Domain=NSOSStatusErrorDomain Code=-54 "(null)" ASAuthorizationController credential request failed with error: Error Domain=com.apple.AuthenticationServices.AuthorizationError Code=1003 "(null)" ========================================== This happens mostly when we switches the network or keep the device in no or low network area. This comes sometimes when app goes in background too. Just trying to give as much as information I could. Any lead would be highly appreciated. Thank you
0
0
131
Apr ’25
Need support downloading key
I’ve been running into an issue for over a day when trying to create a Sign in with Apple key. Each time I attempt to download it, I’m redirected to a page that displays an error and provides no further guidance. I’ve contacted Support and haven’t yet received a reply. I’ve also tried across multiple browsers (Chrome, Safari, Firefox), including incognito modes. Any ideas on how to resolve this? We’re currently stuck and would appreciate guidance.
2
0
132
Apr ’25
Trusted Execution Resources
Trusted execution is a generic name for a Gatekeeper and other technologies that aim to protect users from malicious code. General: Forums topic: Code Signing Forums tag: Gatekeeper Developer > Signing Mac Software with Developer ID Apple Platform Security support document Safely open apps on your Mac support article Hardened Runtime document WWDC 2022 Session 10096 What’s new in privacy covers some important Gatekeeper changes in macOS 13 (starting at 04: 32), most notably app bundle protection WWDC 2023 Session 10053 What’s new in privacy covers an important change in macOS 14 (starting at 17:46), namely, app container protection WWDC 2024 Session 10123 What’s new in privacy covers an important change in macOS 15 (starting at 12:23), namely, app group container protection Updates to runtime protection in macOS Sequoia news post Testing a Notarised Product forums post Resolving Trusted Execution Problems forums post App Translocation Notes (aka Gatekeeper path randomisation) forums post Most trusted execution problems are caused by code signing or notarisation issues. See Code Signing Resources and Notarisation Resources. Share and Enjoy — Quinn “The Eskimo!” @ Developer Technical Support @ Apple let myEmail = "eskimo" + "1" + "@" + "apple.com"
0
0
3.4k
Jan ’26
Conditional create on iPhone + Safari + Passwords violates the WebAuthn spec
WebAuthn Level 3 § 5.1.3 Step 22 Item 4 states the steps a user agent MUST follow when "conditional" mediation is used in conjunction with required user verification: Let userVerification be the effective user verification requirement for credential creation, a Boolean value, as follows. If pkOptions.authenticatorSelection.userVerification is set to required If options.mediation is set to conditional and user verification cannot be collected during the ceremony, throw a ConstraintError DOMException. Let userVerification be true. On my iPhone 15 Pro Max running iOS 18.5, Safari + Passwords does not exhibit this behavior; instead an error is not reported and user verification is not performed (i.e., the UV bit is 0). Per the spec this results in a registration ceremony failure on the server which is made all the more "annoying" since the credential was created in Passwords forcing a user to then delete the credential. : If the Relying Party requires user verification for this registration, verify that the UV bit of the flags in authData is set. In contrast when I use Google Password Manager + Chrome on a Samsung Galaxy S24 running Android 15, user verification is enforced and the UV bit is 1. Either the UV bit should be 1 after enforcing user verification or an error should be thrown since user verification cannot be performed.
1
0
519
Jul ’25
Not receiving Sign in with Apple Server-to-Server Notifications despite correct configuration
I received a notification stating that we need to register a server-to-server notification endpoint to handle the following three events: Changes in email forwarding preferences. Account deletions in your app. Permanent Apple Account deletions. However, even though we have registered the API endpoint under our Identifier configuration, it appears that we are not receiving any API calls when these events trigger. I honestly have no idea what’s going wrong. I’ve checked our WAF logs and there’s no trace of any incoming traffic at all. Is it possible that Apple hasn't started sending these notifications yet, or is there something I might be missing? I’m stuck and don’t know how to resolve this. I would really appreciate any help or insights you could share. Thank you.
0
0
255
Jan ’26
passkey in iOS via iCloudKeyChain
I have a very basic binary question around passkeys. Assuming everything is on latest and greatest version with respect to iOS, when user starts creating a passkey in platform-authenticator i.e., iCloudKeyChain (Apple Password Manager) , will iCloudKeyChain create a hardware-bound passkey in secure-enclave i.e., is brand new key-pair created right inside Secure-enclave ? OR will the keypair be created in software i.e., software-bound-passkey ?? i.e., software-bound keypair and store the private-key locally in the device encrypted with a key that is of course created in secure-enclave.
1
0
162
May ’25