I'm developing an iOS app that utilizes Universal Links and ASWebAuthenticationSession to deep-link from a website to the app itself. This implementation adheres to the recommendations outlined in RFC 8252, ensuring that the app opening the ASWebAuthenticationSession is the same app that is launched via the Universal Link.
Problem:
While most users can successfully launch the app via Universal Links,a few percent of users experience instances where the app fails to launch, and the user is redirected to the browser.
What I've Tried:
ASWebAuthenticationSession Configuration: I've double-checked the configuration of callbackURLScheme and presentationContextProvider.
Universal Links: Verified the apple-app-site-association file and associated domains entitlement.
Network Conditions: Tested on various network environments (Wi-Fi, cellular) and devices.
Questions:
What are the potential causes for this behavior?
Has anyone else encountered a similar issue and found a solution?
Are there any debugging techniques or ways to generate more detailed logs?
I haven't been able to determine which device or OS version is causing this problem.
Thank you.
General
RSS for tagPrioritize user privacy and data security in your app. Discuss best practices for data handling, user consent, and security measures to protect user information.
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
I’m considering storing some sensitive information in the userID field of a passkey, as described in the createCredentialRegistrationRequest method.(link to method).
I'm aware of the largeBlob extension introduced in iOS 17+, but it doesn't meet my needs since I want to create a cross-platform passkey that can be used across various devices — and currently, not many devices support the largeBlob extension.
According to W3C documentation, the userID field is not considered private information and can be displayed to the user without requiring a verification process. Based on my understanding, it's also not encrypted, which means it might be accessible with physical access to the device.
So here are my questions:
How do Apple devices (especially iPhones) handle the userID field in their authenticators?
Is it possible to access the userID without user verification, as permitted by the W3C specification?
Are there any alternative methods to access the userID value stored in a passkey on Apple devices?
Topic:
Privacy & Security
SubTopic:
General
Tags:
Passkeys in iCloud Keychain
Authentication Services
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?
I am experiencing an issue with Apple Sign-In on Vision Pro. When I build and run the app from Xcode, everything works fine—after signing in, the app returns to the foreground as expected.
However, when I launch the app directly on Vision Pro (not from Xcode), after completing the sign-in process, the app does not reopen from the background automatically. Instead, it closes, and I have to manually tap the app icon to reopen it.
Has anyone else encountered this issue? Is there a way to ensure the app properly resumes after sign-in without requiring manual intervention?
Hi everyone,
I’m developing a multiplayer iOS game that uses Multipeer Connectivity for local peer-to-peer networking. I’d like to display user-assigned device names in the UI to help players identify each other during the connection process. In iOS 16 and later, accessing UIDevice.current.name requires the User-Assigned Device Name Entitlement.
The documentation states that the entitlement is granted for functionality involving “interaction between multiple devices that the same user operates”. My game is strictly multiplayer, with devices owned by different users, not a single user managing multiple devices.
I have a few questions regarding this:
Does the requirement for “devices operated by the same user” definitively exclude multiplayer scenarios where devices belong to different players? Can a Multipeer Connectivity-based game qualify for the entitlement in this case?
If the entitlement is not applicable, is prompting users to enter custom names the recommended approach for identifying devices in a multiplayer UI?
Has anyone successfully obtained this entitlement for a similar multiplayer use case with Multipeer Connectivity?
Thanks in advance.
Hi, is it legal to use open APIs to get the users's country country code using the Ip address in the app? I mean I want to know the user country for the game leaderboards data, and there are sites say this is free and open. So, I have two questions, first, is this making the user calling open api to get its country code concept legal? second question, what if these sites suddenly decided that it is not legal to use their apis for commercial use, and i miss that announcement; will you remove my app from the store? or what action will you take exactly?
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?
There is a sudden surge of users in our apps with invalidated biometrics. Even though the issue is being handled correctly and the user has another way to login, some of the users forgot their passwords and they can not login.
Is there any known issue with Biometrics in iOS 18.3.2 or later?
There is a (possible) related discussion here: https://discussions.apple.com/thread/256011565
Hi,
I hope someone is able to help me with this query:
Is there a mandatory requirement to display a view before presenting the App Tracking Transparency modal to explain to the user why the app is asking for tracking? I see there are a few apps which do this, but I don't see any mention of this as a mandatory requirement within the app store review guidelines. The modal can be customised with a description detailing why the app is asking for tracking and I believe this may be sufficient to pass an app store review.
The guidelines also mention that the app must provide access to information about how and where the data will be used. We have these details in our privacy policy which is accessible from within the app. Is this sufficient or do we need a pre-modal view which contains a direct link the the privacy policy.
Any advice on this would be much appreciated.
In response to inquiries from users, we have confirmed the following phenomenon.
If you select "Private email address" in the flow of new user registration with Apple ID, you will not receive the verification code email when performing two-factor authentication.
■User impact
If you use your Apple ID to link an external account without making your email address public, you will not receive the authentication code during two-factor authentication and will not be able to proceed. The date and time of the impact is currently unknown.
◎Impact 1: New registration
If you select "Private email address" in the flow of registering a new user with Apple ID, the verification code will not be received during two-factor authentication and registration will not be completed.
◎Impact 2: Login of existing account
When two-factor authentication is required for an existing account registered with Apple ID set to "Private email address," the verification code is not received and the user cannot log in.
→If you have not registered a login method other than Apple ID for the relevant account, there is no other way to log in.
■About workarounds
・I thought that I could avoid this issue by canceling the private setting of my Apple ID, but I was unable to do so.
→There is currently no workaround found for existing users who are experiencing this issue.
・However, the scope of influence is limited.
■Cause investigation status
Premise: For an Apple ID whose email address is not made public, the two-factor authentication authentication code email follows the following route.
①CDC/GIGYA
miraiz-persol.jp (SendGrid)
Apple's email server (relay server to hide the user's real email address)
User mailbox
→Since '1' are working, the problem seems to have occurred after the connection from ② or ③.
(At this stage, we cannot determine who is at fault: the user, MIRAIZ, or Apple. We are currently investigating.)
◎Hypothesis
・Is there something wrong with Apple's mail server?
・Is it not delivered because the user's mailbox is full?
■Questions, research, and responses we would like to receive
Please check the following two points and reply.
1st point
As shown in the attached image, there seems to be no problem with the SPF settings.
Is it possible to check to see if any errors have occurred with Apple's mail server?
2nd point
Are there any cases where you still can't receive emails even if you deactivate your Apple ID?
I would like to know if there are any patterns in which emails are not being delivered in terms of past inquiries or overall specifications
Topic:
Privacy & Security
SubTopic:
General
Tags:
Sign in with Apple REST API
Sign in with Apple
Sign in with Apple JS
The Core Problem
After Users sign out from the App, the app isn’t properly retrieving the user on second sign in. Instead, it’s treating the user as “Unknown” and saving a new entry in CloudKit and locally. Is there a tutorial aside from 'Juice' that is recent and up to date?
Using personal physical iPhone for simulations. Can't get Keychain to read or store AppleID name/email. I want to avoid hard reseting physical phone.
Logs confirm Keychain is working, but userIdentifier and savedEmail are not being stored correctly.
🔄 Initializing UserManager...
✅ Saved testKeychain to Keychain: Test Value
✅ Retrieved testKeychain from Keychain: Test Value
🔍 Keychain Test - Retrieved Value: Test Value
⚠️ Keychain Retrieve Warning: No stored value found for userIdentifier
⚠️ Keychain Retrieve Warning: No stored value found for savedEmail
🔍 Debug - Retrieved from Keychain: userIdentifier=nil, savedEmail=nil
⚠️ No stored userIdentifier in Keychain. User needs to sign in.
📦 Converting User to CKRecord: Unknown, No Email
✅ User saved locally: Unknown, No Email
✅ User saved to CloudKit: Unknown, No Email
Below UserManager.swift if someone can help troubleshoot. Or step by step tutorial to configure a project and build a User Login & User Account creation for Apple Only app.
import Foundation
import CloudKit
import AuthenticationServices
import SwiftData
@MainActor
class UserManager: ObservableObject {
@Published var user: User?
@Published var isLoggedIn = false
@Published var errorMessage: String?
private let database = CKContainer.default().publicCloudDatabase
init() {
print("🔄 Initializing UserManager...")
// 🔍 Keychain Debug Test
let testKey = "testKeychain"
KeychainHelper.shared.save("Test Value", forKey: testKey)
let retrievedValue = KeychainHelper.shared.retrieve(forKey: testKey)
print("🔍 Keychain Test - Retrieved Value: \(retrievedValue ?? "nil")")
fetchUser() // Continue normal initialization
}
// ✅ Sign in & Save User
func handleSignIn(_ authResults: ASAuthorization) {
guard let appleIDCredential = authResults.credential as? ASAuthorizationAppleIDCredential else {
errorMessage = "Error retrieving Apple credentials"
print("❌ ASAuthorization Error: Invalid credentials received")
return
}
let userIdentifier = appleIDCredential.user
let fullName = appleIDCredential.fullName?.givenName ?? retrieveSavedName()
var email = appleIDCredential.email ?? retrieveSavedEmail()
print("🔍 Apple Sign-In Data: userIdentifier=\(userIdentifier), fullName=\(fullName), email=\(email)")
// 🔄 If Apple doesn't return an email, check if it exists in Keychain
if appleIDCredential.email == nil {
print("⚠️ Apple Sign-In didn't return an email. Retrieving saved email from Keychain.")
}
// ✅ Store userIdentifier & email in Keychain
KeychainHelper.shared.save(userIdentifier, forKey: "userIdentifier")
KeychainHelper.shared.save(email, forKey: "savedEmail")
let newUser = User(fullName: fullName, email: email, userIdentifier: userIdentifier)
saveUserToCloudKit(newUser)
}
func saveUserToCloudKit(_ user: User) {
let record = user.toRecord()
Task {
do {
try await database.save(record)
DispatchQueue.main.async {
self.user = user
self.isLoggedIn = true
self.saveUserLocally(user)
print("✅ User saved to CloudKit: \(user.fullName), \(user.email)")
}
} catch {
DispatchQueue.main.async {
self.errorMessage = "Error saving user: \(error.localizedDescription)"
print("❌ CloudKit Save Error: \(error.localizedDescription)")
}
}
}
}
// ✅ Fetch User from CloudKit
func fetchUser() {
let userIdentifier = KeychainHelper.shared.retrieve(forKey: "userIdentifier")
let savedEmail = KeychainHelper.shared.retrieve(forKey: "savedEmail")
print("🔍 Debug - Retrieved from Keychain: userIdentifier=\(userIdentifier ?? "nil"), savedEmail=\(savedEmail ?? "nil")")
guard let userIdentifier = userIdentifier else {
print("⚠️ No stored userIdentifier in Keychain. User needs to sign in.")
return
}
let predicate = NSPredicate(format: "userIdentifier == %@", userIdentifier)
let query = CKQuery(recordType: "User", predicate: predicate)
Task { [weak self] in
guard let self = self else { return }
do {
let results = try await self.database.records(matching: query, resultsLimit: 1).matchResults
if let (_, result) = results.first {
switch result {
case .success(let record):
DispatchQueue.main.async {
let fetchedUser = User(record: record)
self.user = User(
fullName: fetchedUser.fullName,
email: savedEmail ?? fetchedUser.email,
userIdentifier: userIdentifier
)
self.isLoggedIn = true
self.saveUserLocally(self.user!)
print("✅ User loaded from CloudKit: \(fetchedUser.fullName), \(fetchedUser.email)")
}
case .failure(let error):
DispatchQueue.main.async {
print("❌ Error fetching user from CloudKit: \(error.localizedDescription)")
}
}
}
} catch {
DispatchQueue.main.async {
print("❌ CloudKit fetch error: \(error.localizedDescription)")
}
}
}
}
// ✅ Save User Locally
private func saveUserLocally(_ user: User) {
if let encoded = try? JSONEncoder().encode(user) {
UserDefaults.standard.set(encoded, forKey: "savedUser")
UserDefaults.standard.set(user.fullName, forKey: "savedFullName")
UserDefaults.standard.set(user.email, forKey: "savedEmail")
print("✅ User saved locally: \(user.fullName), \(user.email)")
} else {
print("❌ Local Save Error: Failed to encode user data")
}
}
// ✅ Retrieve Previously Saved Name
private func retrieveSavedName() -> String {
return UserDefaults.standard.string(forKey: "savedFullName") ?? "Unknown"
}
// ✅ Retrieve Previously Saved Email
private func retrieveSavedEmail() -> String {
return KeychainHelper.shared.retrieve(forKey: "savedEmail") ?? UserDefaults.standard.string(forKey: "savedEmail") ?? "No Email"
}
// ✅ Sign Out
func signOut() {
isLoggedIn = false
user = nil
UserDefaults.standard.removeObject(forKey: "savedUser")
print("🚪 Signed Out")
}
}
Topic:
Privacy & Security
SubTopic:
General
Tags:
Sign in with Apple
Authentication Services
iCloud Keychain Verification Codes
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.
Hi,
We're in the process of implementing Apple's App Integrity, but am getting stalled due to missing documents. Can anyone assist with this?
We've been following https://developer.apple.com/documentation/devicecheck/validating-apps-that-connect-to-your-server to make the necessary updates, but have come up short with where the document references decoding the Attestation Object. Can we get more information here and how the decoding process work?
I am working on a SDK which helps identify the device authenticity. I am in need of something which can confirm the firmware/Hardware/OS is signed by Apple and is authentic. There will be no tempering to device?
I'm trying to use ASWebAuthenticationSession on macOS but there is a weird crash and I have no idea what to do.
It looks like there is a main thread check in a framework code that I have no control over.
Any help would be appreciated.
Thank you in advance.
The stack of crashed thread has no symbols, even for supposedly my code in OAuthClient.authenticate.
macOS 15.4.1 (24E263)
Xcode Version 16.3 (16E140)
Thread 11: EXC_BREAKPOINT (code=1, subcode=0x10039bb04)
Thread 12 Queue : com.apple.NSXPCConnection.m-user.com.apple.SafariLaunchAgent (serial)
#0 0x0000000100b17b04 in _dispatch_assert_queue_fail ()
#1 0x0000000100b52834 in dispatch_assert_queue$V2.cold.1 ()
#2 0x0000000100b17a88 in dispatch_assert_queue ()
#3 0x000000027db5f3e8 in swift_task_isCurrentExecutorWithFlagsImpl ()
#4 0x00000001022c7754 in closure #1 in closure #1 in OAuthClient.authenticate() ()
#5 0x00000001022d0c98 in thunk for @escaping @callee_guaranteed (@in_guaranteed URL?, @guaranteed Error?) -> () ()
#6 0x00000001c7215a34 in __102-[ASWebAuthenticationSession initWithURL:callback:usingEphemeralSession:jitEnabled:completionHandler:]_block_invoke ()
#7 0x00000001c72163d0 in -[ASWebAuthenticationSession _endSessionWithCallbackURL:error:] ()
#8 0x00000001c7215fc0 in __43-[ASWebAuthenticationSession _startDryRun:]_block_invoke_2 ()
#9 0x0000000194e315f4 in __invoking___ ()
#10 0x0000000194e31484 in -[NSInvocation invoke] ()
#11 0x00000001960fd644 in __NSXPCCONNECTION_IS_CALLING_OUT_TO_REPLY_BLOCK__ ()
#12 0x00000001960fbe40 in -[NSXPCConnection _decodeAndInvokeReplyBlockWithEvent:sequence:replyInfo:] ()
#13 0x00000001960fb798 in __88-[NSXPCConnection _sendInvocation:orArguments:count:methodSignature:selector:withProxy:]_block_invoke_3 ()
#14 0x0000000194a6ef18 in _xpc_connection_reply_callout ()
#15 0x0000000194a6ee08 in _xpc_connection_call_reply_async ()
#16 0x0000000100b3130c in _dispatch_client_callout3_a ()
#17 0x0000000100b362f8 in _dispatch_mach_msg_async_reply_invoke ()
#18 0x0000000100b1d3a8 in _dispatch_lane_serial_drain ()
#19 0x0000000100b1e46c in _dispatch_lane_invoke ()
#20 0x0000000100b2bfbc in _dispatch_root_queue_drain_deferred_wlh ()
#21 0x0000000100b2b414 in _dispatch_workloop_worker_thread ()
#22 0x0000000100c0379c in _pthread_wqthread ()
My code:
@MainActor
func authenticate() async throws {
let authURL = api.authorizationURL(
scopes: scopes,
state: state,
redirectURI: redirectURI
)
let authorizationCodeURL: URL = try await withUnsafeThrowingContinuation { c in
let session = ASWebAuthenticationSession(url: authURL, callback: .customScheme(redirectScheme)) { url, error in
guard let url = url else {
c.resume(throwing: error ?? Error.unknownError("Failed to get authorization code"))
return
}
c.resume(returning: url)
}
session.presentationContextProvider = presentationContextProvider
session.start()
}
let authorizationCode = try codeFromAuthorizationURL(authorizationCodeURL)
(storedAccessToken, storedRefreshToken) = try await getTokens(authorizationCode: authorizationCode)
}
Here is disassembly of the crashed function.
libdispatch.dylib`_dispatch_assert_queue_fail:
0x10067fa8c <+0>: pacibsp
0x10067fa90 <+4>: sub sp, sp, #0x50
0x10067fa94 <+8>: stp x20, x19, [sp, #0x30]
0x10067fa98 <+12>: stp x29, x30, [sp, #0x40]
0x10067fa9c <+16>: add x29, sp, #0x40
0x10067faa0 <+20>: adrp x8, 71
0x10067faa4 <+24>: add x8, x8, #0x951 ; "not "
0x10067faa8 <+28>: adrp x9, 70
0x10067faac <+32>: add x9, x9, #0x16b ; ""
0x10067fab0 <+36>: stur xzr, [x29, #-0x18]
0x10067fab4 <+40>: cmp w1, #0x0
0x10067fab8 <+44>: csel x8, x9, x8, ne
0x10067fabc <+48>: ldr x10, [x0, #0x48]
0x10067fac0 <+52>: cmp x10, #0x0
0x10067fac4 <+56>: csel x9, x9, x10, eq
0x10067fac8 <+60>: stp x9, x0, [sp, #0x10]
0x10067facc <+64>: adrp x9, 71
0x10067fad0 <+68>: add x9, x9, #0x920 ; "BUG IN CLIENT OF LIBDISPATCH: Assertion failed: "
0x10067fad4 <+72>: stp x9, x8, [sp]
0x10067fad8 <+76>: adrp x1, 71
0x10067fadc <+80>: add x1, x1, #0x8eb ; "%sBlock was %sexpected to execute on queue [%s (%p)]"
0x10067fae0 <+84>: sub x0, x29, #0x18
0x10067fae4 <+88>: bl 0x1006c258c ; symbol stub for: asprintf
0x10067fae8 <+92>: ldur x19, [x29, #-0x18]
0x10067faec <+96>: str x19, [sp]
0x10067faf0 <+100>: adrp x0, 71
0x10067faf4 <+104>: add x0, x0, #0x956 ; "%s"
0x10067faf8 <+108>: bl 0x1006b7b64 ; _dispatch_log
0x10067fafc <+112>: adrp x8, 108
0x10067fb00 <+116>: str x19, [x8, #0x2a8]
-> 0x10067fb04 <+120>: brk #0x1
I must be missing something. How can an iphone that is in lockdown mode, using ONLY data, no Bluetooth connected and only one singular iPhone have seven UNLISTED items on the local network in privacy and settings?
Hello,
We are working on integrating app integrity verification into our service application, following Apple's App Attest and DeviceCheck guide.
Our server issues a challenge to the client, which then sends the challenge, attestation, and keyId in CBOR format to Apple's App Attest server for verification. However, we are unable to reach both https://attest.apple.com and https://attest.development.apple.com due to network issues.
These attempts have been made from both our internal corporate network and mobile hotspot environments. Despite adjusting DNS settings and other configurations, the issue persists.
Are there alternative methods or solutions to address this problem? Any recommended network configurations or guidelines to successfully connect to Apple's App Attest servers would be greatly appreciated.
Thank you.
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.
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.