Get started
Login
© 2024

Deploy Tailscale on iOS/tvOS using MDM

This page contains technical information which you might find useful if you are a system administrator deploying Tailscale for iPhone, iPad, Vision Pro, or Apple TV in a corporate environment using MDM solutions such as Microsoft Intune, Jamf Pro, Kandji, or SimpleMDM.

We are always working on providing more options for system administrators to programmatically manage their Tailscale deployments. If you are deploying Tailscale on the devices listed above and feel the need for a specific configuration option that is currently missing on this page, contact our support team.

If you're looking to configure system policies in the Tailscale client for macOS, refer to the dedicated topic.

Configuration profiles

If you are deploying Tailscale for iOS/tvOS using MDM, you can use configuration profiles to automate parts of the onboarding process for the app, reducing prompt fatigue for the user. You can also use configuration profiles to enforce specific system policies.

Deploying system policies in a configuration profile

Configuration profiles can be used to specify user defaults for Tailscale. The Tailscale client will read its user defaults every time it launches, and apply any system policies it finds in the user defaults. Deploying a configuration profile containing user defaults via your MDM solution can let you configure specific settings of the Tailscale client on behalf of the user, providing an easier setup process.

Refer to our full list of system policies to discover all settings you can configure.

This is an example of a configuration profile to set the ManagedByOrganizationName system policy value:

<?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>Tailscale: System Policy Configuration Profile</string>
        <key>PayloadType</key>
        <string>Configuration</string>
        <key>PayloadVersion</key>
        <integer>1</integer>
        <key>PayloadIdentifier</key>
        <string>io.tailscale.ipn.ios.mdm.797d4461-837c-4f5a-b18e-7e300b057018</string>
        <key>PayloadUUID</key>
        <string>0f451881-7ac4-4171-80ed-b55251053232</string>
        <key>PayloadContent</key>
        <array>
            <dict>
                <key>PayloadDisplayName</key>
                <string>System Policies</string>
                <key>PayloadType</key>
                <string>io.tailscale.ipn.ios</string>
                <key>PayloadVersion</key>
                <integer>1</integer>
                <key>PayloadIdentifier</key>
                <string>io.tailscale.ipn.ios.f4806335-6703-4680-8f41-f40e6f281c72</string>
                <key>PayloadUUID</key>
                <string>3e44f9b0-d309-48d3-b055-6dc683d438c9</string>
                <key>ManagedByOrganizationName</key>
                <string>Tailscale, Inc.</string>
            </dict>
        </array>
    </dict>
</plist>

Installing the configuration profile above will display Managed by Tailscale, Inc. in the Settings view of the iOS app.

Note that the ManagedByOrganizationName system policy is not currently available on Apple TV, and won't result in any user-facing change.

Refer to the list of system policies for other values you can configure on behalf of the user.

Allow push notifications automatically

The Tailscale app for tvOS does not use notifications as third-party apps are not allowed to deliver notifications on Apple TV.

Unlike the other configuration profiles on this page, notification settings can only be deployed to supervised iOS devices.

Tailscale for iOS may sometimes use system notifications to inform the user. For instance, you will receive a notification when:

  • the device key is about to expire
  • a file was received using Taildrop

This is an example of a configuration profile payload to automatically allow notifications for Tailscale on iOS.

<dict>
  <key>NotificationSettings</key>
  <array>
    <dict>
      <key>AlertType</key>
      <integer>1</integer>
      <key>BadgesEnabled</key>
      <true/>
      <key>BundleIdentifier</key>
      <string>io.tailscale.ipn.ios</string>
      <key>CriticalAlertEnabled</key>
      <true/>
      <key>NotificationsEnabled</key>
      <true/>
      <key>ShowInNotificationCenter</key>
      <true/>
    </dict>
  </array>
  <key>PayloadDisplayName</key>
  <string>Allow Tailscale Notifications</string>
  <key>PayloadIdentifier</key>
  <string>b3dc3535-1b06-4f2d-a684-4518a6589dfe</string>
  <key>PayloadOrganization</key>
  <string>Tailscale Inc.</string>
  <key>PayloadType</key>
  <string>com.apple.notificationsettings</string>
  <key>PayloadUUID</key>
  <string>056ec734-91b7-45a3-8787-98ebf2e84025</string>
  <key>PayloadVersion</key>
  <integer>1</integer>
</dict>

Install the Tailscale VPN configuration

On the first time it launches on an iOS/tvOS device, the Tailscale app will install a NetworkExtension VPN configuration. You can choose to skip this step by providing a configuration profile which will configure the VPN configuration before the app launches. During the first launch, the Tailscale app will detect the pre-existing configuration and skip the installation step.

The following is a valid .mobileconfig plist file to set up such a VPN configuration.

When creating a configuration profile for Tailscale for tvOS, replace the value io.tailscale.ipn.ios.network-extension with io.tailscale.ipn.ios.network-extension-tvos in the ProviderBundleIdentifier field. Leave the VPNSubType field untouched (our tvOS app uses the same bundle identifier as the iOS app).

<?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>Tailscale iOS VPN Configuration Profile</string>
  <key>PayloadType</key>
  <string>Configuration</string>
  <key>PayloadVersion</key>
  <integer>1</integer>
  <key>PayloadIdentifier</key>
  <string>com.your-company-name.tailscale.797d4461-837c-4f5a-b18e-7e300a057020</string>
  <key>PayloadUUID</key>
  <string>0f451881-7ac4-4171-80fd-b55251053233</string>
  <key>PayloadContent</key>
  <array>
        <dict>
        <key>PayloadDisplayName</key>
        <string>Tailscale VPN Configuration</string>
        <key>PayloadType</key>
        <string>com.apple.vpn.managed</string>
        <key>PayloadVersion</key>
        <integer>1</integer>
        <key>PayloadIdentifier</key>
        <string>com.your-company-name.tailscale-tunnel</string>
        <key>PayloadUUID</key>
        <string>7ec957e2-b165-4d1f-9946-3a7a16ae0f9c</string>
        <key>UserDefinedName</key>
        <string>Tailscale MobileConfig</string>
        <key>VPNType</key>
        <string>VPN</string>
        <key>VPNSubType</key>
        <string>io.tailscale.ipn.ios</string>
        <key>VPN</key>
         <dict>
            <key>RemoteAddress</key>
            <string>Tailscale Mesh</string>
            <key>AuthenticationMethod</key>
            <string>Password</string>
            <key>ProviderBundleIdentifier</key>
            <string>io.tailscale.ipn.ios.network-extension</string>
        </dict>
    </dict>
  </array>
</dict>
</plist>