Provisioning profile missing entitlement

My iOS app uses CloudKit key-value storage. I have not updated the app in a few years but it works fine. Since it was last updated, I transferred the app from an old organization to my personal developer account. Now that I'm working on the app again I get an error: Provisioning profile "iOS Team Provisioning Profile: com.company.app" doesn't match the entitlements file's value for the com.apple.developer.ubiquity-kvstore-identifier entitlement.

In the entitlement file, it has $(TeamIdentifierPrefix)$(CFBundleIdentifier) as the value for iCloud Key-Value Store. I've verified the variables resolve as expected. When I parse the provisioning profile there is no entitlement value for key-value storage. What am I getting wrong?

I want to start by understanding your goals. The com.apple.developer.ubiquity-kvstore-identifier value starts with your Team ID, and the app’s Team ID changed as part of the app transfer. That means that your new version of the app won’t be able to access settings created by the old version. Is that OK?

If so, we can dig into why Xcode is being snarky. But if it’s not OK — if, for example, you’ve stored critical user data in the iCloud key-value store [1] — then things get more complex.

Share and Enjoy

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

[1] This is something I strongly recommend against. The UserDefaults subsystem, and thus the key-value store, is intended for preferences, not critical user data.

It's just preferences stored in the key-value store. So yes, it is acceptable for that data to be lost.

To clarify, I have updated the entitlement value with the correct Team ID.

It's just preferences stored in the key-value store.

Cool.

I have updated the entitlement value with the correct Team ID.

OK. But you shouldn’t need to do that because Xcode should pick up the correct Team ID via the $(TeamIdentifierPrefix) syntax.


As to your main issue, I suspect that Xcode has cached something that’s causing this. In situations like this I generally approach the problem in two ways:

  1. First, I create a new dummy test app, with a new bundle ID and thence a new App ID, to check whether this is working in general.
  2. Once I’ve confirmed that, I then start trying to resolve the issue with my real project.

With regards that second step:

  1. In Signing & Capabilities, make sure that “Automatically manage signing” is enabled, the new team is selected in the Team popup, and that Signing Certificate is set to Development.
  2. Choose Product > Clean Build Folder.
  3. Quit Xcode.
  4. In Finder, navigate to ~/Library/Developer/Xcode/UserData/Provisioning Profiles.
  5. And trash everything in that folder.
  6. Relaunch Xcode and let automatic code signing do its magic.

Share and Enjoy

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

I've created a dummy test app with the same setup as the real one and signing works. However, after deleting derived data and all provisioning profiles, the real app still cannot sign.

I've created a dummy test app with the same setup as the real one and signing works.

Cool.

after deleting derived data and all provisioning profiles, the real app still cannot sign.

Bummer.

So my next suggestion is that you create a new test project but this time choose the same bundle ID as your main app. If that works, there’s something about your main app’s project setup that’s causing the problem. OTOH, if it fails in the same way, it confirms that this is specific to the code signing setup.

Share and Enjoy

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

I created a new project with the same bundle id and capabilities. Same error.

OK, so definitely not your project.

If you temporarily remove the iCloud key-value storage capability capability, the app builds, right? If so, look in the build log for an entry like this:

CodeSign …/Test811382.app (in target 'Test811382' from project 'Test811382')
    cd …/Test811382
    
    Signing Identity:     "Apple Development: Quinn Quinn (7XFU7D52S4)"
    Provisioning Profile: "iOS Team Provisioning Profile: com.example.apple-samplecode.Test811382"
                          (5db3ba83-07fb-4780-8ca4-f87de64fd20d)

Note For info on how to get the build log, see Command [something] failed with a nonzero exit code.

The UUID in that entry is the UUID of the provisioning profile that Xcode is using to sign your app. You should find that in ~/Library/Developer/Xcode/UserData/Provisioning Profiles. Now dump the contents of that profile like so:

% security cms -D -i 5db3ba83-07fb-4780-8ca4-f87de64fd20d.mobileprovision | plutil -p -
{
  …
  "Entitlements" => {
    "application-identifier" => "SKMME9E2Y8.com.example.apple-samplecode.Test811382"
    "com.apple.developer.icloud-container-development-container-identifiers" => [
    ]
    "com.apple.developer.icloud-container-identifiers" => [
    ]
    "com.apple.developer.icloud-services" => "*"
    "com.apple.developer.team-identifier" => "SKMME9E2Y8"
    "com.apple.developer.ubiquity-container-identifiers" => [
    ]
    "com.apple.developer.ubiquity-kvstore-identifier" => "SKMME9E2Y8.*"
    "get-task-allow" => true
    "keychain-access-groups" => [
      0 => "SKMME9E2Y8.*"
      1 => "com.apple.token"
    ]
  }
  …
}

