Skip to main content

Deploy with .mobileconfig Profiles

Build Apple .mobileconfig profiles that install Vylos WireGuard tunnels as read-only managed system entries.

Choose a Profile Type

GoalVPN payload typeDelivery requirement
Route eligible device traffic through one tunnelcom.apple.vpn.managedInstall directly or deliver through MDM.
Route assigned managed applications through Vyloscom.apple.vpn.managed.applayerMDM is required for production app assignments, even if the VPN profile itself was installed directly.

Both profile types create a managed tunnel in Vylos. They are separate from Managed App Configuration, which controls app behavior but does not install a VPN.

Where Each Setting Belongs

CapabilityProfile location
WireGuard interface and peersVendorConfig.WgQuickConfigBase64 or WgQuickConfig
Split DNS and search domainsVendorConfig.VylosConfigBase64 or VylosConfig
Automatic activationVPN.OnDemandEnabled and VPN.OnDemandRules
Block connections without the VPNVPN.IncludeAllNetworks
Per-app activationTop-level OnDemandMatchAppEnabled and VPNUUID
Vylos restrictions and preferencesManaged App Configuration, not the VPN profile

The examples below use Apple's property-list form. If your MDM presents a form instead, reproduce the same dictionary nesting and types rather than flattening dotted names into literal keys.

WireGuard Configuration Transport

Place exactly one of the following keys inside the VPN payload's VendorConfig dictionary:

KeyValue
WgQuickConfigRaw multiline UTF-8 contents of a WireGuard .conf file.
WgQuickConfigBase64Single-line Base64 encoding of those same UTF-8 .conf contents.

Use WgQuickConfigBase64 when an MDM field does not preserve line breaks. Vylos rejects a payload containing both keys because the intended source would be ambiguous.

Base64 is a transport encoding, not encryption. The encoded value is the .conf text itself—not a .vylos file, a ZIP archive, or a path to either one.

On macOS, this command copies a paste-ready value to the clipboard:

bash
base64 -i "tunnel.conf" | tr -d '\n' | pbcopy

base64 encodes the file, tr -d '\n' removes line breaks from the encoded output, and pbcopy places the result on the clipboard. In an MDM key-value editor, paste that result as WgQuickConfigBase64 and omit WgQuickConfig.

Split DNS Settings Transport

Add exactly one of these optional keys to the same VendorConfig dictionary when the managed tunnel uses Split DNS:

KeyValue
VylosConfigRaw multiline UTF-8 Vylos settings in the settings.conf format.
VylosConfigBase64Single-line Base64 encoding of those same UTF-8 Vylos settings.

Use VylosConfigBase64 for MDM delivery so a key-value editor cannot remove or alter line breaks. Vylos continues to accept the raw VylosConfig key for directly authored profiles, but rejects a payload containing both forms.

Create a settings.conf file containing the managed Split DNS rules:

settings.conf
ini
[SplitDNS]
Domains = corp.example.com, *.internal.example.com
SearchDomains = example.com

Then copy its single-line Base64 value on macOS:

bash
base64 -i "settings.conf" | tr -d '\n' | pbcopy

Paste the result as VylosConfigBase64. The WireGuard configuration must also provide at least one DNS server under [Interface]; Domains selects which DNS queries use those servers, while SearchDomains supplies suffixes for bare hostnames. AllowedIPs remains responsible for traffic routing and is independent of Split DNS.

The Vylos settings transport is part of the VPN profile. It is not a Managed App Configuration key.

Kill Switch for Managed Tunnels

Use Apple's IncludeAllNetworks key in the VPN payload to give a managed device-wide tunnel kill-switch behavior. Do not add the app-created [Routing] section to VylosConfig; managed routing policy belongs to Apple's VPN dictionary.

Add the following beside RemoteAddress and AuthenticationMethod inside the payload's VPN dictionary:

xml
<key>IncludeAllNetworks</key>
<integer>1</integer>

