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

requestTrackingAuthorization stuck in .notDetermined
When developing and testing using my phone I got prompted for allowing app tracking. I later uploaded a build to TestFlight, deleted the old testing app and installed the TestFlight build. I am now stuck in an infinite loop of not getting prompted for allowing app tracking for the app. When entering the app settings the toggle for tracking never appears which leaves me not able to enter the app's content. My guess is that the prompt can only be shown once for the app bundle, but there has to be a way for me to get prompted again without changing the app bundle id. Help is appreciated since this app is scheduled to be published in a week.
0
0
136
May ’25
Can't get user info more than once upon signin ?
Hi, I know it's been discussed before, but I'm testing the Sign in with Apple feature, and I only get the user info on the first try. Now, I know that you're supposed to go to the account settings, and look for the list of accounts that you used your Apple account to sign in with, and it used to work a few months back. But for the last few weeks I haven't been able to get the user info, even after deleting the entry from my Sign In With Apple app list. Has there been a recent change to Apple security policy that prevents such a move from working ? Or am I doing something wrong ? Thank you
0
0
319
Feb ’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
121
Apr ’25
Which in-app events are allowed without ATT consent?
Hi everyone, I'm developing an iOS app using the AppsFlyer SDK. I understand that starting with iOS 14.5, if a user denies the App Tracking Transparency (ATT) permission, we are not allowed to access the IDFA or perform cross-app tracking. However, I’d like to clarify which in-app events are still legally and technically safe to send when the user denies ATT permission. Specifically, I want to know: Is it acceptable to send events like onboarding_completed, paywall_viewed, subscription_started, subscribe, subscribe_price, or app_opened if they are not linked to IDFA or any form of user tracking? Would sending such internal behavioral events (used purely for SKAdNetwork performance tracking or in-app analytics) violate Apple’s privacy policy if no device identifiers are attached? Additionally, if these events are sent in fully anonymous form (i.e., not associated with IDFA, user ID, email, or any identifiable metadata), does Apple still consider this a privacy concern? In other words, can onboarding_completed, paywall_viewed, subsribe, subscribe_price, etc., be sent in anonymous format without violating ATT policies? Are there any official Apple guidelines or best practices that outline what types of events are considered compliant in the absence of ATT consent? My goal is to remain 100% compliant with Apple’s policies while still analyzing meaningful user behavior to improve the in-app experience. Any clarification or pointers to documentation would be greatly appreciated. Thanks in advance!
0
0
178
Jun ’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
78
Apr ’25
api and data collection app stroe connect
I added a feature to my app that retrieves only app settings (no personal data) from my API hosted on Cloudflare Workers. The app does not send, collect, track, or share any user data, and I do not store or process any personal information. Technical details such as IP address, user agent, and device information may be automatically transmitted as part of the internet protocol when the request is made, but my app does not log or use them. Cloudflare may collect this information. Question: Does this count as “data collection” for App Store Connect purposes, or can I select “No Data Collected”?
0
0
429
Aug ’25
iOS Biometric Authentication Implementation when biometric is added
Current Setup: Using Secure Enclave with userPresence access control Foreground keychain accessibility: whenPasscodeSetThisDeviceOnly Security Requirement: Our security group wants us to invalidate biometrics and require a username/password if a biometric item is added (potentially by a hostile 3rd party) Need to upgrade from userPresence to biometricCurrentSet to ensure re-authentication when biometric credentials change. Issue: After implementing biometricCurrentSet, authentication cancels after two failed biometric attempts instead of falling back to passcode. Current Detection Method: User completes initial biometric authentication Biometric changes occur (undetectable by app) App attempts Secure Enclave access Access denial triggers re-authentication requirement Cannot revoke refresh token after access is denied Security Concern: Current implementation allows new biometric enrollments to access existing authenticated sessions without re-verification. Question: What's the recommended approach to: Implement biometricCurrentSet while maintaining passcode fallback Properly handle refresh token invalidation when biometric credentials change Looking for guidance on best practices for implementing these security requirements while maintaining good UX.
0
0
442
Feb ’25
App Attest development server (data-development.appattest.apple.com) returns 403 for CBOR attestation request
Hi, I’m currently implementing App Attest attestation validation on the development server. However, I’m receiving a 403 Forbidden response when I POST a CBOR-encoded payload to the following endpoint: curl -X POST -H "Content-Type: application/cbor" --data-binary @payload.cbor 'https://data-development.appattest.apple.com' Here’s how I’m generating the CBOR payload in Java: Map<String, Object> payload = new HashMap<>(); payload.put("attestation", attestationBytes); // byte[] from DCAppAttestService payload.put("clientDataHash", clientDataHash); // SHA-256 hash of the challenge (byte[]) payload.put("keyId", keyIdBytes); // Base64-decoded keyId (byte[]) payload.put("appId", TEAM_ID + "." + BUNDLE_ID); // e.g., "ABCDE12345.com.example.app" ObjectMapper cborMapper = new ObjectMapper(new CBORFactory()); byte[] cborBody = cborMapper.writeValueAsBytes(payload); I’m unsure whether the endpoint is rejecting the payload format or if the endpoint itself is incorrect for this stage. I’d appreciate clarification on the following: 1. Is https://data-development.appattest.apple.com the correct endpoint for key attestation in a development environment? 2. Should this endpoint accept CBOR-encoded payloads, or is it only for JSON-based assertion validation? 3. Is there a current official Apple documentation that lists: • the correct URLs for key attestation and assertion validation (production and development), • or any server-side example code (e.g., Java, Python) for handling attestation/validation on the backend? So far, I couldn’t find an official document that explicitly describes the expected HTTP endpoints for these operations. If there’s a newer guide or updated API reference, I’d appreciate a link. Thanks in advance for your help.
0
0
163
May ’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
139
May ’25
Apple Sign-In Not Returning First Name and Last Name Despite name Scope Requested
Hi Apple Developer Team, I am encountering an issue with the “Sign in with Apple” feature. While implementing this functionality in my dotnet application, I noticed that the user’s first name and last name are not being returned, even though I have explicitly requested the name scope. However, the email and other requested information are returned successfully. Here are the details of my implementation: 1. Scope Requested: name, email 2. Response Received: Email and other data are present, but fullName is missing or null. 3. Expected Behavior: I expected to receive the user’s first and last name as per the fullName scope. I have verified the implementation and ensured that the correct scopes are being passed in the request. Could you please help clarify the following? 1. Are there specific conditions under which Apple may not return the user’s fullName despite the scope being requested? 2. Is there a recommended approach or fallback mechanism to handle this scenario? 3. Could this behavior be related to a limitation or change in the API, or might it be an issue on my end? I also came to know that for initial sign in the user details will be displayed in the signin-apple payload as Form data but how do I fetch those form-data from the signin-apple request, please suggest I would greatly appreciate any guidance or solutions to resolve this issue. Thank you for your support!
0
4
245
Mar ’25
Password AutoFill does not pick up saved password in developer mode
Without developer mode, I was able to get Password AutoFill to work in my SwiftUI app with my local Vapor server using ngrok and adding the Associated Domains capability with the value webcredentials:....ngrok-free.app and the respective apple-app-site-association file on my local server in /.well-known/. (works on device, but not in the simulator). However, if I use the developer mode (webcredentials:....ngrok-free.app?mode=developer) it only works halfway when running from Xcode: I get asked to save the password, but the saved passwords are not picked up, when I try to login again. Neither on device, nor in the simulator. If I remove the ?mode=developer it seems to work as expected. Is this by design, or am I missing something? var body: some View { ... Section(header: Text("Email")) { TextField("Email", text: $viewModel.credentials.username) .textContentType(.username) .autocapitalization(.none) .keyboardType(.emailAddress) } Section(header: Text("Passwort")) { SecureField("Passwort", text: $viewModel.credentials.password) .textContentType(.password) } ... }
0
0
206
May ’25
Sign in with Apple in a broken state (for my account)
I have a user (myself, during development) who originally signed in with Apple successfully. I attempted to revoke access via Settings > Apple ID > Sign-In & Security > Sign in with Apple, but the app appears stuck in the list and cannot be fully removed. Now when attempting to sign in again, the identity token contains the correct sub but email is undefined. According to Apple's documentation, "Apple provides the user's email address in the identity token on all subsequent API responses." I've tried programmatically revoking via the /auth/revoke endpoint (received 200 OK), and I've implemented the server-to-server notification endpoint to handle consent-revoked events, but subsequent sign-in attempts still return no email. The same Apple ID works fine with other apps. Is there a way to fully reset the credential state for a specific app, or is this a known issue with partially-revoked authorizations?
0
0
289
5d
Importing a PEM-based RSA Private Key and its Certificate
This post is an extension to Importing Cryptographic Keys that covers one specific common case: importing a PEM-based RSA private key and its certificate to form a digital identity. If you have questions or comments, start a new thread in Privacy & Security > General. Tag your thread with Security so that I see it. Share and Enjoy — Quinn “The Eskimo!” @ Developer Technical Support @ Apple let myEmail = "eskimo" + "1" + "@" + "apple.com" Importing a PEM-based RSA Private Key and its Certificate I regularly see folks struggle to import an RSA private key and its corresponding certificate. Importing Cryptographic Keys outlines various options for importing keys, but in this post I want to cover one specific case, namely, a PEM-based RSA private key and its corresponding certificate. Together these form a digital identity, represented as a SecIdentity object. IMPORTANT If you can repackage your digital identity as a PKCS#12, please do. It’s easy to import that using SecPKCS12Import. If you can switch to an elliptic curve (EC) private key, please do. It’s generally better and Apple CryptoKit has direct support for importing an EC PEM. Assuming that’s not the case, let’s explore how to import a PEM-base RSA private key and its corresponding certificate to form a digital identity. Note The code below was built with Xcode 16.2 and tested on the iOS 18.2 simulator. It uses the helper routines from Calling Security Framework from Swift. This code assumes the data protection keychain. If you’re targeting macOS, add kSecUseDataProtectionKeychain to all the keychain calls. See TN3137 On Mac keychain APIs and implementations for more background to that. Unwrap the PEM To start, you need to get the data out of the PEM: /// Extracts the data from a PEM. /// /// As PEM files can contain a large range of data types, you must supply the /// expected prefix and suffix strings. For example, for a certificate these /// are `"-----BEGIN CERTIFICATE-----` and `-----END CERTIFICATE-----`. /// /// - important: This assumes the simplest possible PEM format. It does not /// handle metadata at the top of the PEM or PEMs with multiple items in them. func dataFromPEM(_ pem: String, _ expectedPrefix: String, _ expectedSuffix: String) -> Data? { let lines = pem.split(separator: "\n") guard let first = lines.first, first == expectedPrefix, let last = lines.last, last == expectedSuffix else { return nil } let base64 = lines.dropFirst().dropLast().joined() guard let data = Data(base64Encoded: base64) else { return nil } return data } IMPORTANT Read the doc comment to learn about some important limitations with this code. Import a Certificate When adding a digital identity to the keychain, it’s best to import the certificate and the key separately and then add them to the keychain. That makes it easier to track down problems you encounter. To import a PEM-based certificate, extract the data from the PEM and call SecCertificateCreateWithData: /// Import a certificate in PEM format. /// /// - important: See ``dataFromPEM(_:_:_:)`` for some important limitations. func importCertificatePEM(_ pem: String) throws -> SecCertificate { guard let data = dataFromPEM(pem, "-----BEGIN CERTIFICATE-----", "-----END CERTIFICATE-----"), let cert = SecCertificateCreateWithData(nil, data as NSData) else { throw NSError(domain: NSOSStatusErrorDomain, code: Int(errSecParam), userInfo: nil) } return cert } Here’s an example that shows this in action: let benjyCertificatePEM = """ -----BEGIN CERTIFICATE----- MIIC4TCCAcmgAwIBAgIBCzANBgkqhkiG9w0BAQsFADAfMRAwDgYDVQQDDAdNb3Vz ZUNBMQswCQYDVQQGEwJHQjAeFw0xOTA5MzAxNDI0NDFaFw0yOTA5MjcxNDI0NDFa MB0xDjAMBgNVBAMMBUJlbmp5MQswCQYDVQQGEwJHQjCCASIwDQYJKoZIhvcNAQEB BQADggEPADCCAQoCggEBAOQe5ai68FQhTVIgpsDK+UOPIrgKzqJcW+wwLnJRp6GV V9EmifJq7wjrXeqmP1XgcNtu7cVhDx+/ONKl/8hscak54HTQrgwE6mK628RThld9 BmZoOjaWWCkoU5bH7ZIYgrKF1tAO5uTAmVJB9v7DQQvKERwjQ10ZbFOW6v8j2gDL esZQbFIC7f/viDXLsPq8dUZuyyb9BXrpEJpXpFDi/wzCV3C1wmtOUrU27xz4gBzi 3o9O6U4QmaF91xxaTk0Ot+/RLI70mR7TYa+u6q7UW/KK9q1+8LeTVs1x24VA5csx HCAQf+xvMoKlocmUxCDBYkTFkmtyhmGRN52XucHgu0kCAwEAAaMqMCgwDgYDVR0P AQH/BAQDAgWgMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMCMA0GCSqGSIb3DQEBCwUA A4IBAQAyrArH7+IyHTyEOrv/kZr3s3h4HWczSVeiO9qWD03/fVew84J524DiSBK4 mtAy3V/hqXrzrQEbsfyT7ZhQ6EqB/W0flpVYbku10cSVgoeSfjgBJLqgJRZKFonv OQPjTf9HEDo5A1bQdnUF1y6SwdFaY16lH9mZ5B8AI57mduSg90c6Ao1GvtbAciNk W8y4OTQp4drh18hpHegrgTIbuoWwgy8V4MX6W39XhkCUNhrQUUJk3mEfbC/yqfIG YNds0NRI3QCTJCUbuXvDrLEn4iqRfbzq5cbulQBxBCUtLZFFjKE4M42fJh6D6oRR yZSx4Ac3c+xYqTCjf0UdcUGxaxF/ -----END CERTIFICATE----- """ print(try? importCertificatePEM(benjyCertificatePEM)) If you run this it prints: Optional(<cert(0x11e304c10) s: Benjy i: MouseCA>) Import a Private Key To import a PEM-base RSA private key, extract the data from the PEM and call SecKeyCreateWithData: /// Import an 2048-bit RSA private key in PEM format. /// /// Don’t use this code if: /// /// * If you can switch to an EC key. EC keys are generally better and, for /// this specific case, there’s support for importing them in Apple CryptoKit. /// /// * You can switch to using a PKCS#12. In that case, use the system’s /// `SecPKCS12Import` routine instead. /// /// - important: See ``dataFromPEM(_:_:_:)`` for some important limitations. func importRSA2048PrivateKeyPEM(_ pem: String) throws -> SecKey { // Most private key PEMs are in PKCS#8 format. There’s no way to import // that directly. Instead you need to strip the header to get to the // `RSAPrivateKey` data structure encapsulated within the PKCS#8. Doing that // in the general case is hard. In the specific case of an 2048-bit RSA // key, the following hack works. let rsaPrefix: [UInt8] = [ 0x30, 0x82, 0x04, 0xBE, 0x02, 0x01, 0x00, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, 0x04, 0xA8, ] guard let pkcs8 = dataFromPEM(pem, "-----BEGIN PRIVATE KEY-----", "-----END PRIVATE KEY-----"), pkcs8.starts(with: rsaPrefix) else { throw NSError(domain: NSOSStatusErrorDomain, code: Int(errSecParam), userInfo: nil) } let rsaPrivateKey = pkcs8.dropFirst(rsaPrefix.count) return try secCall { SecKeyCreateWithData(rsaPrivateKey as NSData, [ kSecAttrKeyType: kSecAttrKeyTypeRSA, kSecAttrKeyClass: kSecAttrKeyClassPrivate, ] as NSDictionary, $0) } } IMPORTANT This code only works with 2048-bit RSA private keys. The comments explain more about that limitation. Here’s an example that shows this in action: let benjyPrivateKeyPEM = """ -----BEGIN PRIVATE KEY----- MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDkHuWouvBUIU1S IKbAyvlDjyK4Cs6iXFvsMC5yUaehlVfRJonyau8I613qpj9V4HDbbu3FYQ8fvzjS pf/IbHGpOeB00K4MBOpiutvEU4ZXfQZmaDo2llgpKFOWx+2SGIKyhdbQDubkwJlS Qfb+w0ELyhEcI0NdGWxTlur/I9oAy3rGUGxSAu3/74g1y7D6vHVGbssm/QV66RCa V6RQ4v8MwldwtcJrTlK1Nu8c+IAc4t6PTulOEJmhfdccWk5NDrfv0SyO9Jke02Gv ruqu1FvyivatfvC3k1bNcduFQOXLMRwgEH/sbzKCpaHJlMQgwWJExZJrcoZhkTed l7nB4LtJAgMBAAECggEBAKOPF6ED776SZgrliEog/dmXrhABB6jXybytyw+CRkuP dXhrRmr+isZ9Y0gTzMN4+dILVgW4EozzoP0/sgZ04oWwDqQS30eU2qzRRzMbo+3k oYsZXeu3nhxcYppwXIDsfAEd/ygMFzaadRPKYhrFykR2rA/dpLYCvW2tfm5SuULp RxnKykFlVi8yVT64AovVm0XGOy/QTO5BBbUdftvZY9QCjGn/IEL8QFEz0rxZsb2L s0HgVMUcB1My38RksZQRKLMWCtqLqWnez3oCnPka+dxFQj5RU//vNtRoVh1ExbmW txHz48v00AKQvaudC4ujIspZlY8+UPdYQT0TNjhsfoUCgYEA+7yEvyCgRtYwUNm6 jHTg67LoSldHwENOry63qGZp3rCkWBkPXle7ulgRtuw+e11g4MoMMAgkIGyIGB/Z 6YvnQGmJCTMw+HHIyw3k/OvL1iz4DM+QlxDuD79Zu2j2UIL4maDG0ZDskiJujVAf sFOy4r36TvYedmd7qgh9pgpsFl8CgYEA5/v8PZDs2I1wSDGllGfTr6aeQcxvw98I p8l/8EV/lYpdKQMFndeFZI+dnJCcTeBbeXMmPNTAdL5gOTwDReXamIAdr93k7/x6 iKMHzBrpQZUMEhepSd8zdR1+vLvyszvUU6lvNXcfjwbu7gJQkwbA6kSoXRN+C1Cv i5/w66t0f1cCgYBt02FWwTUrsmaB33uzq4o1SmhthoaXKsY5R3h4z7WAojAQ/13l GwGb2rBfzdG0oJiTeZK3odWhD7iQTdUUPyU0xNY0XVEQExQ3AmjUr0rOte/CJww9 2/UAicrsKG7N0VYEMFCNPVz4pGz22e35T4rLwXZi3J2NqrgZBntK5WEioQKBgEyx L4ii+sn0qGQVlankUUVGjhcuoNxeRZxCrzsdnrovTfEbAKZX88908yQpYqMUQul5 ufBuXVm6/lCtmF9pR8UWxbm4X9E+5Lt7Oj6tvuNhhOYOUHcNhRN4tsdqUygR5XXr E8rXIOXF4wNoXH7ewrQwEoECyq6u8/ny3FDtE8xtAoGBALNFxRGikbQMXhUXj7FA lLwWlNydCxCc7/YwlHfmekDaJRv59+z7SWAR15azhbjqS9oXWJUQ9uvpKF75opE7 MT0GzblkKAYu/3uhTENCjQg+9RFfu5w37E5RTWHD2hANV0YqXUlmH3d+f5uO0xN7 7bpqwYuYzSv1hBfU/yprDco6 -----END PRIVATE KEY----- """ print(try? importRSA2048PrivateKeyPEM(benjyPrivateKeyPEM)) If you run this it prints: Optional(<SecKeyRef algorithm id: 1, key type: RSAPrivateKey, version: 4, 2048 bits (block size: 256), addr: 0x600000c5ce50>) Form a Digital Identity There are two common ways to form a digital identity: SecPKCSImport SecItemCopyMatching SecPKCSImport is the most flexible because it gives you an in-memory digital identity. You can then choose to add it to the keychain or not. However, it requires a PKCS#12 as input. If you’re starting out with separate private key and certificate PEMs, you have to use SecItemCopyMatching. Note macOS also has SecIdentityCreateWithCertificate, but it has some seriously limitations. First, it’s only available on macOS. Second, it requires the key to be in the keychain. If you’re going to add the key to the keychain anyway, you might as well use SecItemCopyMatching. To form a digital identity from a separate private key and certificate: Add the certificate to the keychain. Add the private key to the keychain. Call SecItemCopyMatching to get back a digital identity. Here’s an example of that in action: /// Imports a digital identity composed of separate certificate and private key PEMs. /// /// - important: See ``dataFromPEM(_:_:_:)`` for some important limitations. /// See ``importRSA2048PrivateKeyPEM(_:)`` for alternative strategies that are /// much easier to deploy. func addRSA2048DigitalIdentityPEMToKeychain(certificate: String, privateKey: String) throws -> SecIdentity { // First import the certificate and private key. This has the advantage in // that it triggers an early failure if the data is in the wrong format. let certificate = try importCertificatePEM(certificate) let privateKey = try importRSA2048PrivateKeyPEM(privateKey) // Check that the private key matches the public key in the certificate. If // not, someone has given you bogus credentials. let certificatePublicKey = try secCall { SecCertificateCopyKey(certificate) } let publicKey = try secCall { SecKeyCopyPublicKey(privateKey) } guard CFEqual(certificatePublicKey, publicKey) else { throw NSError(domain: NSOSStatusErrorDomain, code: Int(errSecPublicKeyInconsistent)) } // Add the certificate first. If that fails — and the most likely error is // `errSecDuplicateItem` — we want to stop immediately. try secCall { SecItemAdd([ kSecValueRef: certificate, ] as NSDictionary, nil) } // The add the private key. do { try secCall { SecItemAdd([ kSecValueRef: privateKey, ] as NSDictionary, nil) } } catch let error as NSError { // We ignore a `errSecDuplicateItem` error when adding the key. It’s // possible to have multiple digital identities that share the same key, // so if you try to add the key and it’s already in the keychain then // that’s fine. guard error.domain == NSOSStatusErrorDomain, error.code == errSecDuplicateItem else { throw error } } // Finally, search for the resulting identity. // // I originally tried querying for the identity based on the certificate’s // attributes — the ones that contribute to uniqueness, namely // `kSecAttrCertificateType`, `kSecAttrIssuer`, and `kSecAttrSerialNumber` — // but that failed for reasons I don't fully understand (r. 144152660). So // now I get all digital identities and find the one with our certificate. let identities = try secCall { SecItemCopyMatching([ kSecClass: kSecClassIdentity, kSecMatchLimit: kSecMatchLimitAll, kSecReturnRef: true, ] as NSDictionary, $0) } as! [SecIdentity] let identityQ = try identities.first { i in try secCall { SecIdentityCopyCertificate(i, $0) } == certificate } return try secCall(Int(errSecItemNotFound)) { identityQ } } IMPORTANT This code is quite subtle. Read the comments for an explanation as to why it works the way it does. Further reading For more information about the APIs and techniques used above, see: Importing Cryptographic Keys On Cryptographic Keys Formats SecItem: Fundamentals SecItem: Pitfalls and Best Practices Calling Security Framework from Swift TN3137 On Mac keychain APIs and implementations Finally, for links to documentation and other resources, see Security Resources. Revision History 2025-02-13 Added code to check for mismatched private key and certificate. 2025-02-04 First posted.
0
0
618
Feb ’25
if I skip passkey setup, how long will lapse before I am asked by the OS to register for passkey again
I am currently unable to enable passkey in my app so I am having to tell my users to skip the prompts for using passkey. We have noticed that after a few times of this the OS will stop asking the user to register their passkey. The question is, how long does this last before the OS asks you to use passkey again? Is it permanent until you re-install the app? Just looking for a time frame if anyone knows.
0
0
468
Feb ’25
Application with identifier is not associated with domain
Hi, This issue is happening during Passkey creation. We’ve observed that approximately 1% of our customer users encounter a persistent error during Passkey creation. For the vast majority, the process works as expected. We believe our apple-app-site-association file is correctly configured, served directly from the RP ID over HTTPS without redirects, and is up-to-date. This setup appears to work for most users, and it seems the Apple CDN cache reflects the latest version of the file. To help us diagnose and address the issue for the affected users, we would appreciate guidance on the following: What tools or steps does Apple recommend to identify the root cause of this issue? Are there any known recovery steps we can suggest to users to resolve this on affected devices? Is there a way to force a refresh of the on-device cache for the apple-app-site-association file? Thank you in advance for any input or guidance.
0
1
151
May ’25
Apple Sign in Freeze
I was experiencing a weird sign in error when using apple sign in with my app and wanted to put it here for anyone else who might experience it in the future, and so apple can make this requirement more clear. I was using CloudKit and apple sign in. If you are not using both this probably does not apply to you. Every time I would go to sign in in the iOS simulator I would enter my password, hit "sign in", and everything just froze. The very odd reason for this is if you are using iCloudKit and apple sign in you need to go to specifically the "identifiers" in the "Certificates, Identifiers & Profiles" menu (https://developer.apple.com/account/resources/identifiers/list). And from there you specifically need an App ID Configuration with apple sign in enabled. From there you have to have the same exact bundle identifier in Xcode under project settings(not an upper tab just click your project in the left panel). And that should allow you to both pass validation and have your sign in work. Hope this helps!
0
0
172
Jun ’25
How to programmatically stop passkey in my app
I am using Auth0 as a login manager for our app. The way Auth0 handles login is that their SDK will create a web view where the login is actually handled. Once the login is finished the session will end and the app will gain control. We are not set up for passkeys in their system and can't set up quickly to do that. Unfortunately with the new iOS "passkey is the primary login" way iOS is set up now, users are asked to use passkey when it's not supported on the backend. I don't have direct control of the login screens. Is there any way, at the app level, to tell the app to not use passkeys so that it quits showing up as an option for the users? I can't find any documentation on doing this. How can I stop passkey in my app entirely?
0
0
316
Feb ’25