Thanks for being a part of WWDC25!

How did we do? We’d love to know your thoughts on this year’s conference. Take the survey here

Enterprise Vendor Id changing when it shouldn't

Hi All, Really weird one here...

I have two bundle ids with the same reverse dns name...

com.company.app1 com.company.app2

app1 was installed on the device a year ago. app2 was also installed on the device a year ago but I released a new updated version and pushed it to the device via Microsoft InTunes.

A year ago the vendor Id's matched as the bundle id's were on the same domain of com.company.

Now for some reason the new build of app2 or any new app I build isn't being recognised as on the same domain as app1 even though the bundle id should make it so and so the Vendor Id's do not match and it is causing me major problems as I rely on the Vendor Id to exchange data between the apps on a certain device.

In an enterprise environment, does anyone know of any other reason or things that could affect the Vendor Id?

According to Apple docs, it seems that only the bundle name affects the vendor id but it isn't following those rules in this instance.

Just to confirm, you’re talking about the identifierForVendor property here, right? [edited to fix the link to the property’s documentation]

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Yes that is correct DTS Engineer.

Have you any ideas? :D.

I generally avoid gating critical functionality on identifierForVendor because of all the weird circumstances under which it can change. The docs have similar advice:

if your app stores the value of this property anywhere, you should gracefully handle situations where the identifier changes.

That’s especially important when distributing outside the App Store, because then you’re relying on a bunch of fallback paths (the bundle ID process discussed in the docs being just one of them).

If you take a fresh device, one that’s never seen app1 or app2, and then install both app1 and app2, do they get the same value?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Hi DTS Engineer, We've been relying and using the vendor id in an Enterprise environment for about 10 years now without issue :(.

For a test I have done as you suggested.

I installed the app1 .ipa that was built a while back on a newly wiped device and also installed app2 .ipa that was built recently.

The vendor id's don't match even though the bundle name is on the same dns of com.companyname.xxxx.

Its almost like something else is affecting it...

Is there anything else within your knowledge that can also affect Vendor ID's matching? Certificates or signing or anything?

Its almost like something else is affecting it...

Right. My best guess is that some element of your code signing is leaking into this calculation. But that’s just a guess. Let’s run a test…

If you re-sign app1 with the same code-signing identity you’re using for app2, do the identifierForVendor values then line up?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

I normally use automatic code signing so my understanding of some of the elements in the code signing process is limited, but looking in the mobileprovision the only differences I can see from App1 and App2 are:

  • They have a different DER-Encoded-Profile
  • App2 has an array of provisionedDevices where as App1 has the following key:

<key>ProvisionsAllDevices</key> <true/>

Looking at an older version of App2's mobileprovision it also doesn't have a set list of provisioned devices.

I don't know how this automatically would have changed though or if it affects the vendor id or how to change it back.

I don't suppose you are available for hire or if you can recommend anyone official to assist in this matter via screen share?

So the variation in the provisioning device mechanism indicates that you’re installing these apps via two different channels:

  • The presence of ProvisionedDevices indicates a Development or Ad Hoc signed build, which is limited to a specific set of devices.

  • OTOH, ProvisionsAllDevices indicates an In-House (Enterprise) signed build.

For all the gory details here, see TN3125 Inside Code Signing: Provisioning Profiles.

In theory that shouldn’t affect identifierForVendor but, as I mentioned above, there’s a bunch of hidden state here.

What I’m trying to tease apart here is whether the problem you’re seeing is caused by:

  • Different generations of code signing [1]

  • Or wider issues

Based on your original post I assumed that app1 and app2 were both In-House (Enterprise) signed, but that leaves the possibility of a generational change. My goal is to get both apps on the same generation. However, in trying to do that you varied the distribution channel, which is another factor that might confuse things. So I’d like to avoid dealing with that and instead focus on the original two factors.

My suggestion is that you sign both app1 and app2 the same way and see if you still have problems with identifierForVendor.

Now, I tried this here in my office and I saw the results I expected. I created two apps that only differ by the last component in their bundle ID and installed them on my device:

  • If both apps are Development signed, the identifiers are the same.

  • If both apps are Ad Hoc signed, the identifiers are the same.

  • If I mix Development and Ad Hoc, the identifiers are the same.

Sadly, I don’t have an easy path to test In-House (Enterprise) case )-:

This is Xcode 16.3 targeting iOS 18.5.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

[1] Various code signing factors have changed over the years, and it’s easy to imagine how those changes might interact with identifierForVendor generation.

Hi DTS Engineer, Thank you for taking the time to reply and for providing that information.

For the signing process, I have always ticked "Automatically manage signing".

I then select the "Team" and manually type the "Bundle Identifier".

I tried rebuilding app1 and app2 and the vendor ids are in sync.

The problem is we have about 1200 devices and they all have app1 installed which is basically an app that logs the vendor id and registers a device. The other 5 or 6 apps we have including app2 then use the same shared vendor id.

If possible we need a way so new builds still produce the same vendor id as app1.

We haven't confirmed it yet, but someone has stated that it doesn't seem to have affected iPad 8th Gens. (We are still in the process of confirming this).

I also noticed that just now I received a Command Line Tools 16.4 update (not sure if this could have been some sort of hot fix) but in my XCode settings - Version 16.3 (16E140) the command line tools is still set to 16.3... it doesn't give me an option to select 16.4.

I tried a new build of app2 anyway just to see if the update had fixed it but its still the same.

I tried rebuilding app1 and app2 and the vendor ids are in sync.

OK. That’s good to confirm.

Are you able to create new versions of app1 and app2 that are signed with your In-House (Enterprise) signing identity? That’s the thing that I can’t do [1], and it’s the last bit of the test matrix that we need to fill in.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

[1] Well, I could, but it’d require a bunch of extra work that I just don’t have time for in given that DTS is neck deep in WWDC preparation right now.

Hi DTS Engineer, I tried a few more tests and can also confirm that 8th gen iPads are not immune to the issue.

If I create new versions of App1 and App2 the vendor Id's are in sync when they are installed on a fresh device.

I also tried: On an affected device, (with old app1 and new app2 builds) I tried updating app1 with a new app1 but the vendor ids are still different.

What do you make of all this?

Enterprise Vendor Id changing when it shouldn't
 
 
Q