Recently I am trying to implement apple oauth in expo web version, I created the service id and other related info, i have issue
@PostMapping("/callback")
public ResponseEntity handleAppleCallback(@RequestParam Map<String, String> body) {
String code = body.get("code");
String idToken = body.get("id_token");
if (code == null) {
return ResponseEntity.badRequest().build();
}
// Redirect to your Expo Web app with the code in query
String frontendUrl = "https://mobile-dot-dev-epicportal.uc.r.appspot.com/apple-callback?code=" + code;
return ResponseEntity.status(HttpStatus.FOUND)
.header("Location", frontendUrl)
.build();
}
when i pass the code recived from apple to this route i am getting invalid_grant
i am not sure what is wrong here
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
An ITMS-91061: Missing privacy manifest rejection email looks as follows:
ITMS-91061: Missing privacy manifest- Your app includes
"<path/to/SDK>", which includes , 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, visit: https://developer.apple.com/support/third-party-SDK-requirements.
Glossary
ITMS-91061: Missing privacy manifest: An email that includes the name and path of privacy-impacting SDK(s) with no privacy manifest files in your app bundle. For more information, see https://developer.apple.com/support/third-party-SDK-requirements.
: The specified privacy-impacting SDK that doesn't include a privacy manifest file.
If you are the developer of the rejected app, gather the name of the SDK from the email you received from Apple, then contact the SDK's provider for an updated version that includes a valid privacy manifest. After receiving an updated version of the SDK, verify the SDK includes a valid privacy manifest file at the expected location. For more information, see Adding a privacy manifest to your app or third-party SDK.
If your app includes a privacy manifest file, make sure the file only describes the privacy practices of your app. Do not add the privacy practices of the SDK to your app's privacy manifest.
If the email lists multiple SDKs, repeat the above process for all of them.
If you are the developer of an SDK listed in the email, publish an updated version of your SDK that includes a privacy manifest file with valid keys and values.
Every privacy-impacting SDK must contain a privacy manifest file that only describes its privacy practices.
To learn how to add a valid privacy manifest to your SDK, see the Additional resources section below.
Additional resources
Privacy manifest files
Describing data use in privacy manifests
Describing use of required reason API
Adding a privacy manifest to your app or third-party SDK
TN3182: Adding privacy tracking keys to your privacy manifest
TN3183: Adding required reason API entries to your privacy manifest
TN3184: Adding data collection details to your privacy manifest
TN3181: Debugging an invalid privacy manifest
Topic:
Privacy & Security
SubTopic:
General
Tags:
App Store Connect
Privacy
App Submission
App Review
Hello, I currently have an app that includes the "Sign in with Apple" feature, and I need to transfer this app to another app team. I have reviewed all official documentation but have not found the answer I need. My situation has some specificities, and I hope to receive assistance.
The .p8 key created by the original developer team has been lost, and the app’s backend does not use a .p8 key for verification—instead, it verifies by obtaining Apple’s public key. However, according to the official documentation I reviewed, obtaining a transfer identifier during the app transfer process requires a client_secret generated from the original team’s .p8 key. This has left us facing a challenge, and we have two potential approaches to address this issue:
Q1: During the transfer, is it possible to skip obtaining the transfer identifier and proceed directly with the app transfer, without performing any backend operations? Is this approach feasible?
Q2: If the above approach is not feasible, should we create a new .p8 key in the original team’s account and use this new key for the transfer? If a new key is generated, do we need to re-release a new version of the app before initiating the transfer?
If neither of the above approaches is feasible, are there better solutions to resolve our issue? I hope to receive a response. Thank you.
TN3159: Migrating Sign in with Apple users for an app transfer | Apple Developer Documentation/
https://developer.apple.com/documentation/signinwithapple/transferring-your-apps-and-users-to-another-team
Topic:
Privacy & Security
SubTopic:
Sign in with Apple
Tags:
Sign in with Apple REST API
Sign in with Apple
We are currently trying to fix a bug when using SignIn with Apple. It appears that on some occasions we are not receiving a user's profile info (name, email) when a new account is created.
After doing some investigation we believe this bug is due to the same Apple login being used as an already deleted account. ASF only appears to send profile info the very first time an Apple login is used. If that account is deleted and another is created with the same apple login we won't receive the profile info.
As a result we are not in compliance with Apple's guidelines requiring that we use the provided profile info with Apple SigIn, and need to prompt users to enter it again.
Is there a process in place to properly "clear" a user after their account is deleted in our system, so that the next time a user creates an account with the same Apple login, we receive their profile info again?
Problem Summary
I'm experiencing a persistent invalid-credential error with Apple Sign-In on iOS despite having verified every aspect of the configuration over the past 6 months. The error occurs at the Firebase Authentication level after successfully receiving credentials from Apple.
Error Message: Firebase auth error: invalid-credential - Invalid OAuth response from apple.com. Environment
Platform: iOS (Flutter app)
Firebase Auth: v5.7.0
Sign in with Apple: v6.1.2
Xcode: Latest version with capability enabled
iOS Target: 13.0+
Bundle ID: com.harmonics.orakl
What Actually Happens
✅ Apple Sign-In popup appears
✅ User can authenticate with Apple ID
✅ Apple returns credentials with identityToken
❌ Firebase rejects with invalid-credential error
The error occurs at Firebase level, not Apple level.
What I've Tried
Created a brand new Apple Key (previous key was 6 months old)
Tested with both App ID and Service ID in Firebase
Completely reinstalled CocoaPods dependencies
Verified nonce handling is correct (hashed to Apple, raw to Firebase)
Activated Firebase Hosting and attempted to deploy .well-known file
Checked Cloud Logging (no detailed error messages found)
Disabled and re-enabled Apple Sign-In provider in Firebase
Verified Return URL matches exactly
Waited and retried multiple times over 6 months
Questions
Is the .well-known/apple-developer-domain-association.txt file required? If yes, how should it be generated? Firebase Hosting doesn't auto-generate it.
Could there be a server-side caching/blacklist issue with my domain or Service ID after multiple failed attempts?
Should the Apple Key be linked to the Service ID instead of the App ID? The key shows as linked to Z3NNDZVWMZ.com.harmonics.orakl (the App ID).
Is there any way to get more detailed error logs from Firebase about why it's rejecting the Apple OAuth response?
Could using a custom domain instead of .firebaseapp.com resolve the issue?
Additional Context
Google Sign-In works perfectly on the same app
The configuration has been reviewed by multiple developers
Error persists across different devices and iOS versions
No errors in Xcode console except the Firebase rejection
Any help would be greatly appreciated. I've exhausted all standard troubleshooting steps and documentation.
Project Details:
Bundle ID: com.harmonics.orakl
Firebase Project: harmonics-app
Team ID: Z3N.......
code : // 1. Generate raw nonce
final String rawNonce = _generateRandomNonce();
// 2. Hash with SHA-256
final String hashedNonce = _sha256Hash(rawNonce);
// 3. Send HASHED nonce to Apple ✅
final appleCredential = await SignInWithApple.getAppleIDCredential(
scopes: [AppleIDAuthorizationScopes.email, AppleIDAuthorizationScopes.fullName],
nonce: hashedNonce, // Correct: hashed nonce to Apple
);
// 4. Create Firebase credential with RAW nonce ✅
final oauthCredential = OAuthProvider("apple.com").credential(
idToken: appleCredential.identityToken!,
rawNonce: rawNonce, // Correct: raw nonce to Firebase
);
// 5. Sign in with Firebase - ERROR OCCURS HERE ❌
await FirebaseAuth.instance.signInWithCredential(oauthCredential);
Topic:
Privacy & Security
SubTopic:
Sign in with Apple
Developers of our e-shop are preparing to enable Apple Sign In for account login.
Apple ID verification is conducted via the domain appleid.apple.com, and the responses should be coming back from the following two Apple IP addresses:
IPv4 Address: 17.32.194.6
IPv4 Address: 17.32.194.37
Question is whether these addresses are correct and if they remain unchanged over time. Alternatively, it is existing an official list of IP addresses that may be used for Apple Sign In verification response?
This is necessary to ensure precise network communication settings and protection by F5 security solution.
Thanks a lot for answers.
"Our app has absolutely no integration with DiDi login. We only integrate WeChat, QQ, carrier, and Apple ID login, and all related login entry icons are local resources. On an iPhone 16 Pro Max device with iOS system version 18.7, there was one isolated incident where the Apple ID login entry icon mysteriously changed to the DiDi app icon. What could be the possible iOS system-level causes for this?"
Topic:
Privacy & Security
SubTopic:
Sign in with Apple
When using Apple's Journal app through iPhone Mirroring, the user is allowed to authenticate via TouchID on the Mac instead of requiring you to unlock your phone, authenticate and then re-lock it to access it again in iPhone Mirroring.
Any other app that's using a call to authenticate via FaceID can't do this under iPhone Mirroring. Is there a new API call for this, or is it still a private API for Apple only?
Is it possible to change the Primary App ID set in the Group with an existing primary App ID to another Primary App ID within the same group
If there is a change, whether the sub values of the token will be changed upon successful login
If an app corresponding to the existing Group Primary App ID is deleted from the app store, ask whether or not other apps in the same group are affected and what effect it will have
If anyone knows about the above, please let me know please
I added a feature to my app that retrieves only app settings (no personal data) from my API hosted on Cloudflare Workers. The app does not send, collect, track, or share any user data, and I do not store or process any personal information.
Technical details such as IP address, user agent, and device information may be automatically transmitted as part of the internet protocol when the request is made, but my app does not log or use them. Cloudflare may collect this information.
Question: Does this count as “data collection” for App Store Connect purposes, or can I select “No Data Collected”?
Hi,
I followed step by step documentation to implement SignIn with Apple in iOS/Android application.
I created an AppId com.nhp.queenergy, a related ServiceId com.nhp.queenergy.apple, and a KeyId.
Authorization request is correctly performed by using ServiceId as client_id and my backend redirect_uri
I receive code on my backend
Token request is performed by using ServiceId as client_id, same redirect_uri, the code I have just received and the client_secret as JWT signed with my .p8 certificate with the following decoded structure
Header
{
"kid": ,
"typ": "JWT",
"alg": "ES256"
}
Payload
{
"iss": ,
"sub": "com.nhp.queenergy.apple",
"aud": "https://appleid.apple.com",
"exp": 1756113744,
"iat": 1756111944
}
I always receive "invalid_grant" error without any further error description.
Moreover the error is always the same even though I use any fake string as client secret.
If the code expires, as expected the error changes by adding "The code has expired or has been revoked."
I really don't know how to solve this issue
Best regards
Topic:
Privacy & Security
SubTopic:
Sign in with Apple
Hi everyone,
I'm encountering an issue where the background location indicator remains visible on the status bar even though I have set the location permissions to Never for my app in the system settings. Despite taking all the necessary steps to stop location tracking (including stopping updates, geofencing, and other location-related services), the indicator still appears. This seems to be a bug since everything has been turned off on my end.
Here’s what I’ve already tried:
Setting location permissions to Never in the settings.
Stopping startUpdatingLocation(), stopMonitoringSignificantLocationChanges(), and geofencing (using locationManager.stopMonitoringRegions()).
Calling locationManager.showsBackgroundLocationIndicator = false.
Ensuring that the CLLocationManager is fully invalidated.
Despite all of this, the background location indicator still remains in the status bar. I’ve tested it on real devices, as well as in the simulator, with no improvement.
Has anyone experienced something similar, or can suggest why this might be happening? Could this be related to an iOS 18+ issue?
Any insights or guidance would be greatly appreciated.
Hey folks,
I'm seeing an issue where my iOS app is getting an "unknown" error when US users try to sign in with Apple.
It works fine for users in other countries like the UK, Singapore, and Taiwan.
Could it be related to my developer account not being based in the US? Or have I missed something in my settings?
Thanks in advance!
Topic:
Privacy & Security
SubTopic:
Sign in with Apple
We are implementing authentication login in our iOS mobile application, and during the sign-in/sign-out process, a native system popup appears with the following message:
"This allows the app and website to share information about you."
This popup interrupts the user experience, and we are concerned it may cause confusion for end users and negatively impact the adoption of our login flow.
We would like clarification on the following points:
What triggers this popup during the authentication process?
Are there any recommended configurations or approaches to suppress or avoid this dialog?
If the popup cannot be avoided, what best practices are suggested to ensure a clear and seamless user experience?
Our objective is to provide a smooth, user-friendly authentication flow without unexpected system interruptions.
Topic:
Privacy & Security
SubTopic:
Sign in with Apple
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
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.
Hello everyone.
Hope this one finds you well)
I have an issue with integrating a FIDO2 server with ASAuthorizationController.
I have managed to register a user with passkey successfully, however when authenticating, the request for authentication response fails. The server can't validate signature field.
I can see 2 possible causes for the issue: ASAuthorizationPlatformPublicKeyCredentialAssertion.rawAuthenticatorData contains invalid algorithm information (the server tries ES256, which ultimately fails with false response), or I have messed up Base64URL encoding for the signature property (which is unlikely, since all other fields also require Base64URL, and the server consumes them with no issues).
So the question is, what encryption algorithm does ASAuthorizationController use? Maybe someone has other ideas regarding where to look into?
Please help. Thanks)
Hi,
My MACOS app has sensitive content and dont want user to take screenshot or to record the screen.
I tries window.sharingType=none. With this user can still record the screen.
I know that user can record with external device. But we dont want him to record using screen capture.
Can you please tell me how to detect when screen recording is active in MACOs apps? or how to prevent screen recording in MACOs apps.
Thanks
I regularly see folks confused by the difference in behaviour of app groups between macOS and iOS. There have been substantial changes in this space recently. While much of this is now covered in the official docs (r. 92322409), I’ve updated this post to go into all the gory details.
If you have questions or comments, start a new thread with the details. Put it in the App & System Services > Core OS topic area and tag it with Code Signing and Entitlements. Oh, and if your question is about app group containers, also include Files and Storage.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
App Groups: macOS vs iOS: Working Towards Harmony
There are two styles of app group ID:
iOS-style app group IDs start with group., for example, group.eskimo1.test.
macOS-style app group IDs start with your Team ID, for example, SKMME9E2Y8.eskimo1.test.
This difference has been the source of numerous weird problems over the years. Starting in Feb 2025, iOS-style app group IDs are fully supported on macOS for all product types [1]. If you’re writing new code that uses app groups, use an iOS-style app group ID. If you have existing code that uses a macOS-style app group ID, consider how you might transition to the iOS style.
IMPORTANT The Feb 2025 changes aren’t tied to an OS release but rather to a Developer website update. For more on this, see Feb 2025 Changes, below.
[1] If your product is a standalone executable, like a daemon or agent, wrap it in an app-like structure, as explained in Signing a daemon with a restricted entitlement.
iOS-Style App Group IDs
An iOS-style app group ID has the following features:
It starts with the group. prefix, for example, group.eskimo1.test.
You allocate it on the Developer website. This assigns the app group ID to your team.
You then claim access to it by listing it in the App Groups entitlement (com.apple.security.application-groups) entitlement.
That claim must be authorised by a provisioning profile [1]. The Developer website will only let you include your team’s app group IDs in your profile.
For more background on provisioning profiles, see TN3125 Inside Code Signing: Provisioning Profiles.
iOS-style app group IDs originated on iOS with iOS 3.0. They’ve always been supported on iOS’s child platforms (iPadOS, tvOS, visionOS, and watchOS). On the Mac:
They’ve been supported by Mac Catalyst since that technology was introduced.
Likewise for iOS Apps on Mac.
Starting in Feb 2025, they’re supported for other Mac products.
[1] Strictly speaking macOS does not require that, but if your claim is not authorised by a profile then you might run into other problems. See Entitlements-Validated Flag, below.
macOS-Style App Group IDs
A macOS-style app group ID has the following features:
It should start with your Team ID [1], for example, SKMME9E2Y8.eskimo1.test.
It can’t be explicitly allocated on the Developer website.
Code that isn’t sandboxed doesn’t need to claim the app group ID in the App Groups entitlement. [2]
To use an app group, claim the app group ID in the App Groups entitlement.
The App Groups entitlement is not restricted on macOS, meaning that this claim doesn’t need to be authorised by a provisioning profile [3].
However, if you claim an app group ID that’s not authorised in some way, you might run into problems. More on that later in this post.
If you submit an app to the Mac App Store, the submission process checks that your app group IDs make sense, that is, they either start with your Team ID (macOS style) or are assigned to your team (iOS style).
[1] This is “should” because, historically, macOS has not actually required it. However, that’s now changing, with things like app group container protection.
[2] This was true prior to macOS 15. It may still technically be true in macOS 15 and later, but the most important thing, access to the app group container, requires the entitlement because of app group container protection.
[3] Technically it’s a validation-required entitlement, something that we’ll come back to in the Entitlements-Validated Flag section.
Feb 2025 Changes
On 21 Feb 2025 we rolled out a change to the Developer website that completes the support for iOS-style app group IDs on the Mac. Specifically, it’s now possible to create a Mac provisioning profile that authorises the use of an iOS-style app group ID.
Note This change doesn’t affect Mac Catalyst or iOS Apps on Mac, which have always been able to use iOS-style app group IDs on the Mac.
Prior to this change it was possible to use an iOS-style app group ID on the Mac but that might result in some weird behaviour. Later sections of this post describe some of those problems. Of course, that information is now only of historical interest because, if you’re using an iOS-style app group, you can and should authorise that use with a provisioning profile.
We also started seeding Xcode 16.3, which has since been release. This is aware of the Developer website change, and its Signing & Capabilities editor actively encourages you to use iOS-style app groups IDs in all products.
Note This Xcode behaviour is the only option for iOS and its child platforms. With Xcode 16.3, it’s now the default for macOS as well. If you have existing project, enable this behaviour using the Register App Groups build setting.
Finally, we updated a number of app group documentation pages, including App Groups entitlement and Configuring app groups.
Crossing the Streams
In some circumstances you might need to have a single app that accesses both an iOS- and a macOS-style app group. For example:
You have a macOS app.
You want to migrate to an iOS-style app group ID, perhaps because you want to share an app group container with a Mac Catalyst app.
But you also need to access existing content in a container identified by a macOS-style app group ID.
Historically this caused problems (FB16664827) but, as of Jun 2025, this is fully supported (r. 148552377).
When the Developer website generates a Mac provisioning profile for an App ID with the App Groups capability, it automatically adds TEAM_ID.* to the list of app group IDs authorised by that profile (where TEAM_ID is your Team ID). This allows the app to claim access to every iOS-style app group ID associated with the App ID and any macOS-style app group IDs for that team. This helps in two circumstances:
It avoids any Mac App Store Connect submission problems, because App Store Connect can see that the app’s profile authorises its use of all the it app group IDs it claims access to.
Outside of App Store — for example, when you directly distribute an app using Developer ID signing — you no longer have to rely on macOS granting implicit access to macOS-style app group IDs. Rather, such access is explicitly authorised by your profile. That ensures that your entitlements remain validated, as discussed in the Entitlements-Validated Flag, below.
A Historical Interlude
These different styles of app group IDs have historical roots:
On iOS, third-party apps have always used provisioning profiles, and thus the App Groups entitlement is restricted just like any other entitlement.
On macOS, support for app groups was introduced before macOS had general support for provisioning profiles [1], and thus the App Groups entitlement is unrestricted.
The unrestricted nature of this entitlement poses two problems. The first is accidental collisions. How do you prevent folks from accidentally using an app group ID that’s in use by some other developer?
On iOS this is easy: The Developer website assigns each app group ID to a specific team, which guarantees uniqueness. macOS achieved a similar result by using the Team ID as a prefix.
The second problem is malicious reuse. How do you prevent a Mac app from accessing the app group containers of some other team?
Again, this isn’t an issue on iOS because the App Groups entitlement is restricted. On macOS the solution was for the Mac App Store to prevent you from publishing an app that used an app group ID that’s used by another team.
However, this only works for Mac App Store apps. Directly distributed apps were free to access app group containers of any other app. That was considered acceptable back when the Mac App Store was first introduced. That’s no longer the case, which is why macOS 15 introduced app group container protection. See App Group Container Protection, below.
[1] I’m specifically talking about provisioning profiles for directly distributed apps, that is, apps using Developer ID signing.
Entitlements-Validated Flag
The fact that the App Groups entitlement is unrestricted on macOS is, when you think about it, a little odd. The purpose of entitlements is to gate access to functionality. If an entitlement isn’t restricted, it’s not much of a gate!
For most unrestricted entitlements that’s not a problem. Specifically, for both the App Sandbox and Hardened Runtime entitlements, those are things you opt in to, so macOS is happy to accept the entitlement at face value. After all, if you want to cheat you can just not opt in [1].
However, this isn’t the case for the App Groups entitlement, which actually gates access to functionality. Dealing with this requires macOS to walk a fine line between security and compatibility. Part of that solution is the entitlements-validated flag.
When a process runs an executable, macOS checks its entitlements. There are two categories:
Restricted entitlements must be authorised by a provisioning profile. If your process runs an executable that claims a restricted entitlement that’s not authorised by a profile, the system traps.
Unrestricted entitlements don’t have to be authorised by a provisioning profile; they can be used by any code at any time.
However, the App Groups entitlement is a special type of unrestricted entitlement called a validation-required entitlement. If a process runs an executable that claims a validation-required entitlement and that claim is not authorised by a profile, the system allows the process to continue running but clears its entitlements-validated flag.
Some subsystems gate functionality on the entitlements-validated flag. For example, the data protection keychain uses entitlements as part of its access control model, but refuses to honour those entitlements if the entitlement-validated flag has been cleared.
Note If you’re curious about this flag, use the procinfo subcommand of launchctl to view it. For example:
% sudo launchctl procinfo `pgrep Test20230126`
…
code signing info = valid
…
entitlements validated
…
If the flag has been cleared, this line will be missing from the code signing info section.
Historically this was a serious problem because it prevented you from creating an app that uses both app groups and the data protection keychain [2] (r. 104859788). Fortunately that’s no longer an issue because the Developer website now lets you include the App Groups entitlement in macOS provisioning profiles.
[1] From the perspective of macOS checking entitlements at runtime. There are other checks:
The App Sandbox is mandatory for Mac App Store apps, but that’s checked when you upload the app to App Store Connect.
Directly distributed apps must be notarised to pass Gatekeeper, and the notary service requires that all executables enable the hardened runtime.
[2] See TN3137 On Mac keychain APIs and implementations for more about the data protection keychain.
App Groups and the Keychain
The differences described above explain a historical oddity associated with keychain access. The Sharing access to keychain items among a collection of apps article says:
Application groups
When you collect related apps into an application group using
the App Groups entitlement, they share access to a
group container, and gain the ability to message each other in
certain ways. You can use app group names as keychain access
group names, without adding them to the Keychain Access Groups
entitlement.
On iOS this makes a lot of sense:
The App Groups entitlement is a restricted entitlement on iOS.
The Developer website assigns each iOS-style app group ID to a specific team, which guarantees uniqueness.
The required group. prefix means that these keychain access groups can’t collide with other keychain access groups, which all start with an App ID prefix (there’s also Apple-only keychain access groups that start with other prefixes, like apple).
However, this didn’t work on macOS [1] because the App Groups entitlement is unrestricted there. However, with the Feb 2025 changes it should now be possible to use an iOS-style app group ID as a keychain access group on macOS.
Note I say “should” because I’ve not actually tried it (-:
Keep in mind that standard keychain access groups are protected the same way on all platforms, using the restricted Keychain Access Groups entitlement (keychain-access-groups).
[1] Except for Mac Catalyst apps and iOS Apps on Mac.
Not Entirely Unsatisfied
When you launch a Mac app that uses app groups you might see this log entry:
type: error
time: 10:41:35.858009+0000
process: taskgated-helper
subsystem: com.apple.ManagedClient
category: ProvisioningProfiles
message: com.example.apple-samplecode.Test92322409: Unsatisfied entitlements: com.apple.security.application-groups
Note The exact format of that log entry, and the circumstances under which it’s generated, varies by platform. On macOS 13.0.1 I was able to generate it by running a sandboxed app that claims a macOS-style app group ID in the App Groups entitlement and also claims some other restricted entitlement.
This looks kinda worrying and can be the source of problems. It means that the App Groups entitlement claims an entitlement that’s not authorised by a provisioning profile. On iOS this would trap, but on macOS the system allows the process to continue running. It does, however, clear the entitlements-validate flag. See Entitlements-Validated Flag for an in-depth discussion of this.
The easiest way to avoid this problem is to authorise your app group ID claims with a provisioning profile. If there’s some reason you can’t do that, watch out for potential problems with:
The data protection keychain — See the discussion of that in the Entitlements-Validated Flag and App Groups and the Keychain sections, both above.
App group container protection — See App Group Container Protection, below.
App Group Container Protection
macOS 15 introduced app group container protection. To access an app group container without user intervention:
Claim access to the app group by listing its ID in the App Groups entitlement.
Locate the container by calling the containerURL(forSecurityApplicationGroupIdentifier:) method.
Ensure that at least one of the following criteria are met:
Your app is deployed via the Mac App Store (A).
Or via TestFlight when running on macOS 15.1 or later (B).
Or the app group ID starts with your app’s Team ID (C).
Or your app’s claim to the app group is authorised by a provisioning profile embedded in the app (D) [1].
If your app doesn’t follow these rules, the system prompts the user to approve its access to the container. If granted, that consent applies only for the duration of that app instance.
For more on this, see:
The System Integrity Protection section of the macOS Sequoia 15 Release Notes
The System Integrity Protection section of the macOS Sequoia 15.1 Release Notes
WWDC 2024 Session 10123 What’s new in privacy, starting at 12:23
The above criteria mean that you rarely run into the app group authorisation prompt. If you encounter a case where that happens, feel free to start a thread here on DevForums. See the top of this post for info on the topic and tags to use.
Note Prior to the Feb 2025 change, things generally worked out fine when you app was deployed but you might’ve run into problems during development. That’s no longer the case.
[1] This is what allows Mac Catalyst and iOS Apps on Mac to work.
Revision History
2025-08-12 Added a reference to the Register App Groups build setting.
2025-07-28 Updated the Crossing the Streams section for the Jun 2025 change. Made other minor editorial changes.
2025-04-16 Rewrote the document now that iOS-style app group IDs are fully supported on the Mac. Changed the title from App Groups: macOS vs iOS: Fight! to App Groups: macOS vs iOS: Working Towards Harmony
2025-02-25 Fixed the Xcode version number mentioned in yesterday’s update.
2025-02-24 Added a quick update about the iOS-style app group IDs on macOS issue.
2024-11-05 Further clarified app group container protection. Reworked some other sections to account for this new reality.
2024-10-29 Clarified the points in App Group Container Protection.
2024-10-23 Fleshed out the discussion of app group container protection on macOS 15.
2024-09-04 Added information about app group container protection on macOS 15.
2023-01-31 Renamed the Not Entirely Unsatisfactory section to Not Entirely Unsatisfied. Updated it to describe the real impact of that log message.
2022-12-12 First posted.
Is there a way (in code or on the OAuth2 server/webpage) to specify the desired window size when using ASWebAuthenticationSession on macOS? I haven't found anything, and we would prefer the window to be narrower. For one of our users, the window is even stretched to the full screen width which looks completely broken…