What do you see?

If you don’t want to post your real Team ID and bundle ID, feel free to redact those. Just make sure you redact them consistently. To continue the example above, you might replace all instances of SKMME9E2Y8 with TEAM_ID.

Share and Enjoy

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

Yes, the app builds fine when disabling key-value storage.

Dumping the provisioning profile shows this:

  "Entitlements" => {
    "application-identifier" => "TEAM_ID.com.ORGANIZATION.APP"
    "aps-environment" => "development"
    "com.apple.developer.icloud-container-development-container-identifiers" => [
      0 => "iCloud.ORGANIZATION.APP"
    ]
    "com.apple.developer.icloud-container-environment" => [
      0 => "Production"
      1 => "Development"
    ]
    "com.apple.developer.icloud-container-identifiers" => [
      0 => "iCloud.ORGANIZATION.APP"
    ]
    "com.apple.developer.icloud-services" => "*"
    "com.apple.developer.team-identifier" => "TEAM_ID"
    "com.apple.developer.ubiquity-container-identifiers" => [
      0 => "iCloud.ORGANIZATION.APP"
    ]
    "com.apple.developer.ubiquity-kvstore-identifier" => "OTHER_TEAM_ID.com.ORGANIZATION.APP"
    "com.apple.security.application-groups" => [
      0 => "group.ORGANIZATION"
    ]
    "get-task-allow" => true
    "keychain-access-groups" => [
      0 => "TEAM_ID.*"
      1 => "com.apple.token"
    ]
  }

So it does appear that the old team ID for com.apple.developer.ubiquity-kvstore-identifier.

Well, that’s… I’d say unexpected, but I was starting to think that might be the case given the results of our previous diagnostic tests |-:

Try this:

  1. On the Developer website, navigate to the TEAM_ID.com.ORGANIZATION.APP App ID.
  2. Remove the Cloud capability and save that change.
  3. Create a new test provisioning profile for that App ID and download that.
  4. Go back to the App ID, re-enable the Cloud capability, and save that change.
  5. Create another new test provisioning profile and download that.
  6. Dump the entitlement allowlist in both profiles.

The profile from step 3 should have no com.apple.developer.ubiquity-kvstore-identifier entry, and I’m curious what you see in the profile from step 5.

Share and Enjoy

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

You are correct that the profile from step 3 has no entry for key-value storage. However, the profile from step 5 still uses the old team ID.

One thing I realized while looking at this is that I'm still a member of the old team. That team's developer subscription is no longer active but I'm still a member. I almost left it when I realized but decided to only follow the steps you suggested.

Step 3 (iCloud not enabled)

"Entitlements" => {
    "application-identifier" => "TEAM_ID.com.ORGANIZATION.APP"
    "aps-environment" => "production"
    "beta-reports-active" => true
    "com.apple.developer.team-identifier" => "TEAM_ID"
    "com.apple.security.application-groups" => [
        0 => "group.ORGANIZATION"
    ]
    "get-task-allow" => false
    "keychain-access-groups" => [
        0 => "TEAM_ID.*"
        1 => "com.apple.token"
    ]
}

Step 5 (iCloud re-enabled)

"Entitlements" => {
    "application-identifier" => "TEAM_ID.com.ORGANIZATION.APP"
    "aps-environment" => "production"
    "beta-reports-active" => true
    "com.apple.developer.icloud-container-development-container-identifiers" => [
        0 => "iCloud.ORGANIZATION.APP"
    ]
    "com.apple.developer.icloud-container-environment" => [
        0 => "Production"
        1 => "Development"
    ]
    "com.apple.developer.icloud-container-identifiers" => [
        0 => "iCloud.ORGANIZATION.APP"
    ]
    "com.apple.developer.icloud-services" => "*"
    "com.apple.developer.team-identifier" => "TEAM_ID"
    "com.apple.developer.ubiquity-container-identifiers" => [
        0 => "iCloud.ORGANIZATION.APP"
    ]
    "com.apple.developer.ubiquity-kvstore-identifier" => "OTHER_TEAM_ID.com.ORGANIZATION.APP"
    "com.apple.security.application-groups" => [
        0 => "group.ORGANIZATION"
    ]
    "get-task-allow" => false
    "keychain-access-groups" => [
        0 => "TEAM_ID.*"
        1 => "com.apple.token"
    ]
}
Provisioning profile missing entitlement
 
 
Q