Configure automatic activation separately with Apple's OnDemandRules. Vylos reads both values from NetworkExtension and shows the resulting On-Demand and kill-switch state as read-only tunnel details.

IncludeAllNetworks does not replace or broaden the WireGuard AllowedIPs inside WgQuickConfig or WgQuickConfigBase64. It prevents ordinary traffic from bypassing the VPN; AllowedIPs still determines whether a peer can carry each destination.

WireGuard routes across all peersEffective managed policy
0.0.0.0/0, ::/0 or equivalent complete coverageFull IPv4 and IPv6 tunnel protection.
Complete coverage for only one address familyThat family uses the VPN; destinations in the other family are blocked unless explicitly routed.
Private networks, hosts, or other partial rangesStrict allowlist: only covered destinations can connect, even while the tunnel is connected.
No AllowedIPs routesOrdinary IP traffic is blocked.

Ensure that each DNS server in the WireGuard [Interface] section is covered by at least one peer's AllowedIPs. Otherwise the kill switch also blocks access to that DNS server. Vylos reports the effective route scope and any uncovered DNS servers in the read-only managed-tunnel details; users cannot change the profile there.

Use the restricted forms deliberately for organization allowlists. For a conventional dual-stack full tunnel, deploy both 0.0.0.0/0 and ::/0. Vylos never edits an administrator's route set.

Apple's all-network routing still exempts traffic needed for network control and certain device services. Review the IncludeAllNetworks VPN payload field and NEVPNProtocol.includeAllNetworks before deployment.

Device-Wide Profile

Use com.apple.vpn.managed for a conventional device-wide tunnel. Replace every example identifier, UUID, key, address, and endpoint before deployment.

xml
<?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>PayloadDisplayName</key>
    <string>Vylos Managed Tunnel</string>
    <key>PayloadIdentifier</key>
    <string>com.example.vylos.vpn</string>
    <key>PayloadType</key>
    <string>Configuration</string>
    <key>PayloadUUID</key>
    <string>00000000-0000-0000-0000-000000000003</string>
    <key>PayloadVersion</key>
    <integer>1</integer>
    <key>PayloadContent</key>
    <array>
        <dict>
            <key>PayloadDisplayName</key>
            <string>VPN</string>
            <key>PayloadIdentifier</key>
            <string>com.example.vylos.vpn.corp</string>
            <key>PayloadType</key>
            <string>com.apple.vpn.managed</string>
            <key>PayloadUUID</key>
            <string>00000000-0000-0000-0000-000000000004</string>
            <key>PayloadVersion</key>
            <integer>1</integer>
            <key>UserDefinedName</key>
            <string>Corporate VPN</string>
            <key>VPNType</key>
            <string>VPN</string>
            <key>VPNSubType</key>
            <string>io.cbnventures.vylos</string>
            <key>VendorConfig</key>
            <dict>
                <key>WgQuickConfig</key>
                <string>[Interface]
PrivateKey = AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
Address = 10.0.0.2/32
DNS = 10.0.0.1

[Peer]
PublicKey = BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB=
AllowedIPs = 0.0.0.0/0
Endpoint = vpn.example.com:51820
PersistentKeepalive = 25
</string>
                <key>VylosConfig</key>
                <string>[SplitDNS]
Domains = corp.example.com, *.internal.example.com
SearchDomains = example.com
</string>
            </dict>
            <key>VPN</key>
            <dict>
                <key>RemoteAddress</key>
                <string>vpn.example.com</string>
                <key>AuthenticationMethod</key>
                <string>Password</string>
            </dict>
        </dict>
    </array>
</dict>
</plist>

Generate unique UUIDs with uuidgen. Each additional tunnel is another com.apple.vpn.managed dictionary inside the outer PayloadContent array.

Before deployment, replace every example-specific value:

