Steps to create, build and run Network System Extension on device

Hi! I want to try create App Proxy network system extension. However, I don't see any certain steps for creating provision profile. Can someone describe what I have to do to create and test the extension.

How to configure provisioning profile to launch and test it on my device? Which options I should choose in Apple Developer account to generate a proper profile? What entitlements the application and the system extension target have to include? How to configure app group properly?

Does any ways to build and run system extension without provision profile exist?

Thank you in advance for the answer

Answered by Systems Engineer in 723454022

There is a lot going on here but in general you can start with the following to get started during development:

  1. Use an Xcode managed profile for development and build your container app with the embedded Network System Extension in Xcode. When you have created you build product, use the Product -> Show Build Folder in Finder option in Xcode to drag the container app to the /Application directory to run it. When finished with your test, drag the container app to the trash can. Do not remove it from the command line. I would recommend doing this on a virtual machine.

  2. You'll need to configure a container app set of entitlements that look something like the following (does not have to be exact):

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>com.apple.developer.networking.networkextension</key>
	<array>
		<string>app-proxy-provider</string>
	</array>
	<key>com.apple.developer.system-extension.install</key>
	<true/>
	<key>com.apple.security.app-sandbox</key>
	<true/>
	<key>com.apple.security.application-groups</key>
	<array>
		<string>$(TeamIdentifierPrefix)com.example.apple-samplecode.yourcontainerapp</string>
	</array>
	<key>com.apple.security.files.user-selected.read-write</key>
	<true/>
	<key>com.apple.security.network.client</key>
	<true/>
	<key>com.apple.security.network.server</key>
	<true/>
</dict>
</plist>

This will vary depending upon your circumstances of course, but this should get you started. Notice that only specific capabilities are set in the Developer Portal. Here is generally what the Network System Extension entitlements file looks like for an NEAppProxyProvider, again this does not have to be exact:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>com.apple.developer.networking.networkextension</key>
	<array>
		<string>app-proxy-provider</string>
	</array>
	<key>com.apple.security.app-sandbox</key>
	<true/>
	<key>com.apple.security.application-groups</key>
	<array>
		<string>$(TeamIdentifierPrefix)com.example.apple-samplecode.yourcontainerapp.proxyprovider</string>
	</array>
	<key>com.apple.security.files.user-selected.read-write</key>
	<true/>
	<key>com.apple.security.network.client</key>
	<true/>
	<key>com.apple.security.network.server</key>
	<true/>
</dict>
</plist>
  1. When you are ready to ship something to either a set of internal testers or out to a production environment you have a few different choice on how to proceed based on how #1 and #2 are setup. You can setup new deployment bundle identifiers and then manage production provisioning profiles for this workflow. You can also use the same ones for development in deployment. Generally I would tend to lean towards managing a new set of bundle identifiers and profiles, but I like to isolated my active development vs production workflows and you'll have to do what works for you.
Accepted Answer

There is a lot going on here but in general you can start with the following to get started during development:

  1. Use an Xcode managed profile for development and build your container app with the embedded Network System Extension in Xcode. When you have created you build product, use the Product -> Show Build Folder in Finder option in Xcode to drag the container app to the /Application directory to run it. When finished with your test, drag the container app to the trash can. Do not remove it from the command line. I would recommend doing this on a virtual machine.

  2. You'll need to configure a container app set of entitlements that look something like the following (does not have to be exact):

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>com.apple.developer.networking.networkextension</key>
	<array>
		<string>app-proxy-provider</string>
	</array>
	<key>com.apple.developer.system-extension.install</key>
	<true/>
	<key>com.apple.security.app-sandbox</key>
	<true/>
	<key>com.apple.security.application-groups</key>
	<array>
		<string>$(TeamIdentifierPrefix)com.example.apple-samplecode.yourcontainerapp</string>
	</array>
	<key>com.apple.security.files.user-selected.read-write</key>
	<true/>
	<key>com.apple.security.network.client</key>
	<true/>
	<key>com.apple.security.network.server</key>
	<true/>
</dict>
</plist>

This will vary depending upon your circumstances of course, but this should get you started. Notice that only specific capabilities are set in the Developer Portal. Here is generally what the Network System Extension entitlements file looks like for an NEAppProxyProvider, again this does not have to be exact:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>com.apple.developer.networking.networkextension</key>
	<array>
		<string>app-proxy-provider</string>
	</array>
	<key>com.apple.security.app-sandbox</key>
	<true/>
	<key>com.apple.security.application-groups</key>
	<array>
		<string>$(TeamIdentifierPrefix)com.example.apple-samplecode.yourcontainerapp.proxyprovider</string>
	</array>
	<key>com.apple.security.files.user-selected.read-write</key>
	<true/>
	<key>com.apple.security.network.client</key>
	<true/>
	<key>com.apple.security.network.server</key>
	<true/>
</dict>
</plist>
  1. When you are ready to ship something to either a set of internal testers or out to a production environment you have a few different choice on how to proceed based on how #1 and #2 are setup. You can setup new deployment bundle identifiers and then manage production provisioning profiles for this workflow. You can also use the same ones for development in deployment. Generally I would tend to lean towards managing a new set of bundle identifiers and profiles, but I like to isolated my active development vs production workflows and you'll have to do what works for you.

Thank you a lot for a clear explanation! I have managed to build and test my project following the steps you have provided! However, let's consider a situation when the Xcode can not generate a profile automatically, and a developer has to contact an Apple account admin to get a proper provisioning profile. Is there any way to test a system extension without getting the profile from the admin? For instance, would it work "normally" if the SIP is disabled?

However, let's consider a situation when the Xcode can not generate a profile automatically, and a developer has to contact an Apple account admin to get a proper provisioning profile. Is there any way to test a system extension without getting the profile from the admin? For instance, would it work "normally" if the SIP is disabled?

The standard way to do this would be to try to enable to sign and run locally with an adhoc signature. However, when you add entitlements into the mix those items need to be allowlisted by a provisioning profile for usage. This is when you'll need some sort of provisioning profile and so I would contact your account admin.

Ok, thank you!

Steps to create, build and run Network System Extension on device
 
 
Q