NevoFlux
Canvas

Tool Whitelist

Define exactly which external commands and internal APIs Canvas and the agent may run.

The tool whitelist is how you safely extend what Canvas apps (and the agent) can run. Each tool is a TOML file that declares a command (or internal API), its parameters, and strict constraints. Nothing runs through a shell, and every parameter is validated.

Where tools live, and precedence

User tools are TOML files in ~/.config/nevoflux/canvas-tools/ (manage them in Settings → Canvas Tools). The registry has three layers, in increasing priority:

Builtin → User → Session

A user tool overrides a builtin of the same name; a session tool overrides both. Only enabled tools can be invoked. The list hot-reloads, so a newly added file is picked up without restarting.

TOML schema

KeyMeaning
nameTool name (how it's invoked), e.g. "ffmpeg.trim"
descriptionWhat it does
kind"command" (runs a binary) or "internal" (calls a built-in API)
binaryThe executable, for kind = "command"
apiThe internal API name, for kind = "internal"
args_mode"template" (fixed arg template) or "free" (subcommand allowlist)
argsArg template; use {{param}} placeholders
allowed_subcommandsFor free mode: the only sub-commands permitted
[params.<name>]A parameter spec (see below)
[constraints]Execution limits
enabledWhether the tool is active (default true)

Parameter types ([params.<name>] type = ...)

path (with allowed_prefix), duration, int (min/max), float (min/max), bool, enum (values), text (with a pattern regex), and identifier. Each param may also set optional and default.

Constraints

timeout_seconds (default 60), cwd, max_stdout_bytes and max_stderr_bytes (default 1 MiB each). The token $SESSION_DIR is expanded at runtime to the current session's working directory.

Example: a templated command

name = "ffmpeg.trim"
description = "Trim a video/audio file to a time range"
kind = "command"
binary = "ffmpeg"
args_mode = "template"
args = ["-y", "-i", "{{input}}", "-ss", "{{start}}", "-to", "{{end}}", "-c", "copy", "{{output}}"]

[params.input]
type = "path"
allowed_prefix = "$SESSION_DIR"

[params.start]
type = "text"
pattern = "^[0-9]+([.][0-9]+)?$"

[params.end]
type = "text"
pattern = "^[0-9]+([.][0-9]+)?$"

[params.output]
type = "path"
allowed_prefix = "$SESSION_DIR"

[constraints]
timeout_seconds = 120
cwd = "$SESSION_DIR"
max_stderr_bytes = 65536

Example: a free-mode allowlist

Allow only a few safe sub-commands of a binary:

name = "git"
kind = "command"
binary = "git"
args_mode = "free"
allowed_subcommands = ["status", "log", "diff", "branch", "show", "rev-parse"]

Safety model

  • No shell — binaries are spawned directly; there is no shell interpolation.
  • Validated params — paths are confined to allowed_prefix (no traversal), text must match its pattern, enums/numbers are range-checked.
  • Limits — per-tool timeout and output caps.
  • Audit — every invocation is recorded locally.

From an app, run a tool with NevofluxSDK.tool.invoke(name, params). The agent runs them through the same whitelist.

On this page