Enforce NetBird Settings on iOS

Updated

On iOS there is no file or registry for policy. Apple's channel for configuring a managed app is Managed App Configuration: your MDM sends a dictionary along with the app, and iOS hands it to that app only. The NetBird app reads it from its own preferences, so the payload must target the NetBird app's bundle id: io.netbird.app on iOS and iPadOS, io.netbird.app.tv on tvOS.

What each key does, and how the client applies and locks a policy, is on the MDM Integration page. Read its How the client applies a policy section first if you have not.

The examples use the user device baseline: a self-hosted server at https://netbird.example.com:443, read-only settings, and no extra profiles.

Push the payload

The payload is a plain property-list dictionary, with the same key names as on desktop. The user device baseline is:

<dict>
    <key>managementURL</key>
    <string>https://netbird.example.com:443</string>
    <key>disableUpdateSettings</key>
    <true/>
    <key>disableProfiles</key>
    <true/>
</dict>

Start from netbird-ios-appconfig.plist and delete the keys you do not want to pin: a key that is present is pinned, even when its value is false. Then add it to the NetBird app's assignment in your MDM:

  • Microsoft Intune: Apps → App configuration policies → Add → Managed devices, platform iOS/iPadOS, pick the NetBird app, then set Configuration settings format to Enter XML data and paste the dictionary.
  • Jamf Pro: Devices → Mobile Device Apps → NetBird → App Configuration, and paste the dictionary.
  • Kandji, Mosyle, Workspace ONE, JumpCloud: the same field exists on the managed-app assignment, usually labelled App Configuration or Application Configuration.

Booleans can be written as <true/> and <false/>, or as <integer>1</integer> and <integer>0</integer>. Integers and strings behave as on desktop.

When a policy takes effect

Every key that applies to iOS is enforced: the keys that reshape the app, and the keys the client applies to the connection itself. When a change lands depends on one detail of how iOS works.

iOS delivers the configuration to the NetBird app. The tunnel, though, runs in a Network Extension: a separate process the system starts when the tunnel comes up and stops when it goes down, and which Apple's app-configuration channel does not reach. The app therefore passes the configuration on to the extension whenever the app is running: when it becomes active, when a settings screen appears, and on a timer about every 30 seconds. When the policy has changed, the tunnel restarts on its own and the user is told their IT policy was applied.

What each key does in the app

KeyEffect in the iOS and tvOS app
managementURLHides Settings → Connection and the server step of onboarding. The profile-creation sheet shows and uses the pinned URL.
preSharedKeyThe key row reads Configured and is locked: no Save, no Remove. The value itself never reaches the app's interface.
rosenpassEnabled, rosenpassPermissiveLocks its own switch and shows the pinned value.
disableClientRoutesHides the exit-node selector. The resource list explains why, instead of listing resources.
disableAutoConnectVPN On Demand becomes read-only.
disableProfilesHides the Profiles section: no creating, switching, or removing profiles.
disableNetworksRemoves the Resources tab.
disableAdvancedViewHides Advanced (on tvOS, the whole section).
disableUpdateSettingsRead-only mode: nothing is hidden, and every configuration control is locked.

A second group of keys has no control to lock, because the client applies them straight to the connection: blockInbound, wireguardPort, lazyConnection, allowRemoteJobs, and debugBundleUploadURL (when a remote job produces a bundle). On iOS they are enforced all the same, with nothing on screen to mark: a device whose policy sets allowRemoteJobs: false, for example, refuses remote jobs. On tvOS none of them reach the tunnel, for the reason in the warning above.

The remaining keys do not apply to iOS and are ignored, so they are safe in a payload shared with desktop devices: allowServerSSH (there is no SSH server on iOS), disableServerRoutes (an iOS device does not route for other peers), disableAutostart (desktop app only), disableMetricsCollection, enableLocalMetrics and localMetricsAddress (the local endpoint is not reachable on iOS), and splitTunnelMode and splitTunnelApps.

Verifying on a device

There is no CLI on iOS. A pinned setting shows a lock and a Managed by your organization note in the app, and a gated section disappears altogether. For the user device baseline, the Profiles section is gone and every configuration control is locked.

That confirms the app received the policy. To confirm it reached the tunnel, change the policy while the tunnel is connected and bring NetBird to the foreground: the tunnel restarts and the device shows "NetBird configuration was updated by your IT policy". That notice comes from the extension, so seeing it means the tunnel applied the new policy.

Troubleshooting

Nothing is locked in the app. The app did not receive the configuration. Check that NetBird is a managed app on the device (installed by your MDM, or taken over by it), that the app-configuration policy is assigned to the same device group as the app, and that it targets the bundle id io.netbird.app (io.netbird.app.tv on tvOS).

The app shows the policy, but the tunnel still behaves as before. The app passes the policy to the tunnel only while it is running. Open NetBird and leave it in the foreground for half a minute; the tunnel restarts and reports that the policy was applied. On tvOS the tunnel does not receive the policy at all; see When a policy takes effect.

For problems that look the same on every platform, see Troubleshooting on the MDM Integration page.

Recap

  • iOS delivers the policy as Managed App Configuration to the managed NetBird app, bundle id io.netbird.app (tvOS: io.netbird.app.tv).
  • The user device baseline is the same three keys as on desktop: managementURL, disableUpdateSettings, and disableProfiles.
  • A change reaches the tunnel while the app is open, within about 30 seconds; on tvOS it reaches the app only.
  • Confirm in the app: pinned settings show Managed by your organization.