I looked at this page and can't tell which entitlements are special.
I couldn't find any docs on how to figure out which ones require a dedicated request to Apple. Are there any docs for it?
HKVerifiableClinicalRecordQuery
Request URL: https://developer.apple.com/contact/request/verifiable-health-records/
Entitlements Key: com.apple.developer.healthkit. Must contain the health-records from within its array.
WWDC: https://developer.apple.com/videos/play/wwdc2021/10089/
networking-multicast
Request URL: https://developer.apple.com/contact/request/networking-multicast
Entitlements Key: com.apple.developer.networking.multicast
usernotifications.filtering
Request URL: https://developer.apple.com/contact/request/notification-service
Entitlements Key: com.apple.developer.usernotifications.filtering
critical-alerts
Request URL: https://developer.apple.com/contact/request/notifications-critical-alerts-entitlement
Entitlements key: com.apple.developer.usernotifications.critical-alerts
Local Push Connectivity
Request URL: https://developer.apple.com/contact/request/local-push-connectivity
Entitlements Key: Not sure!
I think the com.apple.developer.networking.networkextension key must exist. The key's value must contain app-push-provider within its array
hotspot-helper
Request URL: https://developer.apple.com/contact/request/hotspot-helper/
Entitlements key: com.apple.developer.networking.HotspotHelper
Do NOT mistake this for NEHotspotConfigurationManager. NEHotspotHelper and NEHotspotConfigurationManager are different and require distinct entitlements.
NetworkExtension used to need it but doesn't need it any more. See Dev Forums - Quinn
To use these facilities you previously had to be granted special
entitlements by Apple. This policy has now changed for
NetworkExtension providers. Any developer can now enable the
NetworkExtension provider entitlement like they would any other
entitlement.
com.apple.managed.vpn.shared keychain access group
Request URL: https://developer.apple.com/support/technical/
Entitlements key: com.apple.managed.vpn.shared
However there's a catch with Network Extensions. From the same Dev Forums, Quinn says:
#9 — After moving to the new entitlement process, my app no longer has access to the com.apple.managed.vpn.shared
keychain access group. How can I regain that access?
Access to this keychain access group requires a special entitlement. If you need that entitlement, please open a DTS tech support incident and we will take things from there.
IMPORTANT This entitlement is only necessary if your VPN supports configuration via a configuration profile and needs to access credentials from that profile (as discussed in the Profile Configuration section of the NETunnelProviderManager Reference). Many VPN apps don’t need this facility.
If I understand this correct, basically if you need to use com.apple.managed.vpn.shared keychain access group entitlement for VPN Credential Storage then you need two entitlements:
Network Extension entitlement which can be done through Apple Developer Portal
Another Special entitlement as mentioned above.
It's also worth noting that every dev team gets to create two DTS tickets a year for free. Beyond that you have to pay.
Included with each enrollment are two Technical Support Incidents, which will expire at the end of your membership year. You will receive two new TSIs when you renew your membership. View your available TSIs, their expiration dates, and your request history in the Code-level Support section in your account. Your TSIs are grouped by expiration date, and the ones that expire soonest will be used first.
Additional TSIs are available for purchase in either a 2-pack for $99 USD or 5-Pack for $249 USD in the Code-level Support section in your account. TSIs purchased separately expire one year from the date of activation.
I'm not sure if any other entitlement needs a special request or not, but these were the ones that I found
How do I add the special entitlement into my app?
Special entitlements are not associated with your App ID, they're added at the very last step of creating your provisioning profile.
When you create an «iOS, macOS, tvOS» «Development / Distribution / In-House (Enterprise)» provisioning profile for the Team ID «Team ID», after selecting the devices to be included in the profile, you should see a new page entitled “Do you need additional entitlements?”. Select “«hotspot helper template name»” from the Entitlements popup to include this special entitlement in your new profile.
Once you’ve finished generating the profile, you can use it in Xcode like any other manually-generated profile.
source: Apple Forums
I have the special Entitlements but Xcode isn't building it correctly for me
Xcode can’t give a special entitlement to you by itself. Hence I don't think Automatic Code Signing would work for special entitlments. It’s something that Apple embeds into your provisioning profile — only at Apple Developer portal. So you have to generate the provisioning profile from Apple Developer portal and then download it from Xcode
Sample email you get from Apple upon approval:
Hello,
This Developer Team has already been assigned the HotspotHelper capability as part of the NetworkExtension entitlement.
To use this special entitlement you must create a new provisioning profile in the Certificates, Identifiers & Profiles section of your Developer account and select the entitlement after the "Do you need additional entitlements?" page.
Please note, it may take 1-3 business days for this entitlement to be visible. Once you've finished generating the profile, you can use it in Xcode like any other manually-generated profile.
IMPORTANT: If you have problems getting this to work, read Technote 2415 "Entitlements Troubleshooting" for troubleshooting steps.
If you have questions about adding or using this entitlement that are not answered by this Technote, please visit the Apple Developer Forums or contact Apple Developer Support.
Thank you,
Apple
How do you add multiple special entitlements?
This is not possible out of the box. The long-term solution for this
would be for Apple to change the developer web site to allow you to
select multiple templates. Please file a bug report requesting that,
then post your bug number, just for the record.
I’m not sure whether there’s a good short-term option. My advice is
that you talk to Apple Developer Programs Support to see whether they
can help you (start [here][ref] and then go Membership and Account >
Other Membership or Account Questions). Make sure to:
Reference this thread
Include your bug number
Tell them to reach out to me if they need clarifications
source: Dev Forums
Do I need the special entitlement only for my main app target?
Check each page's doc.
But I think it depends. e.g. the doc for Local Push Connectivity say:
After you receive the entitlement, apply it to both your app target and your provider extension target.
Source: Docs
What are extended entitlements?
They're exactly the same thing as special entitlements. Just a different name for it.
How long does it actually take to get approved?
Apple will respond within a week. But then usually it's not a straightforward approval. They'd ask for a bunch of changes or justifications and then approve/deny. Sometimes it takes 1 month overall.
According to your answer, i think it would be better share the link content which you shared which needs to login Developer Account. If I find new ones i will add here.
Multicast Networking Entitlement Request
This entitlement allows advanced networking apps to interact with their local network by sending multicast and broadcast IP packets and browsing for arbitrary Bonjour service types. Your app may need to access this level of networking in order to communicate with custom or non-standard devices or to act as a network utility.
Hotspot Helper Request
The NEHotspotHelper interface allows Wi-Fi network implementers to facilitate connections to the large-scale wireless networks that they manage. For a complete explanation of all Wi-Fi management APIs available on iOS, see Technical Q&A QA1942: iOS Wi-Fi Management APIs.
Request a Critical Alert Notifications Entitlement
When a user enables critical alert notifications, your app can send push notifications that play a sound at an app-specified volume when the device is locked, muted, or has Do Not Disturb enabled.
Related
I need to use Network Extension features in an app, particularly to use the Proxy features. The doc says:
Except when you use the NEHotspotHelper class, you do not need to obtain entitlements from Apple to use Network Extension classes. However, you still need to enable the Network Extension entitlement via the Developer portal. To request an entitlement to use the NEHotspotHelper class, visit https://developer.apple.com/contact/network-extension.
I went to the Developer portal, but I couldn't find how to enable the Network Extension entitlement. Is it because my role is "admin" rather than "team agent"? Or someone can tell me how to enable that entitlement?
Due to the confused document and function missing of xcode 8.1, this cost me one whole week to find the solution.
Make sure you enrolled apple developer program (it's not free, you need to pay $100 per year)
Go to https://developer.apple.com/account/ios/identifier/bundle
Select Identifiers => App IDs
Click your app on the right(if there is no, you could create one with xcode),
Click edit button, check the network-extension checkbox
NOTE1: Since November 10th 2016, you dont need entitlement from apple to use network-extension
NOTE2: If you are using Hotspot Helper, go to https://developer.apple.com/contact/network-extension/
If you are using VPN Manager, simply use capability menu of xcode project config.
With Xcode 9 there is an easier way to add network extension entitlements inside Xcode.
Add your developer account to Xcode from Preferences -> Account if you didn't add before.
Select General tab from your app target and then set your developer account details.
From your app target select Capabilities tab and select the switch right of the Network Extensions. Then select the capabilties you are going to use.
Then check your YOUR_PROJECT_NAME.entitlements plist file. Capabilities you selected should be on the Network Extensions list.
As a last step check your AppId from developer portal if everything is fine.
Edit your App ID on Apple's dev portal and look for the Network Extensions capability/service. You also need Personal VPN to create and manage configurations in your app.
The Network Extensions option is new. I'm not sure when it appeared, maybe in the last six months?. It used to be you had to request permission for it and it'd show up under the provisioning profile entitlements, but now Apple's opened it up to everyone.
You might also need to add this to your entitlements file(s). At least you used to - I'm not positive about needing this with the new approach:
<key>com.apple.developer.networking.networkextension</key>
<array>
<string>app-proxy-provider</string>
<string>content-filter-provider</string>
<string>packet-tunnel-provider</string>
</array>
When creating a App Group id in the Provisioning Portal (or whatever its called now), it says to "Enter a unique identifier for your App Group, starting with the string 'group'" and seems to enforce that in the entry field. Also, lots of sample code uses app group id strings like "group.com.company.blah".
However, the definitive sections I've seen to linked throughout the documentation,
App Sandbox Design Guide > App Sandbox In Depth > Container Directories and File System Access > The Application Group Container Directory and Entitlements Key Rerefence > Enabling App Sandbox > Adding an App to an App Group, directly contradict this, clearly stating "must begin with your development team ID, followed by a period".
The examples given in those section are like "Z123456789.com.example.app-group" and "DG29478A379Q6483R9214.HolstFirstAppSuite" respectively. (whah, is that last one a super weird team id or what?)
So with this inconsistency, what do I do to get a App Group ID to work? Should I enter in the Provisioning Portal "group.TEAM-ID.com.example.blah"? And should I use this same string in my source code strings, or omit the "group." part to be like the many code examples? Or is the documentation wrong and the team id is never needed?
Context ... I've been trying to update an iOS cocoapod's test app so I can see extension <-> app communication in action. After updating the app ids and group id to one's in my control, and when using a group id similar to the project's original one, like "group.com.mycompany.thingie", I see containerURLForSecurityApplicationGroupIdentifier: do nothing but return nil and nothing else has fixed it.
UPDATE: (added this for clarity seeing how SO informs me that this Q is getting many hits) It turns out this stuff is more forgiving than I originally thought, as the nil result turns out to have been (mostly?) my doing. See the answer & its comment thread. I haven't checked to see if the documentation & examples are any clearer yet.
On https://developer.apple.com inside "Certificates, Identifiers & Profiles" when you go to the "App Groups" section and first generate your App Group, all that is required is the enforced group.com.companyname.appname
As long as com.companyname.appname matches what you have setup as the bundle identifier for your target underneath general, you should be able to then go to "Capabilities" tab, turn on "App Groups" click the refresh symbol and the group you just created in Provisioning Portal should appear there, as "group.com.companyname.appname" you'll have the option to check it off, and then will have an error with entitlements. Clicking "fix issue" should automatically resolve it.
Now if you navigate to you entitlements file you'll notice that "com.apple.security.applications-groups" will have an item and it will be set to the exact same "group.com.companyname.appname" value.
I've tested on devices and have no issues yet. This doesn't account for the inconsistency in documentation, but I can guarantee that this works.
I got bitten by the inconsistency in this between iOS and macOS while submitting the macOS Sierra version of my app.
group.better.fyi works for iOS submissions but results in the following error during macOS submissions (runs perfectly well otherwise, with no warnings or errors):
ERROR ITMS-90286: "Invalid Code Signing Entitlements. Your application bundle's signature contains code signing entitlements that are not supported on macOS. Specifically, value '[group.better.fyi]' for key 'com.apple.security.application-groups' in 'ind.ie.Better-Mac.pkg/Payload/Better.app/Contents/PlugIns/Blocker-Mac.appex/Contents/MacOS/Blocker-Mac' is not supported. This value should be a string or an array of strings, each starting with your TEAMID followed by a dot '.' ."
Replacing that with $(TeamIdentifierPrefix)better.fyi in the Capabilities tab under App Groups fixed the issue.
This does, of course, create an inconsistency between the iOS and Mac apps.
tl;dr version: https://stackoverflow.com/a/66647419/15809
But if you want to know all the details behind all this, please see below.
iOS
In the portal, all app group IDs created must start with group.; the portal will actually enforce that, so it's not even possible to register a group there without that prefix.
If the app group ID is then set on an app ID in the portal and an iOS provisioning profile is created for that app ID, the app group is embedded into the profile exactly as it has been registered. Take a look at such a profile and you will find the app group ID there.
If an iOS app has app group IDs in its codesign entitlement file, codesign will ensure that the group IDs from the entitlement are also found in the provisioning profile, otherwise it will refuse to sign the app. The provisioning profile thus whitelists the usage of these app groups.
When you configure an app group ID for an app in Xcode at the capabilities section, Xcode will put the ID into the codesign entitlements file for you. The app groups configured there for iOS apps must match exactly the app group IDs registered in the portal.
macOS
For macOS, though, things are entirely different!
If you add an app group ID to an app ID in the portal, this has no effect on macOS provisioning profiles created for that app ID. Have a look yourself; the app group ID is nowhere found in the generated profiles! Thus on macOS, a provisioning profile does not whitelist the usage of any app groups. You can put any app group ID into your entitlement files, this will always sign as codesign doesn't care. Codesign doesn't even care if your app group ID is prefixed by your team ID (or at least it didn't use to in the past, maybe it does as of today).
Unlike on iOS, the uniqueness of app group IDs on macOS is not enforced by the portal, it is enforced by the fact that Apple requires your app group IDs to start with your team ID, so uniqueness across teams is guaranteed and enforcing uniqueness within your own team is your own task.
Actually you don't need to register app group IDs for macOS apps at all in the portal. It's enough to just put your desired app group ID into your Xcode project capabilities and thus into your entitlement file. Many people think they have correctly registered their macOS app group when they register group.TEAM_ID.<whatever> in the portal and some magic makes this group work without group. prefix on the Mac, but that isn't the case. They just registered an iOS group of that name and the reason why TEAM.<whatever> works on the Mac is because that group doesn't require registration in the portal.
Now some readers will say: Wait a minute; if I can just put any app group ID into my entitlement files and it will always sign, who is actually enforcing that it is prefixed with my team ID? The Mac App Store. The Mac App Store won't allow you to publish an app with an app group ID that is not prefixed with the team ID of the publisher. If you try, the upload will fail.
App Groups and Security
You may wonder: Who is enforcing that app groups are prefixed by your team ID for apps distributed outside of the app store? Nobody. But then apps distributed outside of the app store can claim to be a member of any app group, even one from a different developer team, so how would that be secure? It isn't. Apps distributed outside of the app store don't even have to be sandboxed and if they are not sandboxed, they have access to your entire disk, including all app group folders of all apps, so how would that become any less secure by incorrectly claiming to be a member of an app group?
Apps distributed outside the app store may be sandboxed if they wish to restrict themselves for security reasons but even if they opt-in to that, they are free to poke as many holes into their own sandbox as they need or desire since unlike when distributing via the app store, there is no review that will ensure they only poke required and justified holes.
On iOS all apps are always sandboxed and distributed via the App Store, so this question doesn't even arise.
App Groups and Keychain Sharing
What about keychain item sharing? Keychain item sharing via app groups only works on iOS, not on macOS; for exactly that reason! It would be insecure on Mac. On macOS only sharing with keychain access groups works and those are in the provisioning profiles, also in macOS profiles, and for those codesign will always enforce that the profile whitelists them before it signs anything.
Reference from Apple
You'd like to have all of that confirmed directly by Apple? Sure, here is the reference provided by our most famous Apple tech support guru, Quinn:
https://developer.apple.com/forums/thread/133677?answerId=422887022#422887022
I know how to sign an app with Appstore mobile provision, and how to re-sign an Adhoc-signed IPA with Appstore mobile provision. This is not my question.
My question is, can you submit Adhoc-signed IPA to Appstore / iTunesConnect, and have it pass Apple verification and eventually be distributed through Appstore. Why? So that I don't have to store a redundant Appstore-signed IPA along every Adhoc-signed release candidate IPA, and don't have to do the extra step of re-signing that requires a Mac machine.
When using Application Loader, it is able to find all the stupid little errors, like missing icons and launch images, but even when I upload Adhoc-signed IPA through Application Loader, it doesn't complain about non-appstore mobile provision (which is very easy to verify, just like icons).
I have also found out in my testing, that when you take an Appstore-signed IPA (which you are not supposed to be able to install on devices unless distributed through Appstore), it is possible to install it on testing devices, provided the device already has Adhoc provision profile on it (same AppID, same distribution cert).
So, this makes me think Apple just strips out mobile provision when distributing through Appstore.
There was a similar question (closed) from almost 3 years ago, but the OP never provided an answer if it had actually worked: Submitted app to appstore with adhoc profile.
I hope someone since then had actually tried with it confirmed results.
There are a few targeted inner questions within your main question, I'll call attention to each part as we go -- as always, I'll be happy to revise or clarify if I miss something. I suppose it is only a closely guarded secret because much of the reasoning for it working come back to cryptographic details as a function of the Public Key Infrastructure system that backs Apple's provisioning -- This stuff gets deep fast so it is considered by some to be [dark] magic. Hopefully this will shine some light on what is going on!
TL;DR Version
Yes you can, but it is technically an unsupported use case that may change at any time. This works because what information iTunes Connect chooses to validate does not include the single differentiating factor between an App Store and AdHoc distribution provisioning profile. Since this is technically not a permitted configuration, I'd advocate for at least having a backup plan since Apple may change iTunes Connect validation policy at any time breaking this submission edge case.
Now for the curious, the here is the rest of the story...
Can you submit Adhoc-signed IPA to Appstore / iTunesConnect, and have it pass Apple verification and eventually be distributed through Appstore[?]
As of this specific iteration of iTunesConnect and the Application Loader (4 Sept 2014 / Xcode 5.1.1), yes you can submit an AdHoc signed build and have it accepted through the pipeline. The eagle-eyed reader will note that my 'Yes' comes with a built-in escape hatch -- Because of the data encoded in AdHoc vs App Store provisioning profiles is nearly identical coupled with what parts of these files iTunesConnect is actually using for validation, an AdHoc provisioning profile presents to the delivery pipeline in the same manner as the AppStore version of the same app.
Should the provisioning format change between AdHoc and App Store files to explicitly differentiate the two types of Distribution provisioning profiles or should Apple iTunesConnect engineers change server-side validation rules, it is distinctly possible that this undocumented behavior will stop working. Of course we all know that we are supposed to use the App Store provisioning profile, as per Developer documentation in the App Distribution Guide > Submitting Your App > About Store Provisioning Profiles (https://developer.apple.com/library/ios/documentation/IDEs/Conceptual/AppDistributionGuide/SubmittingYourApp/SubmittingYourApp.html#//apple_ref/doc/uid/TP40012582-CH9-SW32) [emphasis added]:
A store distribution provisioning profile contains a single App ID that matches one or more of your apps, and a distribution certificate. For iOS apps, you need a store provisioning profile to submit your app.
...but this other avenue works for now. If you do choose to use this avenue, you just need to be aware that it is not the documented behavior and thus would be subject to change at any point in time, likely without advanced notice. Since it is skirting the edges of submission requirements it would probably be good to at least have a backup plan setup for the case of Apple changing provisioning or iTC validation requirements -- Murphy's law would dictate that these validation changes would happen at the most inopportune time.
Stepping off the 'Best Practice' Soapbox and turning to the technical side of things...
Why [does this work]?
As you may or may not know, provisioning profiles are composed of exactly 1 appId, one or more signing certificates, and zero or more test devices.
Related Reading: I've got a longer answer to What are code signing identities? that speaks in more detail to the parts of the codesign process.
In this case the question is 'why do AdHoc profiles work when the documentation says you need to have an App Store profile?'
The guts of a provisioning profile contain a cryptographically signed .plist that includes the information identified above, plus some additional metadata. On an OS X machine you can open Terminal and run:
security cms -D -i path/to/AdHoc.mobileprovision
...and in a separate Terminal window run the App Store profile equivalent:
security cms -D -i path/to/AppStore.mobileprovison
These commands will dump out the plist portion of the provisioning profile to their respective Terminal windows. When you scroll through the contents of both windows you will note that the following sections are identical:
AppIDName
AppliationIdentifierPrefix
DeveloperCertificates
Entitlements
TeamIdentifier
Version
The profile's metadata are different, but those are entirely expected differences that only matter for validating profile validity, or for humans interrogating the profile:
CreationDate
ExpirationDate
Name
TimeToLive
UUID
The salient points to take away are:
The DeveloperCertificates blocks are identical between both profiles.
The AdHoc profile only adds information (ProvisionedDevices) to the structure and format of the App Store profile.
The contents of the DeveloperCertificates array is the DER encoded X.509 iPhone Distribution Certificate -- The exact same as the one in your keychain. Is is important to note that this DER data is only the public portion of your Distribution certificate public-private keypair, and it can only be used by others to authenticate the application's signature came from you -- It can not be used to resign a binary as you.
If you paste the contents of DeveloperCertificates:Array:Data element into an ASN.1 decoder (http://lapo.it/asn1js/) and compare the elements of the output to the information encoded in the Distribution certificate included in the Keychain, you'll find that it is an exact copy of the public Distribution certificate you downloaded from Apple after submitting your Certificate Signing Request though the Certificates, Identifiers, and Profiles tool.
Because both the AdHoc and App Store provisioning profiles use the same public key certificate as their signing identity, they are inherently using the same private key when generating the application's signature. This means that the signature generated when signing with an AdHoc profile is functionally identical to one generated when signing with the App Store profile
When Apple performs a signature validation on iTunes Connect during the submission process, both and AdHoc signed cryptographic signature and an App Store signed cryptographic signature will successfully validate against the Distribution Certificate Apple has on file as both provisioning profiles are backed by the same Distribution Certificate.
So the signatures match, but why doesn't the extra information in AdHoc profiles trip up the submission?
Your original question suggests that you have familiarity with iOS' app install policies. For the benefit of someone stumbling across this answer in the future I'll briefly summarize:
iOS operates on a 'deny-all unless specifically permitted' policy. That is, iOS assumes you are not allowed to install an app unless a specific 'grant' has been allowed. For devices coming from the App Store, the app's signature includes Apple's App Store identity for which iOS has a specific 'grant' privilege. AdHoc installs by default fall under the 'deny' policy and the ProvisionedDevices section of a Development or AdHoc profile are the specific 'grant' privileges. The app will install outside of the App Store if all of the following hold true:
The application's cryptographic signature is valid
The application's embedded provisioning profile's cryptographic signature is still valid (the profile hasn't been tampered with)
The application's embedded provisioning profile's ExpirationDate hasn't passed and the current time isn't before the CreationDate
The embedded profile or a profile installed to the device match the AppId being proposed for installation.
The embedded profile or a profile installed to the device contain an entry in ProvisionedDevices that exactly match the device's UDID.
As we saw above, the app identity and signing information is identical between an App Store profile and and Ad Hoc profile -- the addition of ProvisionedDevices serves only to add these 'grant' privileges for an external (outside of App Store) distribution mechanism. It turns out that iTunes Connect / Application Loader validation is currently only validating that a Distribution profile was used for the app's signature, not that the profile that was used was an App Store profile instead of an AdHoc profile.
This boils down to the fact that the as of Version 1 (ala Version block in the plist) the only differentiating factor between AdHoc and App Store distribution profiles is the presence or absence of the ProvisionedDevices block. It turns out that as of today, this is not a detail that Apple looks for when interrogating the profile that was used, thus the binary passes the automated portions of app verification. They definitely do check that the AppId in the profile matches what the App claims, that the signing identity matches what was used to sign the binary, expiration dates, and any entitlements used match what is found in the automated scan of the app, in addition to the items you highlighted in your original question (version checks between iTunes Connect and the info.plist, iconography presence, iconography sizes, etc.)
Hypothetically, in a subsequent iTunes Connect / Application Loader update, they could start checking for the absence of this key in the embedded.mobileprovision profile that exists within the submitted binary and auto-reject the submission on the grounds that an App Store profile was not used. Similarly, if the provisioning profile format was updated (ex. Version=2) they could add a new element that explicitly calls out the type of profile and auto-reject if it isn't an App Store type. It could perhaps look like this:
<key>ProfileType</key>
<integer>1</integer>
Where the integer value could be 1, 2 or, 3 depending on the type of profile in use, consistent with the formats used in things like Info.plist for identifying supported device families (iPhone-only, iPad-only, or Universal). This would clarify other questions that have been asked about identifying the type of build.
Related Reading:
How to detect that a provisioning profile is for development or distribution, programmatically
Check if app is ad-hoc|dev|app-store build at run time
So, this makes me think Apple just strips out mobile provision when distributing through Appstore.
Yes they do! If you look at archived versions of the apps you submitted you'll find that the contents of the app contain embedded.mobileprovision -- if you then go download the same version from the App Store, you'll find that file missing. Apple only uses embedded.mobileprovision to verify the contents of your app during the submission and review process. When the app is 'Processing for App Store' the final package is assembled and the embedded profile is removed.
There is a lot of information about iOS distribution. I think I understand the different distriubution models, but I am looking for best practice for distributing an app to a client.
I have a client who has an Enterprise developer account and uses AirWatch for MDM. Here is how I am going to recommend to them that we distribute the app to their organization since they have no one technical on staff that has any experience with Xcode or iOS development and they will not be given access to the source code:
Add me as a member of their developer account
I build the app using their certificate
I give them the .ipa and plist file to distribute either through MDM or website.
Is this the correct way to do this? What if I am going to sell this same app to three clients - would I do it a different way? Is there anything else that needs to be done to distribute through AirWatch?
Again, looking for best practice and how others are handling this situation. Please clarify if I have anything wrong.
UPDATE: Thank you all for the answers. From what I have learned how this is done depends directly on how the client wants to handle the situation. In the end the client added me as an admin on their account (we have worked together quite a bit). I was able to create the distribution profile, build, and deploy the app to them. Not all clients will do this for security reasons. In that case, they will need to provide you will a cert as stated below, or you will need to build the app on one of their machines as Buckeye said below...or go through Apple to distribute the app to them.
Feel free to correct any of this info if it is incorrect. I really think this is helpful information for a lot devs.
I am accepting Patrick's answer because it is the closest to what I actually did.
There are two ways you can do this, but for both you must be added as a member of your client's developer team. Once you have done this, you (or more likely your client) will choose weather to use their in-house certificate or your own distribution certificate that you will manage.
It can be done either way, it is only a matter of who will have authority in the future to submit apps with the same certificate under the same account. That authority resides in the possession of the associated key pair of the certificate. If you are added to the client's dev team and download their distribution certificate, you will NOT have this key and cannot sign distribution builds with associated provisioning profiles.
Therefore, you must either get a .p12 export of the certificate (which contains the key) from the client to install on your machine so that you may sign with it. This will allow you to submit from your machine, but you are then in possession of your clien'ts private key, which they would like to protect. Your other option is to use your own Certificate Signing Request to create a Distribution Certificate on the client's developer account. In this situation, only you have control over the certificate and the client must create new ones if they wish to work with other developers in the future.
Once you have done that, here is an informative guide for enterprise distribution.
As an Enterprise Agent I will tell you that unless your client lives under a rock (technically speaking regarding the Apple dev portal) I doubt they're going to give up the private key and cert. If they have zero legal/contractual access to the source code you've created the only course of action, speaking from experience, would be for you to visit their facility with the source code, compile it on their box that houses the private key & enterprise distribution cert, build & deliver the IPA and finally take the source back with you. That is how I have compiled every build with a 3rd party vendor where we don't own the source and need to deploy internally.
On the flip side of this argument if the client is, for some wild reason, willing to give up the keys to their enterprise castle and export the private key & enterprise distribution cert for you to use... for YOUR sake I would get in writing what the scope of your usage is with that cert and somehow document the fact you have deleted the key & cert after the process is over. Don't open yourself up to liability because if they share it with you there's a chance they may also share it with someone else and as we all know, not all development entities play by the rules. You wouldn't want to get accused of creating some rogue app under their name.
Regarding re-signing the IPA file... AirWatch won't let you do it. AW interrogates the IPA when you upload it and it will note that the embedded provisioning profile doesn't match the re-signed IPA and tank. It becomes a chicken & egg situation where you need the provisioning profile on the device before you install the app however AirWatch won't let you deploy the app unless the aforementioned embedded profile is correct.
Also, #Caleb is correct regarding B2B but the pricing model goes from the project to per-seat (iOS device). In other words if your contract is "you can install this app on an unlimited number of devices" the B2B approach is going to blow up in everyone's faces.
EDIT:
Below are your options when editing a Development Provisioning Profile in an Enterprise iOS Account:
Obviously here you can pick & choose developers and their devices from within the portal that can compile to that profile.
Now here are your "options" for editing the Enterprise Provisioning Profile:
As you can see you don't get an option to edit which portal users or devices can use this profile because it's tied to the Agent's CSR/private key and is deployed globally.
You would need:
Their certificate.
Their provisioning profile.
It's a quite common practise to do this.
My question is, is this the correct way to do this?
Yes.
What if I am going to sell this same app to 3 clients, would I do it a different way?
No, you'll do the same thing. You'll need to build the app separately for each client using each client's distribution certificate.
Another option is to build the app and sell it to your clients using the B2B distribution mechanism.
We have had a number of apps built by a 3rd party developer. I cannot remember how this was done in the past, but they have just updated 2 of our apps to work correctly with iOS 5.x
The agreement is that they will build and sign the files ready for us to upload to iTunes. We cannot build the code as the agreement doesn't include the source.
I have sent them the Distribution Provisioning Profile (.mobileprovision) but they have asked for the "Certificate for Keychain access"
Perhaps I am being overly cautious, but am I right in thinking I need to export my Developer Certificate as a .cer file and email that to them? We do trust the company, but is this the correct way to do things? Is it allowed by Apple?
The 3rd party have no access to our accounts (developer centre / iTunes connect) and we have no access to the source code.
Thank you
If they're going to build things as you, they'll need your certificate and private key as well as the provisioning profile. I don't think there's any way round that if they're going to do the building and code-signing.
I think it's a fairly typical way to do things, in a situation where the client has the dev account but the developer owns the source.
Even if the development company did have access to your iTunes account, you'd still need to send them the private key that your certificate was created with.
Not tried it myself, but seems like there is a way to re-sign the binary (IPA file). Check this link It uses a utility called iReSign