ReplaceWith
Both PayloadIdentifier valuesIdentifiers owned by your organization.
Both PayloadUUID valuesFresh UUIDs generated with uuidgen.
UserDefinedName and display namesThe user-facing tunnel and profile names.
The complete WgQuickConfig valueThe device's real WireGuard configuration, including unique client keys and address.
RemoteAddressThe WireGuard endpoint hostname or address used for display and system metadata.
The optional VylosConfig valueYour Split DNS settings, or remove the key when Split DNS is not used.

Never deploy the sample private key, public key, addresses, endpoint, or UUIDs.

To use a single-line value, replace the example WgQuickConfig key and multiline string with:

xml
<key>WgQuickConfigBase64</key>
<string>BASE64_ENCODED_CONF</string>

Replace the example VylosConfig key and multiline string in the same way:

xml
<key>VylosConfigBase64</key>
<string>BASE64_ENCODED_SETTINGS_CONF</string>

Per-App Profile

Use com.apple.vpn.managed.applayer with Vylos's packet-tunnel provider for per-app WireGuard routing. The payload accepts the same WgQuickConfig and WgQuickConfigBase64 alternatives, plus optional VylosConfig or VylosConfigBase64 Split DNS settings.

SettingValue
PayloadTypecom.apple.vpn.managed.applayer
VPNTypeVPN
VPNSubTypeio.cbnventures.vylos
VPN.ProviderBundleIdentifierio.cbnventures.vylos.packet-tunnel
VPN.ProviderTypepacket-tunnel
VPNUUIDUnique value shared with every managed app assigned to this VPN.
OnDemandMatchAppEnabledtrue to connect when an assigned app initiates network traffic.

The following dictionary can replace the device-wide VPN dictionary inside the profile's PayloadContent array:

xml
<dict>
    <key>PayloadDisplayName</key>
    <string>Vylos Per-App VPN</string>
    <key>PayloadIdentifier</key>
    <string>com.example.vylos.vpn.per-app</string>
    <key>PayloadType</key>
    <string>com.apple.vpn.managed.applayer</string>
    <key>PayloadUUID</key>
    <string>00000000-0000-0000-0000-000000000005</string>
    <key>PayloadVersion</key>
    <integer>1</integer>
    <key>UserDefinedName</key>
    <string>Corporate Per-App VPN</string>
    <key>VPNType</key>
    <string>VPN</string>
    <key>VPNSubType</key>
    <string>io.cbnventures.vylos</string>
    <key>VPNUUID</key>
    <string>00000000-0000-0000-0000-000000000006</string>
    <key>OnDemandMatchAppEnabled</key>
    <true/>
    <key>VendorConfig</key>
    <dict>
        <key>WgQuickConfigBase64</key>
        <string>BASE64_ENCODED_CONF</string>
        <key>VylosConfigBase64</key>
        <string>BASE64_ENCODED_SETTINGS_CONF</string>
    </dict>
    <key>VPN</key>
    <dict>
        <key>AuthenticationMethod</key>
        <string>Password</string>
        <key>RemoteAddress</key>
        <string>vpn.example.com</string>
        <key>ProviderBundleIdentifier</key>
        <string>io.cbnventures.vylos.packet-tunnel</string>
        <key>ProviderType</key>
        <string>packet-tunnel</string>
        <key>OnDemandEnabled</key>
        <integer>1</integer>
    </dict>
</dict>

Installing this payload creates the VPN but does not assign applications to it. Continue with Configure Per-App VPN to associate managed apps with the same VPNUUID and understand the supported routing fields.

Install and Remove Profiles

Deliver profiles through MDM for centralized ownership, replacement, and removal. A user can also install a device-wide profile directly when MDM is unavailable, then remove it later through the operating system's profile-management settings.

Vylos treats either delivery method as profile-owned and read-only. Updating or removing the profile—not editing inside Vylos—is the supported way to change the tunnel.

For the resulting app experience, see Deploy Managed Tunnels. For Apple's complete payload contract, see the VPN payload reference and AppLayerVPN payload reference.