Do I need to request entitlement during the prototyping phase?
This is a surprisingly tricky question. The answer is “It depends on the subsystem.” Lemme start with some terminology.
There are three flavours of entitlements:
-
An unrestricted entitlement does not need to be authorised by a provisioning profile. You only see these on macOS.
-
A restricted entitlement must be authorised by a provisioning profile, but any paid developer can create a profile that authorises the entitlement. Most of these are supported by Xcode’s Signing & Capabilities editor, but some require you to use the Developer website.
-
A managed entitlement is a restricted entitlement where you must apply for, and be approved to, create a profile that authorises its use.
A capability is our general name for configuring an app to support a feature. Many capabilities are associated with an entitlement. Setting such a capability on your App ID adds the entitlement to the App ID’s allowlist, and that flows through to the allowlist for provisioning profiles created for that App ID. Such capabilities can be unrestricted, restricted, or managed, just like their underlying entitlement.
There are two flavours of code:
-
Development-signed code is signed with an Apple Development signing identity (or one of its predecessors). Such code uses a development provisioning profile.
-
Distribution-signed code is signed with an Apple Distribution signing identity (or one of its predecessors). On iOS this includes Ad Hoc and In-House (Enterprise) distribution. On macOS this includes Developer ID signing. Such code uses a distribution provisioning profile.
Note On iOS and its child platforms, all third-party code must be authorised by a profile. On macOS, only code that uses a restricted entitlement needs a profile.
For more details about provisioning profiles, see TN3125 Inside Code Signing: Provisioning Profiles.
So, with that out of the way, lets look at the common approaches.
-
Some subsystems gate access to a feature based on whether the code is development- or distribution-signed. For example, a distribution-signed Network Extension content filter provider is restricted to supervised devices [1], but you can test a development-signed one on any device.
-
Some subsystems gate access to a feature based on a restricted entitlement. To use the feature, add the associated capability to your App ID, using either Xcode’s Signing & Capabilities editor or the Developer website. A good example of this is WeatherKit.
-
Some subsystems gate access to a feature based on a managed entitlement. In that case you’ll need to apply for, and be approved to use, the managed entitlement before you can start creating a prototype. A good example of this is the Endpoint Security subsystem on macOS.
-
Some subsystems adopt a hybrid approach. Access to the feature is gated by a managed entitlement but you can create a development provisioning profile to authorise that entitlement without any special permission from Apple. Later on, when you go to distribute your product, you must apply for, and be approved to use, the managed entitlement in distribution provisioning profiles. Family Controls is a good example of this.
Sometimes it can be hard to tell whether a specific capability is restricted to development-signed code. For a good way to do this, see Finding a Capability’s Distribution Restrictions.
Some capabilities are only available to specific team types. For information about that, see the Support capabilities sections of Developer Account Help. For example:
In the case of Network Extension’s app push providers, I believe that falls into the third category, that is, you have to be granted access to the managed entitlement before you can start work. If you create a development profile from an App ID with the Network Extension capability enabled, the allowlist looks like this:
% security cms -D -i Test735356_Dev.mobileprovision | plutil -p -
{
…
"Entitlements" => {
"application-identifier" => "SKMME9E2Y8.com.example.apple-samplecode.Test735356"
"com.apple.developer.networking.networkextension" => [
0 => "app-proxy-provider"
1 => "content-filter-provider"
2 => "packet-tunnel-provider"
3 => "dns-proxy"
4 => "dns-settings"
5 => "relay"
]
"com.apple.developer.team-identifier" => "SKMME9E2Y8"
"get-task-allow" => 1
"keychain-access-groups" => [
0 => "SKMME9E2Y8.*"
1 => "com.apple.token"
]
}
…
}
Note that this authorises many different NE provider types, but not the app-push-provider
one.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
[1] Well, that’s not quite true. See TN3134 Network Extension provider deployment for information about the exceptions.