We have been having very high response times in device check device validation service (https://developer.apple.com/documentation/devicecheck/accessing-and-modifying-per-device-data#Create-the-payload-for-a-device-validation-request) since 17 July at 19:10hs GMT. The service information page says the service was running in green status but that isn't the case and we currenly have stop consuming it.
Is it being looked at? Are you aware of this issue? Can you give us an estimate of when it should be working correctly?
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
I’ve been running into an issue for over a day when trying to create a Sign in with Apple key. Each time I attempt to download it, I’m redirected to a page that displays an error and provides no further guidance.
I’ve contacted Support and haven’t yet received a reply. I’ve also tried across multiple browsers (Chrome, Safari, Firefox), including incognito modes.
Any ideas on how to resolve this? We’re currently stuck and would appreciate guidance.
Hello,
We received a rejection on one of our IOS applications because we were doing Microsoft MSAL login through the user's browser. The representative recommended that we use Webview to do in-app logins. However when we tried to handle the custom app uri redirection (looking like myapp://auth/), Webview does not seem to send the user back to the application. Does anyone have a fix for this?
Thanks!
Topic:
Privacy & Security
SubTopic:
General
Tags:
Safari and Web
UI Frameworks
Authentication Services
WebKit
Hello
I'm using Auth0 for handling auth in my app
When the user wants to sign in, it will show the auth system pop-up
And when the user wants to log out it shows the same pop-up
My issue is how to replace the Sign In text in this pop-up to show Sign Out instead of Sign In when the user wants to sign out?
We are using SecPKCS12Import C API in our application to import a self seigned public key certificate. We tried to run the application for the first time on Tahoe and it failed with OSStatus -26275 error.
The release notes didn't mention any deprecation or change in the API as per https://developer.apple.com/documentation/macos-release-notes/macos-26-release-notes.
Are we missing anything? There are no other changes done to our application.
We’ve identified an issue in our app where, upon clicking the "Call Customer Center" button, users are unexpectedly shown a logo and message option on a native pop-up window.
However, this wasn't the case before, and it should only display a phone number to dial, which was given inside our code.
This is incorrect and misleading for our users, as:
We are a Canadian-based service and have no affiliation with US messaging chat.
The messaging feature was never enabled or intended for our app.
Our app should only initiate a phone call to our customer support center — no messages or branding from third parties should appear
Topic:
Privacy & Security
SubTopic:
General
I regularly help developers with keychain problems, both here on DevForums and for my Day Job™ in DTS. Many of these problems are caused by a fundamental misunderstanding of how the keychain works. This post is my attempt to explain that. I wrote it primarily so that Future Quinn™ can direct folks here rather than explain everything from scratch (-:
If you have questions or comments about any of this, put them in a new thread and apply the Security tag so that I see it.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
SecItem: Fundamentals
or How I Learned to Stop Worrying and Love the SecItem API
The SecItem API seems very simple. After all, it only has four function calls, how hard can it be? In reality, things are not that easy. Various factors contribute to making this API much trickier than it might seem at first glance.
This post explains the fundamental underpinnings of the keychain. For information about specific issues, see its companion post, SecItem: Pitfalls and Best Practices.
Keychain Documentation
Your basic starting point should be Keychain Items.
If your code runs on the Mac, also read TN3137 On Mac keychain APIs and implementations.
Read the doc comments in <Security/SecItem.h>. In many cases those doc comments contain critical tidbits.
When you read keychain documentation [1] and doc comments, keep in mind that statements specific to iOS typically apply to iPadOS, tvOS, and watchOS as well (r. 102786959). Also, they typically apply to macOS when you target the data protection keychain. Conversely, statements specific to macOS may not apply when you target the data protection keychain.
[1] Except TN3137, which is very clear about this (-:
Caveat Mac Developer
macOS supports two different keychain implementations: the original file-based keychain and the iOS-style data protection keychain.
IMPORTANT If you’re able to use the data protection keychain, do so. It’ll make your life easier. See the Careful With that Shim, Mac Developer section of SecItem: Pitfalls and Best Practices for more about this.
TN3137 On Mac keychain APIs and implementations explains this distinction. It also says:
The file-based keychain is on the road to deprecation.
This is talking about the implementation, not any specific API. The SecItem API can’t be deprecated because it works with both the data protection keychain and the file-based keychain. However, Apple has deprecated many APIs that are specific to the file-based keychain, for example, SecKeychainCreate.
TN3137 also notes that some programs, like launchd daemons, can’t use the file-based keychain. If you’re working on such a program then you don’t have to worry about the deprecation of these file-based keychain APIs. You’re already stuck with the file-based keychain implementation, so using a deprecated file-based keychain API doesn’t make things worse.
The Four Freedoms^H^H^H^H^H^H^H^H Functions
The SecItem API contains just four functions:
SecItemAdd(_:_:)
SecItemCopyMatching(_:_:)
SecItemUpdate(_:_:)
SecItemDelete(_:)
These directly map to standard SQL database operations:
SecItemAdd(_:_:) maps to INSERT.
SecItemCopyMatching(_:_:) maps to SELECT.
SecItemUpdate(_:_:) maps to UPDATE.
SecItemDelete(_:) maps to DELETE.
You can think of each keychain item class (generic password, certificate, and so on) as a separate SQL table within the database. The rows of that table are the individual keychain items for that class and the columns are the attributes of those items.
Note Except for the digital identity class, kSecClassIdentity, where the values are split across the certificate and key tables. See Digital Identities Aren’t Real in SecItem: Pitfalls and Best Practices.
This is not an accident. The data protection keychain is actually implemented as an SQLite database. If you’re curious about its structure, examine it on the Mac by pointing your favourite SQLite inspection tool — for example, the sqlite3 command-line tool — at the keychain database in ~/Library/Keychains/UUU/keychain-2.db, where UUU is a UUID.
WARNING Do not depend on the location and structure of this file. These have changed in the past and are likely to change again in the future. If you embed knowledge of them into a shipping product, it’s likely that your product will have binary compatibility problems at some point in the future. The only reason I’m mentioning them here is because I find it helpful to poke around in the file to get a better understanding of how the API works.
For information about which attributes are supported by each keychain item class — that is, what columns are in each table — see the Note box at the top of Item Attribute Keys and Values. Alternatively, look at the Attribute Key Constants doc comment in <Security/SecItem.h>.
Uniqueness
A critical part of the keychain model is uniqueness. How does the keychain determine if item A is the same as item B? It turns out that this is class dependent. For each keychain item class there is a set of attributes that form the uniqueness constraint for items of that class. That is, if you try to add item A where all of its attributes are the same as item B, the add fails with errSecDuplicateItem. For more information, see the errSecDuplicateItem page. It has lists of attributes that make up this uniqueness constraint, one for each class.
These uniqueness constraints are a major source of confusion, as discussed in the Queries and the Uniqueness Constraints section of SecItem: Pitfalls and Best Practices.
Parameter Blocks Understanding
The SecItem API is a classic ‘parameter block’ API. All of its inputs are dictionaries, and you have to know which properties to set in each dictionary to achieve your desired result. Likewise for when you read properties in output dictionaries.
There are five different property groups:
The item class property, kSecClass, determines the class of item you’re operating on: kSecClassGenericPassword, kSecClassCertificate, and so on.
The item attribute properties, like kSecAttrAccessGroup, map directly to keychain item attributes.
The search properties, like kSecMatchLimit, control how the system runs a query.
The return type properties, like kSecReturnAttributes, determine what values the query returns.
The value type properties, like kSecValueRef perform multiple duties, as explained below.
There are other properties that perform a variety of specific functions. For example, kSecUseDataProtectionKeychain tells macOS to use the data protection keychain instead of the file-based keychain. These properties are hard to describe in general; for the details, see the documentation for each such property.
Inputs
Each of the four SecItem functions take dictionary input parameters of the same type, CFDictionary, but these dictionaries are not the same. Different dictionaries support different property groups:
The first parameter of SecItemAdd(_:_:) is an add dictionary. It supports all property groups except the search properties.
The first parameter of SecItemCopyMatching(_:_:) is a query and return dictionary. It supports all property groups.
The first parameter of SecItemUpdate(_:_:) is a pure query dictionary. It supports all property groups except the return type properties.
Likewise for the only parameter of SecItemDelete(_:).
The second parameter of SecItemUpdate(_:_:) is an update dictionary. It supports the item attribute and value type property groups.
Outputs
Two of the SecItem functions, SecItemAdd(_:_:) and SecItemCopyMatching(_:_:), return values. These output parameters are of type CFTypeRef because the type of value you get back depends on the return type properties you supply in the input dictionary:
If you supply a single return type property, except kSecReturnAttributes, you get back a value appropriate for that return type.
If you supply multiple return type properties or kSecReturnAttributes, you get back a dictionary. This supports the item attribute and value type property groups. To get a non-attribute value from this dictionary, use the value type property that corresponds to its return type property. For example, if you set kSecReturnPersistentRef in the input dictionary, use kSecValuePersistentRef to get the persistent reference from the output dictionary.
In the single item case, the type of value you get back depends on the return type property and the keychain item class:
For kSecReturnData you get back the keychain item’s data. This makes most sense for password items, where the data holds the password. It also works for certificate items, where you get back the DER-encoded certificate. Using this for key items is kinda sketchy. If you want to export a key, called SecKeyCopyExternalRepresentation. Using this for digital identity items is nonsensical.
For kSecReturnRef you get back an object reference. This only works for keychain item classes that have an object representation, namely certificates, keys, and digital identities. You get back a SecCertificate, a SecKey, or a SecIdentity, respectively.
For kSecReturnPersistentRef you get back a data value that holds the persistent reference.
Value Type Subtleties
There are three properties in the value type property group:
kSecValueData
kSecValueRef
kSecValuePersistentRef
Their semantics vary based on the dictionary type.
For kSecValueData:
In an add dictionary, this is the value of the item to add. For example, when adding a generic password item (kSecClassGenericPassword), the value of this key is a Data value containing the password.
This is not supported in a query dictionary.
In an update dictionary, this is the new value for the item.
For kSecValueRef:
In add and query dictionaries, the system infers the class property and attribute properties from the supplied object. For example, if you supply a certificate object (SecCertificate, created using SecCertificateCreateWithData), the system will infer a kSecClass value of kSecClassCertificate and various attribute values, like kSecAttrSerialNumber, from that certificate object.
This is not supported in an update dictionary.
For kSecValuePersistentRef:
For query dictionaries, this uniquely identifies the item to operate on.
This is not supported in add and update dictionaries.
Revision History
2025-05-28 Expanded the Caveat Mac Developer section to cover some subtleties associated with the deprecation of the file-based keychain.
2023-09-12 Fixed various bugs in the revision history. Added a paragraph explaining how to determine which attributes are supported by each keychain item class.
2023-02-22 Made minor editorial changes.
2023-01-28 First posted.
Confirmation on "Sign in with Apple JS" Web Implementation Compatibility
Hello Developers
We are trying to implement "Sign in with Apple JS" on our e-commerce website, which is built on a SaaS platform called Ticimax in Turkey.
Our platform provider (Ticimax) claims that a web-based implementation of "Sign in with Apple" is not currently possible. They state this is due to "Apple's browser security policies" that prevent consistent and secure support across all major browsers, particularly Safari with its privacy features.
Could you please confirm if there are any fundamental security policies or technical restrictions imposed by Apple that would prevent a standard, secure implementation of "Sign in with Apple JS" on a typical e-commerce website?
We know many global websites use this feature successfully. We need to know if our provider's claim has a technical basis from Apple's perspective, or if this is a standard implementation challenge that developers are expected to handle (e.g., using pop-ups instead of redirects to comply with ITP).
Any official clarification or documentation you can provide on this matter would be greatly appreciated.
Thank you.
Topic:
Privacy & Security
SubTopic:
Sign in with Apple
Tags:
Sign in with Apple
Sign in with Apple JS
completeRequestWithTextToInsert is used to return text into an arbitrary textfield via the context menu AutoFill/Passwords from a 3rd party password manager (or presumably the Passwords App) in iOS 18.
While testing this feature in the debugger, it would often fail on the first invocation. It also appears to happen intermittently in the released app extension. Subsequent testing using the Passwords App shows it too may fail to return a value.
I have confirmed this behaviour is repeatable with the Passwords App on an iPhone running iOS 18.3.1
Reboot the iPhone.
Show the App Library, and right click Autofill.
Select Passwords
Select Passwords (App)
Select a password.
Nothing will be inserted (intermittently).
Feedback assistant report: FB16788563
override func prepareInterface(forPasskeyRegistration registrationRequest: any ASCredentialRequest)
int this function how can i get the "challenge" from user agent, the params "challenge" need to be used in webauthn navigator.credentials.create
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
Could you tell me about account security and passkeys? Our service is considering implementing passkeys, and these questions are to understand how Apple protects accounts from third parties.
① Apple website states that two-factor authentication is mandatory for newly created Apple Accounts. When did this requirement come into effect? What are the conditions for users who do not have two-factor authentication enabled?
② Apple website mentions that a verification code may be required when signing into an Apple Account from a new device or browser. Is my understanding of the situations where a verification code is requested accurate, as listed below? Are there any other situations?
Completely signing out of the Apple Account on that device.
Erasing the device.
Needing to change the password for security reasons.
③ If a user is already using a passkey on an Apple device, and then upgrades to a new device, will additional authentication, such as entering a PIN code, be required to use the passkey on the new device?
Hi Apple Devs,
For our app, we utilize passkeys for account creation (not MFA). This is mainly for user privacy, as there is 0 PII associated with passkey account creation, but it additionally also satisfies the 4.8: Login Services requirement for the App Store.
However, we're getting blocked in Apple Review. Because the AASA does not get fetched immediately upon app install, the reviewers are not able to create an account immediately via passkeys, and then they reject the build.
I'm optimistic I can mitigate the above. But even if we pass Apple Review, this is a pretty catastrophic issue for user security and experience. There are reports that 5% of users cannot create passkeys immediately (https://developer.apple.com/forums/thread/756740). That is a nontrivial amount of users, and this large of an amount distorts how app developers design onboarding and authentication flows towards less secure experiences:
App developers are incentivized to not require MFA setup on account creation because requiring it causes significant churn, which is bad for user security.
If they continue with it anyways, for mitigation, developers are essentially forced to add in copy into their app saying something along the lines of "We have no ability to force Apple to fetch the config required to continue sign up, so try again in a few minutes, you'll just have to wait."
You can't even implement a fallback method. There's no way to check if the AASA is available before launching the ASAuthorizationController so you can't mitigate a portion of users encountering an error!!
Any app that wants to use the PRF extension to encrypt core functionality (again, good for user privacy) simply cannot exist because the app simply does not work for an unspecified amount of time for a nontrivial portion of users.
It feels like a. Apple should provide a syscall API that we can call to force SWCD to verify the AASA or b. implement a config based on package name for the app store such that the installation will immediately include a verified AASA from Apple's CDN. Flicking the config on would require talking with Apple. If this existed, this entire class of error would go away.
It feels pretty shocking that there isn't a mitigation in place for this already given that it incentivizes app developers to pursue strictly less secure and less private authentication practices.
Topic:
Privacy & Security
SubTopic:
General
Tags:
Authentication Services
Universal Links
Passkeys in iCloud Keychain
I'm building a macOS app that registers itself for HTTP(S) url handling and would like it to participate in the ASWebAuthenticationSession fow.
I did:
update the plist to register as a handler for URL shemes (http, https, file)
use NSWorkspace setDefaultApplication API to set this app as a default handler for urls in question
wrote custom ASWebAuthenticationSessionWebBrowserSessionHandling implementation and set it as SessionManager's sessionHandler
I launched this app from Xcode, then I triggered authentication flow from a third-party app.
When the sign in flow is initiated, I can see that my app is activeated (willBecomeActive and didBecomeActive callbacks are both called), but there is no call for sessionHandler's begin() method.
With some additional debugging I see that my app receives an apple event when the flow is started:
{sfri,auth target=SafariLaunchAgent {qntp=90/$627......},aapd=TRUE
If I switch system default browser back to Safari and then start the login flow, it correctly displays a sign in web page. What do I miss?
PS. I'm on Tahoe 26.2
I would like to confirm about fraud prevention using Device Check when publishing multiple apps.
If the Team ID and Key ID are the same, will the values be shared across all apps with Device Check?
With Device Check, only two keys can be created per developer account, and these two are primarily intended for key renewal in case of a leak, rather than for assigning different keys to each app, correct?
If both 1 and 2 are correct, does that mean that Device Check should not be used to manage "one-time-only rewards per device" when offering them across multiple apps?
Thank you very much for your confirmation.
Hi Apple Team and Community,
We encountered a sudden and widespread failure related to the App Attest service on Friday, July 25, starting at around 9:22 AM UTC.
After an extended investigation, our network engineers noted that the size of the attestation objects received from the attestKey call grew in size notably starting at that time. As a result, our firewall began blocking the requests from our app made to our servers with the Base64-encoded attestation objects in the payload, as these requests began triggering our firewall's max request length rule.
Could Apple engineers please confirm whether there was any change rolled out by Apple at or around that time that would cause the attestation object size to increase?
Can anyone else confirm seeing this?
Any insights from Apple or others would be appreciated to ensure continued stability.
Thanks!
Hello,
I am implementing "Sign in with Apple" on my backend and validating the Identity Token (JWT) received from the client.
I noticed that for some users who choose the "Hide My Email" option, the is_private_email claim is missing from the ID Token payload, even though the email address clearly belongs to the private relay domain (@privaterelay.appleid.com).
Here is an example of the decoded payload I received:
{ "iss": "https://appleid.apple.com", "aud": "xxx", "exp": 1764402438, "iat": 1764316038, "sub": "xxxxxxxx", "c_hash": "3FAJNf4TILzUgo_YFe4E0Q", "email": "xxx@privaterelay.appleid.com", "email_verified": true, "auth_time": 1764316038, "nonce_supported": true // "is_private_email": true <-- This field is missing }
My Questions:
Is the is_private_email claim considered optional in the ID Token?
Is it safe and recommended to rely solely on the email domain suffix (@privaterelay.appleid.com) to identify if a user is using a private email?
Any insights or official references would be appreciated.
Thanks.
Hi, we were recently approved for the com.apple.developer.web-browser.public-key-credential entitlement and have added it to our app. It initially worked as expected for a couple of days, but then it stopped working. We're now seeing the same error as before adding the entitlement:
Told not to present authorization sheet: Error Domain=com.apple.AuthenticationServicesCore.AuthorizationError Code=1 "(null)"
ASAuthorizationController credential request failed with error: Error Domain=com.apple.AuthenticationServices.AuthorizationError Code=1004 "(null)"
Do you have any insights into what might be causing this issue?
Thank you!
Hi,
My app keeps getting rejected during App Review with the reason that the Sign in with Apple button is unresponsive. However, I have tested it extensively on:
• A real iPad Pro (iPadOS 18.3.2)
• Multiple Xcode simulators
• Including an iPad Air 5th simulator (18.3.1)
In all of these cases, the button works correctly.
The reviewer mentioned they are using an iPad Air 5th running iPadOS 18.3.2, which I cannot find as a simulator in Xcode, nor do I have access to this exact device around me.
I’m using standard SignInWithAppleButton code with no custom wrappers or UI layers on top. Here is the relevant snippet:
GeometryReader { geometry in
ZStack {
Color.black.opacity(0.3)
.ignoresSafeArea()
.onTapGesture {
prompt = ""
showChat = false
}
VStack(alignment: .leading, spacing: 0){
switch purchaseManager.hasAISubscription {
case 1:
HStack{
}
case 2:
HStack{
}
case 3:
HStack{
}
default:
HStack{
}
}
Divider()
ScrollView {
VStack(alignment: .leading, spacing: 8) {
ForEach(filteredChatHistory, id: \.id) { chat in
}
}
Spacer()
}
.frame(maxHeight: geometry.size.height * 0.7)
.defaultScrollAnchor(.bottom)
.padding()
Divider()
HStack(){
if httpManager.isLoggedIn && purchaseManager.hasAISubscription > 0 {
}
}
else if purchaseManager.hasAISubscription == 0{
}
else{
Spacer()
SignInWithAppleButton(.continue){ request in
request.requestedScopes = [.email]
} onCompletion: { result in
switch result {
case .success(let auth):
switch auth.credential {
case let appleCredential as ASAuthorizationAppleIDCredential:
let userID = appleCredential.user
saveToKeychain(userID, for: "com.xing-fu.aireader.apple.userid")
if let identityTokenData = appleCredential.identityToken,
let identityToken = String(data: identityTokenData, encoding: .utf8) {
Task {
//后端认证过,才算登录成功
await httpManager.loginWithApple(identityToken)
}
}
break
default:
break
}
case .failure(let error):
print("error")
}
}
.frame(maxWidth: 350, maxHeight: 40)
.padding()
.cornerRadius(10)
Spacer()
}
}
}
.overlay( // 边框
RoundedRectangle(cornerRadius: 10)
.stroke(Color.g2, lineWidth: 4)
)
.background(Color(UIColor.systemBackground))
.cornerRadius(10) // 圆角
.shadow(color: Color.black.opacity(0.1), radius: 5, x: 0, y: 5)
.frame(width: geometry.size.width * 0.8)
.onDisappear{
httpManager.alertMessage = nil
}
}
}
Topic:
Privacy & Security
SubTopic:
Sign in with Apple
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.