Samsung Knox multi-window restrictions via KSP: the JSON nobody documents
A customer runs dedicated Samsung tablets in COBO mode as order terminals. Requirement: the foreground app stays foreground. No split screen, no pop-up view, no dragging a second app in from the edge panel. Android’s standard management API has no policy for this — multi-window control is a Samsung-specific restriction that lives in Knox Service Plugin (KSP).
KSP’s documentation tells you the restriction exists. What it does not tell you is what the configuration actually looks like once it leaves the managed configuration UI, which matters the moment you want to version it, review it, or push it via Graph instead of clicking through Intune. This post documents that JSON.
Where the setting lives
KSP is deployed as a managed Google Play app with an app configuration policy. The multi-window switch sits under device-wide restrictions:
Device-wide policies (Device Owner) → Restrictions → Allow Multi Window Mode
Set Enable device policy controls and Enable restrictions to true, then disable multi-window. Three toggles across two nesting levels — easy in the UI once you know where to look, and completely opaque in the resulting payload.
The JSON nobody documents
Intune stores the managed configuration as a flat list of bundle keys. The relevant fragment, extracted via Graph from the androidManagedAppConfigurations payload:
{
"kind": "androidenterprise#managedConfiguration",
"managedProperty": [
{ "key": "doPoliciesSelection", "valueBool": true },
{
"key": "doRestrictionsBundle",
"valueBundle": {
"managedProperty": [
{ "key": "doRestrictions", "valueBool": true },
{ "key": "doAllowMultiWindowMode", "valueBool": false }
]
}
}
]
}
The naming convention is consistent once you see it: do prefix for Device Owner (fully managed / dedicated), po prefix for Profile Owner (work profile). The same restriction for a work profile would be poAllowMultiWindowMode — though on a work profile it only affects work apps, which is rarely what anyone wants.
Two gotchas in this structure:
doRestrictionsis a gate. SettingdoAllowMultiWindowMode: falsewithoutdoRestrictions: truein the same bundle does nothing. KSP evaluates the gate first and skips the whole bundle if it is false. This is the single most common reason “KSP isn’t applying”.- Booleans are real booleans in Graph but strings in some export paths. If you round-trip a configuration through
managedDeviceMobileAppConfigurationsexport you may get"false"as a string. KSP tolerates it; your diff tooling will not.
Deploying via Graph
For versioned deployments I keep the KSP configuration in the repo and push it with a runbook. The relevant call:
$body = Get-Content ./ksp-order-terminals.json -Raw
Invoke-MgGraphRequest -Method PATCH `
-Uri "https://graph.microsoft.com/beta/deviceAppManagement/mobileAppConfigurations/$configId" `
-Body $body -ContentType "application/json"
Assignment stays in Intune; only the payload is code. PRs diff cleanly, and when Samsung renames a key in a KSP release (it happens — check the KSP release notes, they are the only changelog that matters), the change is visible instead of buried in a portal.
Verifying on-device
KSP writes a result per policy into its own UI. On the device: open the KSP app (visible in COBO via managed home screen or adb shell am start -n com.samsung.android.knox.kpu/.ui.MainActivity) and check Policy results. You want:
Allow Multi Window Mode: Success (false)
The behavioral test: long-press the recents key, or drag from the edge panel. Both should do nothing. If multi-window still works but KSP reports success, you are almost certainly looking at a device below the required Knox version — doAllowMultiWindowMode needs Knox 3.7+, which in practice means Android 11 era Samsung firmware or newer.
The pattern generalizes
Multi-window is one key, but the lesson is the whole KSP surface: every Samsung-specific restriction — USB modes, edge panel, developer options hard-block, firmware update windows via E-FOTA — follows this same do/po bundle structure, gated by the same doRestrictions-style booleans. Extract your working configuration once via Graph, keep it in the repo, and stop treating the Intune UI as the source of truth. The UI is an editor; the JSON is the policy.