Tuoni Script Engine
The Tuoni Script Engine runs Python automation inside the Tuoni Server process using GraalPy Community. It is enabled by default in Tuoni 0.15.0.
Scripts can:
- create dynamic command aliases
- query agents and update their status or metadata
- react to audit events
- send commands and process their results
- manage discovery data, files, listeners, and payloads
The Python standard library is available. Pure-Python packages can be installed in the configured virtual environment; native C extensions are not supported.
Module migration in 0.15.0
New scripts must use the public tuoni_script_engine module:
The former tuoni module remains available for existing scripts in 0.15.0 but
is deprecated. Migrate both the import and the API calls; the new module uses
typed enums, explicit configuration objects, read-only properties with update
methods, and revised command and event interfaces.
Install
tuoni-script-engine-stubs
in a development environment for API documentation, type checking, and editor
completion. The package is not required by scripts running in Tuoni.
Getting started
Place a .py file in the scripts directory, which defaults to
/srv/tuoni/data/scripts. No Settings toggle or API request is required.
Tuoni detects and executes new and modified files automatically.
Script output and errors are written to
${tuoni.scripting.logs-dir}/<script-name>.log, which defaults to
/srv/tuoni/data/script_logs/<script-name>.log.
File changes
File changes are debounced for three seconds by default. Changing a running script stops its current execution and starts it again after the debounce interval.
Configuration
Set Script Engine properties in tuoni.yml or with the corresponding server
command-line options.
| Property | Default | Description |
|---|---|---|
tuoni.scripting.scripts-dir |
${tuoni.data-dir}/scripts |
Directory watched for .py scripts |
tuoni.scripting.logs-dir |
${tuoni.data-dir}/script_logs |
Directory for script output and errors |
tuoni.scripting.file-change-debounce-time |
3s |
Delay before a changed script is restarted |
Permissions and sandboxing
Each script runs in an isolated GraalVM context. Configure its filesystem,
network, and environment access under tuoni.scripting.permissions:
Filesystem access
| Mode | Value | Read access | Write access |
|---|---|---|---|
| Sandbox | "sandbox" |
Scripts directory, Tuoni files directory, GraalPy home, and virtual environment | /tmp/tuoni-script-<name> only |
| Read-only | "read-only" |
Sandbox paths and the real filesystem | /tmp/tuoni-script-<name> only |
| Read-write | "read-write" |
Full filesystem; scripts and Tuoni files remain read-only | Full filesystem |
| Property | Default | Description |
|---|---|---|
allow-net-access |
false |
Permit outbound network connections |
allow-env-access |
false |
Permit reads from environment variables |
Trusted scripts only
Combining fs-access: "read-write" with allow-net-access: true
effectively removes the sandbox. Such a script has the same access as the
Tuoni Server process.
Script lifecycle
- Tuoni detects a new or modified
.pyfile. - It creates an isolated GraalPy context and makes
tuoni_script_engineavailable. - The script runs from top to bottom.
- A script with active event subscriptions stays alive.
- The script stops after normal completion with no active subscriptions, when every subscription is stopped, when the file is deleted, or when the server shuts down.
Minimal dynamic alias
This alias runs whoami on Windows shellcode agents:
After the file is saved, script-whoami appears in the Tuoni UI for compatible
agents.