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

Created

Is there a way to hide the 'Save to another device' option during iOS WebAuthn registration?
Hello, I am currently implementing a biometric authentication registration flow using WebAuthn. I am using ASAuthorizationPlatformPublicKeyCredentialRegistrationRequest, and I would like to know if there is a way to hide the "Save to another device" option that appears during the registration process. Specifically, I want to guide users to save the passkey only locally on their device, without prompting them to save it to iCloud Keychain or another device. If there is a way to hide this option or if there is a recommended approach to achieve this, I would greatly appreciate your guidance. Also, if this is not possible due to iOS version or API limitations, I would be grateful if you could share any best practices for limiting user options in this scenario. If anyone has experienced a similar issue, your advice would be very helpful. Thank you in advance.
1
0
1.1k
Nov ’24
Deffie Hellman exchange for ECDH
I am trying to generate public and private keys for an ECDH handshake. Back end is using p256 for public key. I am getting a failed request with status 0 public func makeHandShake(completion: @escaping (Bool, String?) -> ()) { guard let config = self.config else { completion(false,APP_CONFIG_ERROR) return } var rData = HandshakeRequestTwo() let sessionValue = AppUtils().generateSessionID() rData.session = sessionValue //generating my ECDH Key Pair let sPrivateKey = P256.KeyAgreement.PrivateKey() let sPublicKey = sPrivateKey.publicKey let privateKeyBase64 = sPrivateKey.rawRepresentation.base64EncodedString() print("My Private Key (Base64): \(privateKeyBase64)") let publicKeyBase64 = sPublicKey.rawRepresentation.base64EncodedString() print("My Public Key (Base64): \(publicKeyBase64)") rData.value = sPublicKey.rawRepresentation.base64EncodedString() let encoder = JSONEncoder() do { let jsonData = try encoder.encode(rData) if let jsonString = String(data: jsonData, encoding: .utf8) { print("Request Payload: \(jsonString)") } } catch { print("Error encoding request model to JSON: \(error)") completion(false, "Error encoding request model") return } self.rsaReqResponseHandler(config: config, endpoint: config.services.handShake.endpoint, model: rData) { resToDecode, error in print("Response received before guard : \(resToDecode ?? "No response")") guard let responseString = resToDecode else { print("response string is nil") completion(false,error) return } print("response received: \(responseString)") let decoder = JSONDecoder() do { let request = try decoder.decode(DefaultResponseTwo.self, from: Data(responseString.utf8)) let msg = request.message let status = request.status == 1 ? true : false completion(status,msg) guard let serverPublicKeyBase64 = request.data?.value else { print("Server response is missing the value") completion(false, config.messages.serviceError) return } print("Server Public Key (Base64): \(serverPublicKeyBase64)") if serverPublicKeyBase64.isEmpty { print("Server public key is an empty string.") completion(false, config.messages.serviceError) return } guard let serverPublicKeyData = Data(base64Encoded: serverPublicKeyBase64) else { print("Failed to decode server public key from Base64. Data is invalid.") completion(false, config.messages.serviceError) return } print("Decoded server public key data: \(serverPublicKeyData)") guard let serverPublicKey = try? P256.KeyAgreement.PublicKey(rawRepresentation: serverPublicKeyData) else { print("Decoded server public key data is invalid for P-256 format.") completion(false, config.messages.serviceError) return } // Derive Shared Secret and AES Key let sSharedSecret = try sPrivateKey.sharedSecretFromKeyAgreement(with: serverPublicKey) // Derive AES Key from Shared Secret let symmetricKey = sSharedSecret.hkdfDerivedSymmetricKey( using: SHA256.self, salt: "AES".data(using: .utf8) ?? Data(), sharedInfo: Data(), outputByteCount: 32 ) // Storing AES Key in Config let symmetricKeyBase64 = symmetricKey.withUnsafeBytes { Data($0) }.base64EncodedString() print("Derived Key: \(symmetricKeyBase64)") self.config?.cryptoConfig.key = symmetricKeyBase64 AppUtils.Log(from: self, with: "Handshake Successful, AES Key Established") } catch { AppUtils.Log(from: self, with: "Handshake Failed :: \(error)") completion(false, self.config?.messages.serviceError) } } } this is request struct model public struct HandshakeRequestTwo: Codable { public var session: String? public var value: String? public enum CodingKeys: CodingKey { case session case value } public init(session: String? = nil, value: String? = nil) { self.session = session self.value = value } } This is backend's response {"message":"Success","status":1,"data":{"senderId":"POSTBANK","value":"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAErLxbfQzX+xnYVT1LLP5VOKtkMRVPRCoqYHcCRTM64EMEOaRU16yzsN+2PZMJc0HpdKNegJQZMmswZtg6U9JGVw=="}} This is my response struct model public struct DefaultResponseTwo: Codable { public var message: String? public var status: Int? public var data: HandshakeData? public init(message: String? = nil, status: Int? = nil, data: HandshakeData? = nil) { self.message = message self.status = status self.data = data } } public struct HandshakeData: Codable { public var senderId: String? public var value: String? public init(senderId: String? = nil, value: String? = nil) { self.senderId = senderId self.value = value } }
3
0
618
Nov ’24
How to Restrict Passkey Authentication to FaceID or TouchID Only
Hi everyone, I'm looking for a way to configure Passkey on iOS so that authentication is only possible using FaceID or TouchID. Specifically, I want to disable the use of passcodes and QR codes for authentication. Additionally, is there a method to detect if the authentication was done using a passcode or QR code? Thanks for your help!
1
0
517
Nov ’24
sending to Private Relay Email using amazon ses not working
Hello Developers, I have ran into a problem while sending mail to apple private relay email. We have built a mobile application where user can sign up through apple and they can sign up using hide-my-email feature. Which provides private relay address for us. Now we want to communicate with them using private relay mail address. The technology we are using to send emails are amazon SES, have done SPF, DMIK, DMARC and added domains in apple identity services for mail communication, passed an SPF check as well. But still mail is not getting delivered what am i doing wrong or apple doesn't support third party apps for sending emails to private relay? Is there any other way to achieve this please let me know Using the same body as attached in image is working fine for rest emails.
1
0
627
Nov ’24
PSSO 2.0: is previous password expected to unlock keychain?
Wondering if others have encountered this issue with PSSO 2.0. We are observing that if, after registration, a user changes their IDP password, they may be prompted for their previous password in order to unlock the Keychain. We are trying to determine if this is expected behavior or if there is a way to avoid it. To reproduce this, the flow would be as follows: user registers with PSSO user logs out and logs back in with their IDP password user is authenticated (and not prompted for previous password) user logs out user changes their IDP password on another machine user logs in and is prompted to use their previous password to unlock the Keychain. Failure to provide the previous password nukes the Keychain, which is not an outcome we want. Any insight anyone has on this issue would be most welcome. Thanks
1
0
455
Nov ’24
How to reset user preference for crypto token kit access
When an app is trying to access identities put in the keychain by cryptotokenkit extension, the user gets asked a permission pop-up which reads 'Token Access Request" would like access a token provided by: " with 2 options 'Don't allow' and 'OK' I accidently clicked "Don't allow" and now can't access identities put in crypto token kit. How can I reset the preference?
7
0
768
Nov ’24
Passkey Associated domain error 1004
iOS18.1.1 macOS15.1.1 xcode16.1 Error Domain=com.apple.AuthenticationServices.AuthorizationError Code=1004 "Unable to verify webcredentials association of ********** with domain ******************. Please try again in a few seconds." Our domain must query with VPN, so I set webcredentials:qa.ejeokvv.com?mode=developer following: "If you use a private web server, which is unreachable from the public internet, while developing your app, enable the alternate mode feature to bypass the CDN and connect directly to your server. To do this, add a query string to your associated domains entitlement, as shown in the following example: :?mode= " but it still not working, even after I set mode=developer. Please help!!!!
4
2
944
Nov ’24
ASWebAuthenticationSession + https iOS <17.4
Hi everyone, I am trying to use ASWebAuthenticationSession to authorize user using OAuth2. Service Webcredentials is set. /.well-known/apple-app-site-association file is set. When using API for iOS > 17.4 using new init with callback: .https(...) everything works as expected, however i cannot make .init(url: ,callbackURLScheme: ....) to work. How can i intercept callback using iOS <17.4? Do I really need to use universal links? callbackURL = https://mydomain.com/auth/callback
1
0
445
Nov ’24
Load network/security extension skip the finish callback
Hi, i'm working on an endpoint security extension loader and implement several callbacks from delegate object OSSystemExtensionRequestDelegate the callback i'm interested in is : public func request(_ request: OSSystemExtensionRequest, didFinishWithResult result: OSSystemExtensionRequest.Result); public func requestNeedsUserApproval(_ request: OSSystemExtensionRequest); I've noticed that if I manually approve the extension long time after it was activated, the extension process goes up, but the callback isn't being called. The requestNeedUserApproval callback always gets called. I see in the unified logs that when the extension goes from activated_waiting_for_user -> activated_enabling -> activated_enabled Than the request callback doesn't get called. But whenever the extension goes activated_waiting_for_user -> activated_disabled The request callback gets called. (this is counter intuitive since we expected the state activated_disabled may hint that the extension failed to be activated somehow) Any Idea why my callback doesn't gets called if the extension gets approved long after it was activated ?
1
0
414
Nov ’24
Retrieving certificates from System Roots keychain
Hi there, I'm continuing to build up the API on keychain, I'm trying to implement the ability to create an own certificate chain for validation purposes, similar to ssl. To this extent I need to retrieve the certificates from the System's stores but I can't seem to find a way to do this in code? Creating a query with kSecMatchTrustedOnly only returns certificates which are seemingly manually marked as trusted or otherwise just skips over the System roots keychain. As far as I understand using kSecUseKeychain doesn't work either, since (besides SecKeychain being deprecated) it only works with SecItemAdd.
9
0
701
Nov ’24
Privacy-impacting third-party SDK in a Flutter app
Hi all, I received the following email from Apple: ITMS-91061: Missing privacy manifest - Your app includes “Frameworks/share_plus.framework/share_plus”, which includes share_plus, an SDK that was identified in the documentation as a privacy-impacting third-party SDK. Starting February 12, 2025, if a new app includes a privacy-impacting SDK, or an app update adds a new privacy-impacting SDK, the SDK must include a privacy manifest file. Please contact the provider of the SDK that includes this file to get an updated SDK version with a privacy manifest. For more details about this policy, including a list of SDKs that are required to include signatures and manifests I use Share Plus version 7.2.2 which does not have privacy manifest file yet but I am currently unable to upgrade it to a newer version since it would then bring a restriction that I should start using Dart version 3 where I am not there yet considering my other dependencies! So I am wondering what options I have... Will Apple accept my app's new submission if I add this manifest file to my project itself rather than it is being presented in the third-party SDK? Or what else can I do, please?
2
2
2.1k
Dec ’24
Verify the Password using the AuthorizationCopyRights
Hi everyone, I’m working on building a passwordless login system on macOS using the NameAndPassword module. As part of the implementation, I’m verifying if the password provided by the user is correct before passing it to the macOS login window. Here’s the code snippet I’m using for authentication: // Create Authorization reference AuthorizationRef authorization = NULL; // Define Authorization items AuthorizationItem items[2]; items[0].name = kAuthorizationEnvironmentPassword; items[0].value = (void *)password; items[0].valueLength = (password != NULL) ? strlen(password) : 0; items[0].flags = 0; items[1].name = kAuthorizationEnvironmentUsername; items[1].value = (void *)userName; items[1].valueLength = (userName != NULL) ? strlen(userName) : 0; items[1].flags = 0; // Prepare AuthorizationRights and AuthorizationEnvironment AuthorizationRights rights = {2, items}; AuthorizationEnvironment environment = {2, items}; // Create the authorization reference [Logger debug:@"Authorization creation start"]; OSStatus createStatus = AuthorizationCreate(NULL, &amp;environment, kAuthorizationFlagDefaults, &amp;authorization); if (createStatus != errAuthorizationSuccess) { [Logger debug:@"Authorization creation failed"]; return false; } // Set authorization flags (disable interaction) AuthorizationFlags flags = kAuthorizationFlagDefaults | kAuthorizationFlagExtendRights; // Attempt to copy rights OSStatus status = AuthorizationCopyRights(authorization, &amp;rights, &amp;environment, flags, NULL); // Free the authorization reference if (authorization) { AuthorizationFree(authorization, kAuthorizationFlagDefaults); } // Log the result and return if (status == errAuthorizationSuccess) { [Logger debug:@"Authentication passed"]; return true; } else { [Logger debug:@"Authentication failed"]; return false; } } This implementation works perfectly when the password is correct. However, if the password is incorrect, it tries to re-call the macOS login window, which is already open. even i though i did not used the kAuthorizationFlagInteractionAllowed flag. This causes the process to get stuck and makes it impossible to proceed. I’ve tried logging the flow to debug where things go wrong, but I haven’t been able to figure out how to stop the system from re-calling the login window. Does anyone know how to prevent this looping behavior or gracefully handle an incorrect password in this scenario? I’d appreciate any advice or suggestions to resolve this issue. Thanks in advance for your help!
7
1
828
Dec ’24
Transferring multiple apps that use Sign in with Apple
Hello, These questions are in regard to transferring Sign in With Apple users as part of an app transfer to another developer team. We’ve already read and absorbed the following documents from Apple, but we still have questions that aren’t covered in these documents, due to the unique nature of our use case. Transferring Your Apps and Users to Another Team Bringing New Apps and Users Into Your Team Resolving Sign in with Apple Response Errors Background: We have a suite of three apps that we are tranferring to another developer team. Each app supports Sign In With Apple. Our accounts/users are shared among all three apps. We have all three apps currently grouped together for SIWA. We’re aware that we will need to un-group them before doing the SIWA user transfer. Questions: The API for generating and exchanging transferIDs for users (endpoint /auth/usermigrationinfo) requires a parameter client_id which is described in the docs as "The identifier (App ID or Services ID) for the transferring app." Since we are transferring a set of three apps which share users, we aren’t sure which AppID to use, or whether it matters? We’re assuming we only need to transfer the users once in total (not once-per-app), is this correct? Does it matter which of the three apps’ AppID we use for this? To give more specific context to this question, here’s a more detailed example: For simplicity’s sake, let’s say we have 10 user accounts total, and any of them could sign into any of our three apps. Users 1-7 have signed into all three apps previously User8 has only signed into AppA User9 has only signed into AppB User10 has only signed into AppC Ideally we want to transfer all 10 users all at once. Does it matter which AppID we use for client_id? For example, if we use AppA as the client_id, will we still be able to transfer all 10 users (including User9 and User10)? We’ve tested this on the sender team side, and we’re able to successfully create transferIDs for all 10 users using AppA as client_id. But we’re not sure if this will still work on the recipient side, that we’ll be able to exchange the transferID for all 10 users. . To add another wrinkle, there is a possibility that we won’t be able to transfer one of our three apps (due to one of Apple’s limitations for app transfer). In that case we’ll have to create a new app on the recipient team and shut down the old one on the sender team. But the other two apps in the suite would still be transferred normally. We’d still want all 10 users to be transferred, as the intention is still that all our users can sign into any of their existing accounts in any of the three apps. Would this scenario change the answer to question 1? For example, say we aren’t able to transfer AppC over to the new development team, but instead had to create a new app, AppCNew on the new development team. But we still are able to transfer AppA and AppB. Would we still be able to transfer all 10 users using AppA as the client_id? Including User10 who only ever signed in to AppC (which isn’t being transferred)? We'd really appreciate any answers or guidance that anyone can provide. Thank you, Adam
4
6
587
Dec ’24
Sim Presence Detection
Hi, I am working on a banking app and as per compliance, we have to detect whether the sim is present in the device when using the App or not, also it has to be the same sim which is used when registering with the App/Bank. Currently I dont find any way to detect this. The CTCarrier is depricated and all methods I check returns dummy value and not useful
1
0
499
Dec ’24
How to get user's email? Login with apple id
Hi We use login using apple id feature in our website. However when it comes to apple id, it is possible for user to hide the original email and show a relay email. We have found that this relay email doesn't work Hence looking for a possible solution to acquire the real email from the user. Is there a possibility in doing that? any help would be greatly appreciated. Best Regards Hasintha
3
0
564
Dec ’24
Publishing an app with the correct privacy settings
I am a new developer working to publish an app that includes a location tracker but does not collect user location data. I lam developing my app using Thunkable. My initial submission was rejected because opening the app triggered the error message: "This app is missing "NUserTrackingDescription so tracking transparency will fail. Ensure that this key exists in app's info.plist" However when I add in the NUserTrackingDescription it triggers a process by which I have to notify users that their location data is being collected, which is not the case. I am looking for advice on how to re-submit my app with the correct privacy settings that do not trigger the error message received previously.
0
1
328
Dec ’24
What purpose do shared web credentials in a Message Filter Extension serve?
I'm experiencing the same situation as this post from several months ago, which never received an answer to their follow up question. https://forums.developer.apple.com/forums/thread/759255 The documentation for adding a message filter extension says "you must set up shared credentials as described in Shared Web Credentials" (https://developer.apple.com/documentation/sms_and_call_reporting/sms_and_mms_message_filtering/creating_a_message_filter_app_extension) However credentials are not forwarded to the server and calling SecAddSharedWebCredential from within the extension isn't possible. So I don't understand why the documentation states Shared Web Credentials must be set up. After setting them up, then what is expected to happen with them, or what are you supposed to do with them next. The documentation just says to set them up, it doesn't say how/if they are used or how to use them in the specific context of a message filter extension
1
1
375
Dec ’24