Security Boundaries
Sandbox Policy
Macro Handler runs Lua scripts inside a sandboxed runtime. This page documents which APIs are open to scripts, which dangerous constructs are kept closed, and which Android permissions back the runtime calls — all in one place.
1. Forbidden APIs (closed)
The Lua constructs below are blocked by the sandbox. If you put them into your script or inline expressions you get a LuaError; failure is never silent.
- Blocked
loadstring / loadRuntime conversion of strings into Lua code is disabled. A shared script must remain visually auditable before it runs.
- Blocked
requireExternal module loading is blocked. The entire API surface is shipped with the app; no unexpected external code can be injected.
- Blocked
os.execute / io.popenShell or subprocess invocations are blocked. Scripts cannot run device commands; this is the core safety guarantee for shared macros.
- Blocked
debug.*The Lua debug library is fully disabled. A sandboxed script cannot reach host-side state (upvalues, getlocal, sethook).
- Blocked
setmetatable / getmetatable (post-init)Metatable manipulation is locked once the standard library initializes. Polyfills run before this shutdown; user scripts cannot install new metatables.
- Blocked
Control flow inside inline expressions ({{var}})Inline expressions in Visual Builder parameter fields support variable reads + basic math only. ; loadstring require if/while/for and similar are rejected at the block level.
2. Allowed constructs
The public API surface is fully open. The categories below are the most commonly used; see the API documentation for the full 530+ method list.
- Open
The entire public API surface20 global functions + 38 global objects + ~530 methods. Region, Asset, Snap, Touch, Request, JSON, Hud, KV, Async, System, etc.
- Open
Error catching with pcallThe pcall(function() ... end) pattern is fully supported across scripts. Unexpected LuaError values can be caught and logged.
- Open
string.* / table.* / math.*The pure (side-effect-free) parts of the standard library are open: string.format / string.sub / table.insert / math.floor and so on.
- Open
Async.defer / every / promise / awaitA sandboxed timer + promise API: MAX 128 timers + 128 promises. All active timers are auto-cancelled when the script stops.
3. Android permissions backing the runtime
Even though the Lua APIs are open inside the sandbox, several calls depend on Android-side permissions. When a permission is denied, the call returns nil/false or silently no-ops; the script does not crash.
- Permission
Display Over Other AppsThe floating overlay panel, HUD, and runtime overlays require this permission. The macro still runs without it, but on-screen controls cannot be drawn.
- Permission
Accessibility ServiceIMAGE / TEXT / COLOR scans, touch simulation, and screen reading depend on this service. If it is disabled, Region:find / quickTap / OCR calls return nil or error out.
- Permission
MediaProjection (capture only)Snap.screenRefresh() uses the MediaProjection token under the hood. The Android 14+ user prompt appears on the first capture; if revoked, the next capture re-prompts.
- Permission
Foreground Service (specialUse / mediaProjection)The macro runtime and overlay services are declared with Android 14+ Play-compliant foreground service types. The system keeps them alive alongside a visible notification.
- Permission
POST_NOTIFICATIONS (Android 13+)System.noti() / NOTIFY_TOAST request this permission at runtime. If denied, the call silently no-ops; the macro does not crash.