we can get token but when send to verity from apple. it reture Error : {"responseCode":"400","responseMessage":"Missing or incorrectly formatted device token payload"}
Prioritize 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
Dear Apple Developer Support Team,
We are experiencing a recurring issue with the DeviceCheck API where the following error is being returned:
com.apple.devicecheck.error 0
Upon analyzing our logs, we have noticed that this error occurs significantly more often when users are connected to Wi-Fi networks, compared to mobile networks. This leads us to suspect that there might be a relationship between Wi-Fi configuration and the DeviceCheck service’s ability to generate or validate tokens.
We would like to know:
Is this error code (0) known to be caused by specific types of network behavior or misconfigurations on Wi-Fi networks (e.g., DNS filtering, firewall restrictions, proxy servers)?
Are there any recommended best practices for ensuring reliable DeviceCheck API communication over Wi-Fi networks?
Additionally, could you please clarify what general conditions could trigger this com.apple.devicecheck.error 0? The lack of specific documentation makes debugging this issue difficult from our side.
Any guidance or internal documentation on this error code and its potential causes would be greatly appreciated.
IDE: Xcode 16.3
Looking forward to your support.
Best regards,
Hi everyone,
I am currently implementing Server-to-Server Notifications for Sign in with Apple. I’ve encountered a discrepancy between the official documentation and the actual payload I received, and I would like to clarify which one is correct.
The Situation: I triggered an account deletion event via privacy.apple.com to test the notification flow. When my server received the notification, the type field in the JSON payload was account-deleted (past tense).
The Issue: According to the official Apple documentation, the event type is listed as account-delete (present tense).
Here is the discrepancy I am observing:
Documentation: account-delete
Actual Payload: account-deleted
My Question: Is the documentation outdated, or is this a known inconsistency? Should I handle both strings (account-delete and account-deleted) in my backend logic to be safe, or is account-deleted the new standard?
Any insights or confirmation from those who have implemented this would be greatly appreciated.
Thanks!
It seems it is not possible to give a CLI app (non .app bundle) full disk access in macOS 26.1. This seems like a bug and if not that is a breaking change. Anybody seeing the same problem?
Our application needs full disk access for a service running as a LaunchDaemon. The binary is located in a /Library subfolder.
Hello
I have a problem with provisionprofile file. I have created Identifier with Sign in with Apple capability turned on, created Profile with Developer ID selected and now I try to export archive with generated Developer ID provision file but it says "Profile doesn't support Sign in with Apple"
Also interesting thing that default provisions like
macOS App Development
Mac App Store Connect
don't show such error when I try to export archive
Maybe this problem is only related to Developer ID provision and Direct Distribution doesn't support Sign in with Apple, but I havent found proves about this idea
I keep getting invalid_client,
here is a test login: https://www.bella-booking.ch/_get_incl/test_apple_login.cfm
Any help appreciated.
NOTE: Everey other error, like wrong reroute or wrong client id, a different error will be sent frpm apple, after I checked all and crosschecked with jwt.io, it keep getting invalid_client.
Any clue?
If the response is correct, the token should be displayed on the page.
Thx
Topic:
Privacy & Security
SubTopic:
Sign in with Apple
Is there a step by step program on Sending Push notifications?
I seem to be stuck at load private key. I get this error. SecKeyCreateWithData failed with error: Error Domain=NSOSStatusErrorDomain Code=-50 "EC private key creation from data failed"
It is a new p8 file. I tried different format. I read some articles that say that there is a bug I think. I don't know for sure because it was written in jibberish.
90% of the code is dealing with these stupid keys. This should be 1 function setting the pipe and then I can use the pipe. This is ridiculous. If anybody has any ideas. The code is a mess because I tried so many different ideas.
Push Notification.txt
With Let's Encrypt having completely dropped support for OCSP recently [1], I wanted to ask if macOS has a means of keeping up to date with their CRLs and if so, roughly how often this occurs?
I first observed an issue where a revoked-certificate test site, "revoked.badssl.com" (cert signed by Let's Encrypt), was not getting blocked on any browser, when a revocation policy was set up using the SecPolicyCreateRevocation API, in tandem with the kSecRevocationUseAnyAvailableMethod and kSecRevocationPreferCRL flags.
After further investigation, I noticed that even on a fresh install of macOS, Safari does not block this test website, while Chrome and Firefox (usually) do, due to its revoked certificate. Chrome and Firefox both have their own means of dealing with CRLs, while I assume Safari uses the system Keychain and APIs.
I checked cert info for the site here [2]. It was issued on 2025-07-01 20:00 and revoked an hour later.
[1] https://letsencrypt.org/2024/12/05/ending-ocsp/
[2] https://www.ssllabs.com/ssltest/analyze.html?d=revoked.badssl.com
I have Authorisation Plugin which talks using XPC to my Launch Daemon to perform privileged actions.
I want to protect my XPC service narrowing it to be called from known trusted clients.
Now since I want authorisation plugin code which is from apple to call my service, I cannot use my own team id or app group here.
I am currently banking on following properties of client connection.
Apple Team ID : EQHXZ8M8AV
Bundle ID starting with com.apple.
Client signature verified By Apple.
This is what I have come up with.
func isClientTrusted(connection: NSXPCConnection) -> Bool {
let clientPID = connection.processIdentifier
logInfo("🔍 Checking XPC Client - PID: \(clientPID)")
var secCode: SecCode?
var secStaticCode: SecStaticCode?
let attributes = [kSecGuestAttributePid: clientPID] as NSDictionary
let status = SecCodeCopyGuestWithAttributes(nil, attributes, [], &secCode)
guard status == errSecSuccess, let code = secCode else {
logInfo("Failed to get SecCode for PID \(clientPID)")
return false
}
let staticStatus = SecCodeCopyStaticCode(code, [], &secStaticCode)
guard staticStatus == errSecSuccess, let staticCode = secStaticCode else {
logInfo("Failed to get SecStaticCode")
return false
}
var signingInfo: CFDictionary?
let signingStatus = SecCodeCopySigningInformation(staticCode, SecCSFlags(rawValue: kSecCSSigningInformation), &signingInfo)
guard signingStatus == errSecSuccess, let info = signingInfo as? [String: Any] else {
logInfo("Failed to retrieve signing info")
return false
}
// Extract and Verify Team ID
if let teamID = info["teamid"] as? String {
logInfo("XPC Client Team ID: \(teamID)")
if teamID != "EQHXZ8M8AV" { // Apple's official Team ID
logInfo("Client is NOT signed by Apple")
return false
}
} else {
logInfo("Failed to retrieve Team ID")
return false
}
// Verify Bundle ID Starts with "com.apple."
if let bundleID = info["identifier"] as? String {
logInfo("XPC Client Bundle ID: \(bundleID)")
if !bundleID.hasPrefix("com.apple.") {
logInfo("Client is NOT an Apple system process")
return false
}
} else {
logInfo("Failed to retrieve Bundle Identifier")
return false
}
// Verify Apple Code Signature Trust
var trustRequirement: SecRequirement?
let trustStatus = SecRequirementCreateWithString("anchor apple" as CFString, [], &trustRequirement)
guard trustStatus == errSecSuccess, let trust = trustRequirement else {
logInfo("Failed to create trust requirement")
return false
}
let verifyStatus = SecStaticCodeCheckValidity(staticCode, [], trust)
if verifyStatus != errSecSuccess {
logInfo("Client's signature is NOT trusted by Apple")
return false
}
logInfo("Client is fully verified as Apple-trusted")
return true
}
Q: Just wanted community feedback, is this correct approach?
Hello!
I do know apple does not support electron, but I do not think this is an electron related issue, rather something I am doing wrong. I'd be curious to find out why the keychain login is happenning after my app has been signed with the bundleid, entitlements, and provision profile.
Before using the provision profile I did not have this issue, but it is needed for assessments feature.
I'm trying to ship an Electron / macOS desktop app that must run inside Automatic Assessment Configuration. The build signs and notarizes successfully, and assessment mode itself starts on Apple-arm64 machines, but every single launch shows the system dialog that asks to allow access to the "login" keychain. The dialog appears on totally fresh user accounts, so it's not tied to anything I store there.
It has happened ever since I have added the provision profile to the electron builder to finally test assessment out.
entitlements.inherit.plist keys
<key>com.apple.security.cs.allow-jit</key> <true/>
<key>com.apple.security.cs.allow-unsigned-executable-memory</key> <true/>
entitlements.plist keys:
<key>com.apple.security.cs.allow-jit</key> <true/>
<key>com.apple.security.cs.allow-unsigned-executable-memory</key> <true/>
<key>com.apple.developer.automatic-assessment-configuration</key> <true/>
I'm honestly not sure whether the keychain is expected, but I have tried a lot of entitlement combinations to get rid of It. Electron builder is doing the signing, and we manually use the notary tool to notarize but probably irrelevant.
mac: {
notarize: false,
target: 'dir',
entitlements: 'buildResources/entitlements.mac.plist',
provisioningProfile: 'buildResources/xyu.provisionprofile',
entitlementsInherit: 'buildResources/entitlements.mac.inherit.plist',
Any lead is welcome!
Topic:
Privacy & Security
SubTopic:
General
Tags:
Automatic Assessment Configuration
Assessment
Security
Entitlements
Hello,
We’ve resumed the migration process after a break. Since my colleague is no longer with us, I had to go through the steps again myself.
As before, we’re trying to migrate "Sign In with Apple" users from tenant TENANT_A with client_id=CLIENT_ID_A to tenant TENANT_B with client_id=CLIENT_ID_B
I followed the procedure described here: [Apple Developer Documentation](https://developer.apple.com/documentation/technotes/tn3159-migrating-sign-in-with-apple-users-for-an-app-transfer – Migrating Sign In with Apple Users, essentially repeating what my coworker previously attempted in coordination with your employee Stephanie.
Here’s a summary of the steps and the issue we’re facing:
STEP 1 - get authcode for TEAM A
curl --location 'https://appleid.apple.com/auth/token'
--header 'Content-Type: application/x-www-form-urlencoded'
--data-urlencode 'grant_type=client_credentials'
--data-urlencode 'scope=user.migration'
--data-urlencode 'client_id=pl.CLIEND_ID_A'
--data-urlencode 'client_secret=<TEAM_A_SECRET>'
I receive response:
{
"access_token": "<ACCESS_TOKEN_TEAM_A>",
"token_type": "Bearer",
"expires_in": 3600
}
STEP 2 - get authcode for TEAB B
curl --location 'https://appleid.apple.com/auth/token'
--header 'Content-Type: application/x-www-form-urlencoded'
--data-urlencode 'grant_type=client_credentials'
--data-urlencode 'scope=user.migration'
--data-urlencode 'client_id=CLIENT_ID_B'
--data-urlencode 'client_secret=<TEAB_B_SECRET>'
I receive response:
{
"access_token":"<ACCESS_TOKEN_TEAB_B>",
"token_type": "Bearer",
"expires_in": 3600
}
STEP 3 - get transfer_sub from TEAM A
curl --location 'https://appleid.apple.com/auth/usermigrationinfo'
--header 'Authorization: Bearer <ACCESS_TOKEN_TEAM_A>'
--header 'Content-Type: application/x-www-form-urlencoded'
--data-urlencode 'client_id=CLIENT_ID_A'
--data-urlencode 'client_secret=<TEAM_A_SECRET>'
--data-urlencode 'sub=USER_SUB_FROM_TEAM_A'
--data-urlencode 'target=TENANT_B'
I receive response:
{
"transfer_sub": "USER_SUB_FROM_TEAM_B"
}
STEP 4 - Team B exchanges transfer identifers
curl --location 'https://appleid.apple.com/auth/usermigrationinfo'
--header 'Authorization: Bearer <ACCESS_TOKEN_TEAM_B'
--header 'Content-Type: application/x-www-form-urlencoded'
--data-urlencode 'client_id=CLIENT_ID_B'
--data-urlencode 'client_secret=<TEAM_B_SECRET>'
I receive response:
{
"error": "invalid_request"
}
We’ve created a new client_id under tenant B and want to migrate users there. However, we skipped the step described in Step 3 of the documentation(https://developer.apple.com/documentation/technotes/tn3159-migrating-sign-in-with-apple-users-for-an-app-transfer#3-Team-A-initiates-app-transfer-to-Team-B), which involves initiating an app transfer. The reason is that this client_id is used solely for web authentication, not for a mobile app, so we don’t have an app to transfer.
Based on our analysis and your documentation, it seems this flow only works if the client_id matches across both tenants, which can only be achieved through an app transfer, something we cannot proceed with.
Apple previously insisted that we migrate these users, but as shown above, we’re stuck. Is there any alternative flow available, or can you assist us in completing this migration?
Topic:
Privacy & Security
SubTopic:
Sign in with Apple
Hi everyone,
I'm experiencing an intermittent issue with Keychain data loss on the latest iOS Beta 2. In about 7% of cases, users report that previously saved Keychain items are missing when the app is relaunched — either after a cold start or simply after being killed and reopened.
Here are the key observations:
The issue occurs sporadically, mostly once per affected user, but in 3 cases it has happened 4 times.
No explicit deletion is triggered from the app.
No system logs or error messages from Apple indicate any Keychain-related actions.
The app attempts to access Keychain items, but they are no longer available.
This behavior is inconsistent with previous iOS versions and is not reproducible in development environments.
This raises concerns about:
Whether this is a bug in the beta or an intentional change in Keychain behavior.
Whether this could affect production apps when the final iOS version is released.
The lack of any warning or documentation from Apple regarding this behavior.
Has anyone else encountered similar issues? Any insights, workarounds, or official clarification would be greatly appreciated.
Thanks!
Topic:
Privacy & Security
SubTopic:
General
Using the SDK, I've printed out some log messages when I enter the wrong password:
2025-08-20 15:58:14.086 Db SecurityAgentHelper-arm64[818:1efd] [com.example.apple-samplecode.LoggingAuthPlugin:mechanism] invoke
2025-08-20 15:58:14.086 Db SecurityAgentHelper-arm64[818:1efd] [com.example.apple-samplecode.LoggingAuthPlugin:mechanism] general:
2025-08-20 15:58:14.086 Db SecurityAgentHelper-arm64[818:1efd] [com.example.apple-samplecode.LoggingAuthPlugin:mechanism] progname: 'SecurityAgentHelper-arm64'
2025-08-20 15:58:14.086 Db SecurityAgentHelper-arm64[818:1efd] [com.example.apple-samplecode.LoggingAuthPlugin:mechanism] OS version: 'Version 15.5 (Build 24F74)'
2025-08-20 15:58:14.086 Db SecurityAgentHelper-arm64[818:1efd] [com.example.apple-samplecode.LoggingAuthPlugin:mechanism] pid: '818'
2025-08-20 15:58:14.086 Db SecurityAgentHelper-arm64[818:1efd] [com.example.apple-samplecode.LoggingAuthPlugin:mechanism] ppid: '1'
2025-08-20 15:58:14.086 Db SecurityAgentHelper-arm64[818:1efd] [com.example.apple-samplecode.LoggingAuthPlugin:mechanism] euid: '92'
2025-08-20 15:58:14.086 Db SecurityAgentHelper-arm64[818:1efd] [com.example.apple-samplecode.LoggingAuthPlugin:mechanism] uid: '92'
2025-08-20 15:58:14.087 Db SecurityAgentHelper-arm64[818:1efd] [com.example.apple-samplecode.LoggingAuthPlugin:mechanism] session: 0x186e9
2025-08-20 15:58:14.087 Db SecurityAgentHelper-arm64[818:1efd] [com.example.apple-samplecode.LoggingAuthPlugin:mechanism] attributes:
2025-08-20 15:58:14.087 Db SecurityAgentHelper-arm64[818:1efd] [com.example.apple-samplecode.LoggingAuthPlugin:mechanism] is root: f
2025-08-20 15:58:14.087 Db SecurityAgentHelper-arm64[818:1efd] [com.example.apple-samplecode.LoggingAuthPlugin:mechanism] has graphics: t
2025-08-20 15:58:14.087 Db SecurityAgentHelper-arm64[818:1efd] [com.example.apple-samplecode.LoggingAuthPlugin:mechanism] has TTY: t
2025-08-20 15:58:14.087 Db SecurityAgentHelper-arm64[818:1efd] [com.example.apple-samplecode.LoggingAuthPlugin:mechanism] is remote: f
2025-08-20 15:58:14.087 Db SecurityAgentHelper-arm64[818:1efd] [com.example.apple-samplecode.LoggingAuthPlugin:mechanism] auth session: 0x0
2025-08-20 15:58:14.087 Db SecurityAgentHelper-arm64[818:1efd] [com.example.apple-samplecode.LoggingAuthPlugin:mechanism] context:
2025-08-20 15:58:14.088 Db SecurityAgentHelper-arm64[818:1efd] [com.example.apple-samplecode.LoggingAuthPlugin:mechanism] authentication-failure: --S -14090
2025-08-20 15:58:14.088 Db SecurityAgentHelper-arm64[818:1efd] [com.example.apple-samplecode.LoggingAuthPlugin:mechanism] pam_result: X-S 9
2025-08-20 15:58:14.089 Db SecurityAgentHelper-arm64[818:1efd] [com.example.apple-samplecode.LoggingAuthPlugin:mechanism] hints:
2025-08-20 15:58:14.089 Db SecurityAgentHelper-arm64[818:1efd] [com.example.apple-samplecode.LoggingAuthPlugin:mechanism] authorize-right: "system.login.console"
2025-08-20 15:58:14.090 Db SecurityAgentHelper-arm64[818:1efd] [com.example.apple-samplecode.LoggingAuthPlugin:mechanism] client-path: "/System/Library/CoreServices/loginwindow.app"
2025-08-20 15:58:14.090 Db SecurityAgentHelper-arm64[818:1efd] [com.example.apple-samplecode.LoggingAuthPlugin:mechanism] client-pid: 807
2025-08-20 15:58:14.090 Db SecurityAgentHelper-arm64[818:1efd] [com.example.apple-samplecode.LoggingAuthPlugin:mechanism] client-type: 'LDNB'
2025-08-20 15:58:14.090 Db SecurityAgentHelper-arm64[818:1efd] [com.example.apple-samplecode.LoggingAuthPlugin:mechanism] client-uid: 0
2025-08-20 15:58:14.090 Db SecurityAgentHelper-arm64[818:1efd] [com.example.apple-samplecode.LoggingAuthPlugin:mechanism] creator-audit-token:
2025-08-20 15:58:14.090 Db SecurityAgentHelper-arm64[818:1efd] [com.example.apple-samplecode.LoggingAuthPlugin:mechanism] ff ff ff ff 00 00 00 00 00 00 00 00 00 00 00 00 ................
2025-08-20 15:58:14.090 Db SecurityAgentHelper-arm64[818:1efd] [com.example.apple-samplecode.LoggingAuthPlugin:mechanism] 00 00 00 00 27 03 00 00 e9 86 01 00 68 08 00 00 ....'.......h...
2025-08-20 15:58:14.090 Db SecurityAgentHelper-arm64[818:1efd] [com.example.apple-samplecode.LoggingAuthPlugin:mechanism] creator-pid: 807
2025-08-20 15:58:14.090 Db SecurityAgentHelper-arm64[818:1efd] [com.example.apple-samplecode.LoggingAuthPlugin:mechanism] flags: 259
2025-08-20 15:58:14.090 Db SecurityAgentHelper-arm64[818:1efd] [com.example.apple-samplecode.LoggingAuthPlugin:mechanism] reason: 0
2025-08-20 15:58:14.090 Db SecurityAgentHelper-arm64[818:1efd] [com.example.apple-samplecode.LoggingAuthPlugin:mechanism] tries: 1
2025-08-20 15:58:14.090 Db SecurityAgentHelper-arm64[818:1efd] [com.example.apple-samplecode.LoggingAuthPlugin:mechanism] immutable hints:
2025-08-20 15:58:14.090 Db SecurityAgentHelper-arm64[818:1efd] [com.example.apple-samplecode.LoggingAuthPlugin:mechanism] client-apple-signed: true
2025-08-20 15:58:14.090 Db SecurityAgentHelper-arm64[818:1efd] [com.example.apple-samplecode.LoggingAuthPlugin:mechanism] client-firstparty-signed: true
2025-08-20 15:58:14.090 Db SecurityAgentHelper-arm64[818:1efd] [com.example.apple-samplecode.LoggingAuthPlugin:mechanism] creator-apple-signed: true
2025-08-20 15:58:14.090 Db SecurityAgentHelper-arm64[818:1efd] [com.example.apple-samplecode.LoggingAuthPlugin:mechanism] creator-firstparty-signed: true
2025-08-20 15:58:14.091 Db SecurityAgentHelper-arm64[818:1efd] [com.example.apple-samplecode.LoggingAuthPlugin:mechanism] arguments:
2025-08-20 15:58:14.091 Db SecurityAgentHelper-arm64[818:1efd] [com.example.apple-samplecode.LoggingAuthPlugin:mechanism] none
2025-08-20 15:58:14.108 Db SecurityAgentHelper-arm64[818:1efd] [com.example.apple-samplecode.LoggingAuthPlugin:mechanism] LAContext: LAContext[4:8:112]
2025-08-20 15:58:14.119 Db SecurityAgentHelper-arm64[818:1efd] [com.example.apple-samplecode.LoggingAuthPlugin:mechanism] token identities: 0
2025-08-20 15:58:14.120 Db SecurityAgentHelper-arm64[818:1efd] [com.example.apple-samplecode.LoggingAuthPlugin:mechanism] token watcher: <TKTokenWatcher: 0x11410ee70>
Specifically, is there a manual/link somewhere that can allow me to interpret:
authentication-failure: --S -14090
and
pam_result: X-S 9
Has anybody else experienced something similar? This is on the login screen.
I call update() and it doesn't call me back with view()
2025-08-21 17:04:38.669 Db SecurityAgentHelper-arm64[1134:2df1] [***:LoginView] calling update()
Then silence...
Hello,
I’m trying to set up Sign In with Apple for my Firebase Authentication integration.
Steps I followed:
Created a Service ID in Apple Developer, e.g. com.example.myapp.signin.
Tried to enable Sign In with Apple and configure the Web Authentication Configuration.
Web Domain: myapp.firebaseapp.com
Return URL: https://myapp.firebaseapp.com/__/auth/handler
When I click Save, I get the following error in the browser console and a blank response page:
Unsupported Request
PATCH to http://developer.apple.com/services-account/v1/bundleIds/XXXXXXXX not supported.
Reference #...
What I have verified so far:
My Apple Developer Program membership is active (paid).
My App ID (e.g. com.example.myapp) exists in Identifiers.
The App ID has Sign In with Apple capability checked.
I need to link the Service ID with this App ID for Firebase web-based auth.
Goal:
Complete setup of Apple as a sign-in provider in Firebase Authentication. To do this, Apple requires me to add the Firebase return URL above, but the Developer Portal prevents saving with the 501 error.
Has anyone else run into this, and is there a workaround (e.g. enabling via Xcode, App Store Connect, or other methods)? Is this a known bug with the Apple Developer Portal?
Here is the screenshot of the error:
And Response part:
Thanks in advance!
Hi everyone,
I’m currently facing an issue while trying to submit an update for my app to the App Store. The review process is blocking the update due to a "Privacy - Data Use and Sharing" warning, stating that our app requests "tracking purchase history for tracking purposes."
However, we have already removed this functionality and deleted the NSUserTrackingUsageDescription key from our latest build. Despite this, the warning persists, and we are unable to proceed with the update.
I have already contacted Apple Support, but in the meantime, I wanted to ask the community:
Has anyone else encountered this issue, and if so, how did you resolve it?
Is there a way to force a refresh of privacy-related settings in App Store Connect?
Are there any additional steps we need to take to completely remove this tracking flag from our app submission?
Any insights or guidance would be greatly appreciated! Thanks in advance for your help.
Hi everyone,
I have a macOS application that uses Screen Recording permission. I build my app with an adhoc signature (not with a Developer ID certificate).
For example, in version 1.0.0, I grant Screen Recording permission to the app. Later, I build a new version (1.1.0) and update by dragging the new app into the Applications folder to overwrite the previous one.
However, when I launch the updated app, it asks for Screen Recording permission again, even though I have already granted it for the previous version.
I don’t fully understand how TCC (Transparency, Consent, and Control) determines when permissions need to be re-granted.
Can anyone explain how TCC manages permissions for updated builds, especially with adhoc signatures? Is there any way to retain permissions between updates, or any best practices to avoid having users re-authorize permissions after every update?
I am developing a background program that is included in the app as an extension. I would like to include logic to check the teamID and code signature validity of the program I created to ensure that it has not been tampered with. Is this possible?
Using the simplified sign-in with tvOS and a third party password manager, I receive a complete ASPasswordCredential, and I can easily log into my app. When I do the same thing but with Apple's password manager as the source, I receive an ASPasswordCredential that includes the email address, but the password is an empty string.
I have tried deleting the credentials from Apple Passwords and regenerating them with a new login to the app's website. I have tried restarting my iPhone.
Is this the expected behavior? How should I be getting a password from Apple's Password app with an ASAuthorizationPasswordRequest?
Issue Summary
I'm encountering a DCError.invalidInput error when calling DCAppAttestService.shared.generateAssertion() in my App Attest implementation. This issue affects only a small subset of users - the majority of users can successfully complete both attestation and assertion flows without any issues. According to Apple Engineer feedback, there might be a small implementation issue in my code.
Key Observations
Success Rate: ~95% of users complete the flow successfully
Failure Pattern: The remaining ~5% consistently fail at assertion generation
Key Length: Logs show key length of 44 characters for both successful and failing cases
Consistency: Users who experience the error tend to experience it consistently
Platform: Issue observed across different iOS versions and device types
Environment
iOS App Attest implementation
Using DCAppAttestService for both attestation and assertion
Custom relying party server communication
Issue affects ~5% of users consistently
Key Implementation Details
1. Attestation Flow (Working)
The attestation process works correctly:
// Generate key and attest (successful for all users)
self.attestService.generateKey { keyId, keyIdError in
guard keyIdError == nil, let keyId = keyId else {
return completionHandler(.failure(.dcError(keyIdError as! DCError)))
}
// Note: keyId length is consistently 44 characters for both successful and failing users
// Attest key with Apple servers
self.attestKey(keyId, clientData: clientData) { result in
// ... verification with RP server
// Key is successfully stored for ALL users (including those who later fail at assertion)
}
}
2. Assertion Flow (Failing for ~5% of Users with invalidInput)
The assertion generation fails for a consistent subset of users:
// Get assertion data from RP server
self.assertRelyingParty.getAssertionData(kid, with: data) { result in
switch result {
case .success(let receivedData):
let session = receivedData.session
let clientData = receivedData.clientData
let hash = clientData.toSHA256() // SHA256 hash of client data
// THIS CALL FAILS WITH invalidInput for ~5% of users
// Same keyId (44 chars) that worked for attestation
self.attestService.generateAssertion(kid, clientDataHash: hash) { assertion, err in
guard err == nil, let assertion = assertion else {
// Error: DCError.invalidInput
if let err = err as? DCError, err.code == .invalidKey {
return reattestAndAssert(.invalidKey, completionHandler)
} else {
return completionHandler(.failure(.dcError(err as! DCError)))
}
}
// ... verification logic
}
}
}
3. Client Data Structure
Client data JSON structure (identical for successful and failing users):
// For attestation (works for all users)
let clientData = ["challenge": receivedData.challenge]
// For assertion (fails for ~5% of users with same structure)
var clientData = ["challenge": receivedData.challenge]
if let data = data { // Additional data for assertion
clientData["account"] = data["account"]
clientData["amount"] = data["amount"]
}
4. SHA256 Hash Implementation
extension Data {
public func toSHA256() -> Data {
return Data(SHA256.hash(data: self))
}
}
5. Key Storage Implementation
Using UserDefaults for key storage (works consistently for all users):
private let keyStorageTag = "app-attest-keyid"
func setKey(_ keyId: String) -> Result<(), KeyStorageError> {
UserDefaults.standard.set(keyId, forKey: keyStorageTag)
return .success(())
}
func getKey() -> Result<String?, KeyStorageError> {
let keyId = UserDefaults.standard.string(forKey: keyStorageTag)
return .success(keyId)
}
Questions
User-Specific Factors: Since this affects only ~5% of users consistently, could there be device-specific, iOS version-specific, or account-specific factors that cause invalidInput?
Key State Validation: Is there any way to validate the state of an attested key before calling generateAssertion()? The key length (44 chars) appears normal for both successful and failing cases.
Keychain vs UserDefaults: Could the issue be related to using UserDefaults instead of Keychain for key storage? Though this works for 95% of users.
Race Conditions: Could there be subtle race conditions or timing issues that only affect certain users/devices?
Error Recovery: Is there a recommended way to handle this error? Should we attempt re-attestation for these users?
Additional Context & Debugging Attempts
Consistent Failure: Users who experience this error typically experience it on every attempt
Key Validation: Both successful and failing users have identical key formats (44 character strings)
Device Diversity: Issue observed across different device models and iOS versions
Server Logs: Our server successfully provides challenges and processes attestation for all users
Re-attestation: Forcing re-attestation sometimes resolves the issue temporarily, but it often recurs
The fact that 95% of users succeed with identical code suggests there might be some environmental or device-specific factor that we're not accounting for. Any insights into what could cause invalidInput for a subset of users would be invaluable.