title: On the Mac, how to specify a custom tunnel provider in a App per App VPN configuration profile?
body: <p>I am developing a VPN desktop client for the macOS platform and I am trying to achieve App Per-App VPN. From my understanding, this feature works by letting the user install a configuration profile, that contains information about which apps are included in the feature. A sample  configuration <a href="https://github.com/alfonsotesauro/App-Per-App-VPN-Config-Profile" rel="nofollow noreferrer">profile</a> is the following:</p>
  <pre><code>&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
  &lt;!DOCTYPE plist PUBLIC &quot;-//Apple//DTD PLIST 1.0//EN&quot; &quot;http://www.apple.com/DTDs/PropertyList-1.0.dtd&quot;&gt;
  &lt;plist version=&quot;1.0&quot;&gt;
     &lt;dict&gt;
     &lt;key&gt;PayloadContent&lt;/key&gt;
     &lt;array&gt;
        &lt;dict&gt;
           &lt;key&gt;PayloadDescription&lt;/key&gt;
           &lt;string&gt;Configures VPN app mapping settings&lt;/string&gt;
           &lt;key&gt;PayloadDisplayName&lt;/key&gt;
           &lt;string&gt;VPN (Per-App VPN TCP App Mapping)&lt;/string&gt;
           &lt;key&gt;PayloadIdentifier&lt;/key&gt;
           &lt;string&gt;com.f5.access.macos.perapp.vpn.appmapping&lt;/string&gt;
           &lt;key&gt;PayloadOrganization&lt;/key&gt;
           &lt;string/&gt;
           &lt;key&gt;PayloadType&lt;/key&gt;
           &lt;string&gt;com.apple.vpn.managed.appmapping&lt;/string&gt;
           &lt;key&gt;PayloadUUID&lt;/key&gt;
           &lt;string&gt;6B015006-D559-4C5C-B197-737CF4DCFA96&lt;/string&gt;
           &lt;key&gt;PayloadVersion&lt;/key&gt;
           &lt;integer&gt;1&lt;/integer&gt;
           &lt;key&gt;AppLayerVPNMapping&lt;/key&gt;
           &lt;array&gt;
              &lt;dict&gt;
                 &lt;key&gt;Identifier&lt;/key&gt;
                 &lt;string&gt;com.google.Chrome&lt;/string&gt;
                 &lt;key&gt;VPNUUID&lt;/key&gt;
                 &lt;string&gt;6A015006-D559-4C5C-B197-737CF4DCFA96&lt;/string&gt;
                 &lt;key&gt;SigningIdentifier&lt;/key&gt;
                 &lt;string&gt;com.google.Chrome&lt;/string&gt;
                 &lt;key&gt;DesignatedRequirement&lt;/key&gt;
                 &lt;string&gt;(identifier &quot;com.google.Chrome&quot; or identifier &quot;com.google.Chrome.beta&quot; or identifier &quot;com.google.Chrome.dev&quot; or identifier &quot;com.google.Chrome.canary&quot;) and (certificate leaf = H&quot;85cee8254216185620ddc8851c7a9fc4dfe120ef&quot; or certificate leaf = H&quot;c9a99324ca3fcb23dbcc36bd5fd4f9753305130a&quot;)&lt;/string&gt;
              &lt;/dict&gt;
              &lt;dict&gt;
                 &lt;key&gt;Identifier&lt;/key&gt;
                 &lt;string&gt;org.mozilla.firefox&lt;/string&gt;
                 &lt;key&gt;VPNUUID&lt;/key&gt;
                 &lt;string&gt;6A015006-D559-4C5C-B197-737CF4DCFA96&lt;/string&gt;
                 &lt;key&gt;SigningIdentifier&lt;/key&gt;
                 &lt;string&gt;org.mozilla.firefox&lt;/string&gt;
                 &lt;key&gt;DesignatedRequirement&lt;/key&gt;
                 &lt;string&gt;anchor apple generic and certificate leaf[field.1.2.840.113635.100.6.1.9] /* exists */ or anchor apple generic and certificate 1[field.1.2.840.113635.100.6.2.6] /* exists */ and certificate leaf[field.1.2.840.113635.100.6.1.13] /* exists */ and certificate leaf[subject.OU] = &quot;43AQ936H96&quot;&lt;/string&gt;
                 &lt;/dict&gt;
           &lt;/array&gt;
        &lt;/dict&gt;
        &lt;dict&gt;
           &lt;key&gt;PayloadType&lt;/key&gt;
           &lt;string&gt;com.apple.vpn.managed.applayer&lt;/string&gt;
           &lt;key&gt;PayloadDescription&lt;/key&gt;
           &lt;string&gt;Configures VPN settings, including authentication.&lt;/string&gt;
           &lt;key&gt;PayloadDisplayName&lt;/key&gt;
           &lt;string&gt;VPN (Per-App VPN App Mapping)&lt;/string&gt;
           &lt;key&gt;PayloadIdentifier&lt;/key&gt;
           &lt;string&gt;com.f5.access.macos.perapp.vpn.vpn&lt;/string&gt;
           &lt;key&gt;PayloadOrganization&lt;/key&gt;
           &lt;string/&gt;
           &lt;key&gt;PayloadUUID&lt;/key&gt;
           &lt;string&gt;5A015006-D559-4C5C-B197-737CF4DCFA96&lt;/string&gt;
           &lt;key&gt;PayloadVersion&lt;/key&gt;
           &lt;integer&gt;1&lt;/integer&gt;
           &lt;key&gt;Proxies&lt;/key&gt;
           &lt;dict/&gt;
           &lt;key&gt;UserDefinedName&lt;/key&gt;
           &lt;string&gt;App Mapping&lt;/string&gt;
           &lt;key&gt;VPN&lt;/key&gt;
              &lt;dict&gt;
                 &lt;key&gt;AuthName&lt;/key&gt;
                 &lt;string&gt;test&lt;/string&gt;
                 &lt;key&gt;AuthPassword&lt;/key&gt;
                 &lt;string&gt;test&lt;/string&gt;
                 &lt;key&gt;AuthenticationMethod&lt;/key&gt;
                 &lt;string&gt;Password&lt;/string&gt;
                 &lt;key&gt;RemoteAddress&lt;/key&gt;
                 &lt;string&gt;https://portal.example.com&lt;/string&gt;
                 &lt;key&gt;OnDemandMatchAppEnabled&lt;/key&gt;
                 &lt;true/&gt;
                 &lt;key&gt;ProviderType&lt;/key&gt;
                 &lt;string&gt;packet-tunnel&lt;/string&gt;
                 &lt;key&gt;ProviderBundleIdentifier&lt;/key&gt;
                 &lt;string&gt;com.f5.access.macos.PacketTunnel&lt;/string&gt;
              &lt;/dict&gt;
           &lt;key&gt;VPNSubType&lt;/key&gt;
           &lt;string&gt;com.f5.access.macos&lt;/string&gt;
           &lt;key&gt;VPNType&lt;/key&gt;
           &lt;string&gt;VPN&lt;/string&gt;
           &lt;key&gt;VendorConfig&lt;/key&gt;
           &lt;dict/&gt;
           &lt;key&gt;VPNUUID&lt;/key&gt;
           &lt;string&gt;6A015006-D559-4C5C-B197-737CF4DCFA96&lt;/string&gt;
        &lt;/dict&gt;
      &lt;/array&gt;
      &lt;key&gt;PayloadDescription&lt;/key&gt;
      &lt;string&gt;PerApp VPN Payload TCP Test&lt;/string&gt;
      &lt;key&gt;PayloadDisplayName&lt;/key&gt;
      &lt;string&gt;MDM - Per-App VPN TCP&lt;/string&gt;
      &lt;key&gt;PayloadIdentifier&lt;/key&gt;
      &lt;string&gt;com.f5.access.macos.perapp.vpn&lt;/string&gt;
      &lt;key&gt;PayloadOrganization&lt;/key&gt;
      &lt;string/&gt;
      &lt;key&gt;PayloadRemovalDisallowed&lt;/key&gt;
      &lt;false/&gt;
      &lt;key&gt;PayloadType&lt;/key&gt;
      &lt;string&gt;Configuration&lt;/string&gt;
      &lt;key&gt;PayloadUUID&lt;/key&gt;
      &lt;string&gt;06A850CC-BC81-43FB-AA16-42BE472D2421&lt;/string&gt;
      &lt;key&gt;PayloadVersion&lt;/key&gt;
      &lt;integer&gt;1&lt;/integer&gt;
     &lt;/dict&gt;
  &lt;/plist&gt;
  </code></pre>
  <p>When saved in a .mobileconfig (sorry I do not know which kind of file extension is appropriate for a macOS config profile so I used the iOS extension) profile, and double clicking on it, macOS properly says that the config profile is available for install in System Preferences -&gt; Profiles. When I go there, I can install the profile, although it is not signed, and I can see that for example Google Chrome loses Internet connectivity since the config file contains many placeholders. But I believe this means that the config file is doing its job, and the system simply does not find the relevant VPN network configuration. My next step would be to fill the data with actual Ike2 credentials etc. but my end goal is to use this Per App VPN with a custom VPN protocol (Wireguard) that my application supports in its network extension appex, using a custom tunnel provider. I really have no clue on how to configure the config profile for this Scenario, so I was hoping somebody could bring me in the right direction. Thanks for any help.</p>