For administrators
Deploying NeatKiosk with MDM
Every Managed App Configuration key, copy-paste XML for Jamf Pro, and how to make the lock survive a reboot. All of it free — NeatKiosk has no paid tier.
Bundle ID
com.trincom.NeatKiosk
App Store ID
6785420745
Requires
iOS / iPadOS 17 or later
Quick start
Jamf Pro in five steps
The same App Configuration XML works in Intune, Mosyle, Kandji, Miradore, or any MDM that supports Apple's Managed App Configuration — only the menu names differ.
Add the app
In Jamf Pro, go to Devices → Mobile Device Apps → New → App Store app and search for NeatKiosk. Distribute it with a VPP/Apps & Books device assignment so it installs without an Apple Account on the iPad.
Scope it
Under Scope, target your kiosk device group. Set Distribution Method to Install Automatically.
Paste the App Configuration
Open the app's App Configuration tab (Jamf Pro 10.x: Apps & Books → App Configuration → Preferences) and paste the XML below. Change homeURL to your site — that key is the only required one.
Lock the device
Add a Restrictions or Single App Mode payload naming com.trincom.NeatKiosk, or list it under AutonomousSingleAppModePermittedAppIDs so the app can lock itself. Details below.
Deploy and verify
On first launch the kiosk starts on your URL with no setup wizard and no prompts. Confirm the idle reset and URL rules behave as expected before scaling to the full fleet.
Reference
Managed App Configuration keys
NeatKiosk reads these keys from com.apple.configuration.managed. Only homeURL is required; every other key falls back to the default shown.
| Key | Type | Default | What it does |
|---|---|---|---|
homeURL | String | required | The page the kiosk opens and returns to. Must be http or https with a valid host — anything else is rejected and the app falls back to the on-device setup wizard. |
allowlist | Array of Strings | empty | Extra hosts visitors may reach. The home host and its subdomains are always allowed, so an empty list means "this site only". See pattern syntax. |
denylist | Array of Strings | empty | Hosts or paths to block. Deny always wins over allow, including over the home host. |
idleTimeoutMinutes | Integer | 2 | Minutes of no interaction before the kiosk returns home and clears cookies, cache, local storage and history. Use 0 to never reset. Omitting the key gives you 2 minutes, not "off". |
blockExternalSchemes | Boolean | true | Blocks tel:, mailto:, sms:, App Store and other app-opening links, so a visitor can't escape into Mail or Phone. |
disableZoom | Boolean | true | Disables pinch-to-zoom, so a visitor can't leave the layout zoomed for the next person. |
navChromeEnabled | Boolean | false | Shows a back / forward / home / reload bar. Leave off for a clean single-page kiosk; turn on for multi-page sites. |
statusBarVisible | Boolean | true | Shows the iOS status bar (time, battery, Wi-Fi). |
statusBarLight | Boolean | true | Status-bar text colour: true = white for dark sites, false = black for light sites. |
forceBrightness | Boolean | true | Holds the display at full brightness while the kiosk is awake. |
displayScheduleEnabled | Boolean | false | Enables the nightly blackout schedule below. |
displayOffMinutes | Integer | 1320 (22:00) | Blackout starts, in minutes after local midnight. |
displayOnMinutes | Integer | 480 (08:00) | Blackout ends, in minutes after local midnight. The window may wrap past midnight. |
Blackout is a black overlay plus zero brightness, not a real power-off — iOS gives apps no way to switch the panel off. A tap wakes the screen until the idle timer expires again.
Copy & paste
App Configuration XML
Minimal — one site, defaults for everything else
<dict>
<key>homeURL</key>
<string>https://kiosk.example.edu</string>
</dict>Full — every key set explicitly
<dict>
<key>homeURL</key>
<string>https://catalog.example.edu</string>
<key>allowlist</key>
<array>
<string>*.example.edu</string>
<string>search.worldcat.org</string>
<string>cdn.example.net/assets</string>
</array>
<key>denylist</key>
<array>
<string>admin.example.edu</string>
<string>catalog.example.edu/account/settings</string>
</array>
<key>idleTimeoutMinutes</key>
<integer>5</integer>
<key>blockExternalSchemes</key>
<true/>
<key>disableZoom</key>
<true/>
<key>navChromeEnabled</key>
<true/>
<key>statusBarVisible</key>
<true/>
<key>statusBarLight</key>
<false/>
<key>forceBrightness</key>
<true/>
<key>displayScheduleEnabled</key>
<true/>
<key>displayOffMinutes</key>
<integer>1320</integer>
<key>displayOnMinutes</key>
<integer>480</integer>
</dict>Jamf Pro expects the <dict> element shown here. If your MDM asks for a complete property list, wrap it in the usual <?xml … ?> and <plist version="1.0"> header.
Syntax
Allow / deny patterns
example.edu— that exact host, nothing else.www.example.eduwould not match.*.example.edu— the domain and every subdomain, includingexample.eduitself.example.edu/library— host plus a path prefix, matched on whole segments:/libraryand/library/hoursmatch,/librariansdoes not.- Entries are one host per array element. Don't put several hosts in one string.
- Matching is on the host only — no public-suffix logic, so
*.co.ukis not special-cased. Be specific. - Deny wins. A host on both lists is blocked, and a denylist entry can carve a path out of your own site.
- The home host and its subdomains are always allowed; the allowlist is for hosts beyond that (SSO providers, a CDN, a payment page).
Blocked navigations are cancelled silently — the visitor simply stays on the current page.
Device lock
Single App Mode & ASAM
Managed App Configuration sets up the kiosk. Locking the iPad to it is a separate MDM payload — and it's what makes the lock survive a reboot.
Single App Mode
Requires a supervised device. The iPad launches NeatKiosk and stays in it across reboots and battery drain. Nothing but an MDM command releases it. This is the right choice for unattended public iPads.
Autonomous Single App Mode (ASAM)
Also requires supervision. List the bundle ID as permitted and NeatKiosk locks itself on launch — useful when staff need to release the iPad for other use without an MDM round trip. NeatKiosk attempts ASAM by default. On an unsupervised device the attempt is ignored and the app runs normally.
<key>AutonomousSingleAppModePermittedAppIDs</key>
<array>
<string>com.trincom.NeatKiosk</string>
</array>No MDM? Guided Access locks a single iPad without supervision, but it does not survive a reboot or a flat battery.
Before you scale
Known limits
Worth reading before you push to fifty iPads rather than after.
Configuration is applied on first launch only
NeatKiosk reads your Managed App Configuration when it starts with no saved configuration on the device — a fresh install, or after a reset. Re-pushing a changed configuration to an iPad that is already running does nothing. To roll out a new URL or new settings, reinstall the app from your MDM, or open Settings on the device (hold the top-left corner ~3 seconds, enter the PIN) and choose Reset kiosk. We're looking at making re-pushed configurations apply live; tell us if that matters for your deployment.
The Settings PIN cannot be pushed
The PIN is stored only as a salted SHA-256 hash, never in plain text, so there is nothing sensible to send over the wire. Set it on the device during setup. On an MDM-managed fleet you can leave it unset and rely on Single App Mode instead — the hidden gesture then opens Settings directly.
Some settings are on-device only
Keep-awake, the idle warning countdown, which data categories the idle reset clears, and the ASAM toggle are not exposed as Managed App Configuration keys. They use sensible defaults: screen stays awake, a 20-second warning before reset, all web data cleared, ASAM attempted.
Blackout is not a real screen-off
iOS gives apps no way to power the panel down. The nightly schedule draws a black overlay and drops brightness to zero. It saves meaningful power on OLED iPads and stops the room glowing, but the display is technically still on.
Mixed http/https sites
NeatKiosk allows cleartext http, because plenty of intranet appliances and sign-in portals still redirect through an http hop. If your kiosk site is https-only, nothing changes.
Day two
Getting back into Settings
There is no visible exit button — that's the point. As the administrator:
- If Guided Access is running, triple-click the top button and enter its passcode first.
- Press and hold the top-left corner of the screen for about 3 seconds.
- Enter the Settings PIN, then choose Change settings or Reset kiosk.
The Settings PIN is separate from the Guided Access passcode. Record both — a lost Guided Access passcode means erasing the iPad.
Deploying a fleet? Ask us.
Send us your App Configuration and we'll check it before you scope it to the whole group. Real people, usually same day.
Email support@wakesys.comNo accounts, no sales calls, no upsell — NeatKiosk is free and stays free.