Skip to content
Version v0.35 ยท supported
[WIP] Pending copyedit and approval.

Grants and the sandbox

A profile's Lua scripts run in a sandbox: they can do the things a voice command needs, and nothing more. A grant is a capability you add in your own engine.toml to let one profile reach past that boundary. This page describes what the sandbox allows by default and what each grant opens up.

The sandbox by default

When a profile's script runs, it has the full amri.* API for input, speech, sound, variables, profile and category control, sandboxed file reads, and the ordinary parts of Lua. The risky parts of the Lua standard library are removed, so a downloaded profile cannot run arbitrary programs or read arbitrary files.

What a sandboxed script keeps:

Available Notes
string.*, math.*, table.* The full libraries.
os.date, os.time Current date and time only.
tonumber, tostring, type, pairs, ipairs, pcall, xpcall Basic globals.
amri.* Input, speech, sound, variables, profiles, tasks, sandboxed file reads.
amri.file.read, amri.file.exists A relative path always resolves inside the profile folder, with no grant.

What is removed, regardless of grants:

os.execute   os.exit    os.getenv   os.remove   os.rename   os.tmpname
io.*         load       loadfile    dofile      require     package
debug        collectgarbage

Because these functions are never installed in the sandboxed state, the sandbox is enforced by construction. There is no per-call permission check to turn off, and no way for a script to reach a removed function.

Grants widen it

A capability that reaches past the sandbox is gated behind a grant. Each grant is a boolean you set per profile. Without the grant, run, shell, and kill are not available to a script at all, and a profile that calls them without the grant is refused at load. The file and input grants are quieter: an absolute-path file read returns nothing, and an escape-class key is dropped, when the grant is not held.

The per-profile grants, and the functions each one unlocks:

Grant What it allows Unlocks
run Run a program directly, no shell amri.sys.run, amri.sys.exec_async
shell Run a shell command string amri.sys.shell
kill Send a signal to a process amri.sys.kill
file_absolute Read files by absolute path, outside the profile folder amri.file.read, amri.file.exists with an absolute path
unrestricted_input Emit escape-class keys held back by default: bare Super, Alt+Tab, Ctrl+Alt+Delete, Ctrl+Alt+Backspace, Ctrl+Alt+Fn, and control characters in amri.input.text amri.input.*

Two more capabilities are user opt-ins that live in engine.toml, but are not per-profile grant flags:

  • read_keyboard lets Amri read the keyboard and mouse globally, which backs amri.sys.key_pressed and amri.sys.mouse_button. It is one switch under [input], not a per-profile setting, so an imported profile cannot turn on keyboard reading by itself.
  • permit_system_overrides_for lets a named profile replace a built-in amri command. It lives under [security]. See System overrides.

Where grants live

Grants live only in engine.toml, the file you control. They are never read from a profile. A profile can request a capability, but only you grant it by editing this file. This is the same consent location that holds your profile trust decisions and the system-override allowlist.

Per-profile grants go under [grants."<profile>"], keyed on the profile name:

# engine.toml, the file you control.

# Grant one profile the ability to launch a program and read an absolute path.
[grants."elite_dangerous"]
run = true
file_absolute = true

# Read the keyboard and mouse globally (a single switch, all profiles).
[input]
read_keyboard = true

# A global kill-switch: force a capability off for EVERY profile, overriding
# any per-profile grant above. Any flag set here wins.
[deny]
shell = true

# Let a named profile override a built-in `amri` command.
[security]
permit_system_overrides_for = ["my_personal_overlay"]

Grants and deny are top-level tables

[grants."<profile>"] and [deny] are their own top-level tables, not entries under [security]. Only permit_system_overrides_for lives under [security], and read_keyboard lives under [input].

Deny overrides grant

A flag set under [deny] forces that capability off for every profile, whatever a [grants."<profile>"] table says. Use it to switch a whole capability off across the machine without editing each profile's grants.