Workspace Node.js Security
Understand how Ansight discovers and executes trusted workspace TypeScript, which process controls it applies, and which operating-system capabilities remain available.
CLI v0.23.1
Ansight uses Node.js to execute workspace-owned TypeScript for repository tasks, event triggers, and custom session sanitizers.
Security notice Workspace TypeScript is trusted local code
Ansight process controls are not an operating-system sandbox. A module and anything it imports run with the filesystem, process, and network permissions of the user running Studio or the CLI. Review code before running a task, connecting triggers, or selecting a custom sanitizer.
The execution model
Ansight separates discovery from execution where the module contract permits it:
- Task and trigger discovery does not run Node.js. The host reads the
module as text and extracts the JSON-compatible
export const task = { ... }orexport const trigger = { ... }descriptor. - Execution starts Node.js directly. Ansight does not use a shell. It launches the configured Node executable with an argument list and a small Ansight bootstrap module.
- TypeScript uses Node’s type stripping.
.tsmodules run with--experimental-strip-types; Ansight does not bundle the module or transform it into a restricted language. - The module is imported as an ES module. Top-level code and imported dependencies execute during this import, before the default task, trigger, or sanitizer function is called.
- Ansight and Node exchange structured JSON over redirected stdin/stdout. The host validates protocol messages and dispatches permitted tool calls.
console.log, console.info, and console.debug are redirected to stderr so
ordinary diagnostics cannot corrupt the stdout protocol. Module code should
not write directly to process.stdout.
Process lifetime by module type
| Module | Node process lifetime | Starts when |
|---|---|---|
| Task | Fresh process for each task run | A person, agent, test runner, Studio, or CLI invokes the task. |
| Trigger | Fresh process for each attempt, including retries | A connected trigger matches an App ID, event kind, and every condition. |
| Sanitizer | One process for the selected sanitization operation; item handlers are invoked serially over the same protocol | An export or share explicitly selects the custom sanitizer. |
Timed-out or cancelled work causes Ansight to terminate the Node process tree. A process ending does not undo filesystem writes, network calls, or child-system effects that already completed.
Reduced environment
Before launching Node, Ansight clears the inherited process environment and adds only the values needed to locate tools and temporary storage:
- inherited
PATHwhen present; TMPDIR,TEMP, andTMP, all pointing at the selected temporary directory;SystemRooton Windows when present;NO_COLOR=1; and- one execution marker:
ANSIGHT_TASK=1,ANSIGHT_AUTOMATION=1, orANSIGHT_SANITIZER=1.
Arbitrary parent variables—including API keys and application secrets—are not copied into the child environment. Test-secret values resolved from secure storage or an explicitly declared environment-variable alias, along with the locally stored model credential, are not injected into repository Node processes.
This is secret minimization, not isolation. The module still runs as the same
OS user. It can discover information through Node and operating-system APIs,
read accessible files by path, open network connections, and start programs it
can locate. Inheriting PATH also means executable resolution follows the
host’s current path configuration.
Ansight capability boundaries
The JavaScript bridge restricts what module code can ask Ansight itself to do:
- Task host APIs are pinned to the selected
sessionId; caller-supplied target overrides are removed. - Standard task host methods are allow-listed by the generated API contract.
- Extra
ansight.callToolnames must be declared intask.hostToolsand must exist in the active task registry. - App methods remain pinned to the selected live session and are validated against the app’s published tool catalog, argument schema, grants, and tool guard.
- A trigger can return no action or one app-tool action. It cannot call Studio host tools or dispatch a sequence of app actions inside its function.
- A sanitizer receives the current serialized evidence item and bounded helper
data through the protocol; returned content must be an object or
null.
These rules constrain calls through Ansight. They do not prevent direct Node filesystem, process, package, or network access.
Runtime bounds
| Control | Tasks | Triggers | Custom sanitizers |
|---|---|---|---|
| Module size | 1 MiB | 1 MiB | TypeScript module required; export processing remains bounded by archive controls |
| Module-load handshake | 5 seconds | 5 seconds | 5 seconds |
| Function time | 1–300 seconds; default 120 | 10–1,000 ms; default 100 ms | 20 seconds per item handler |
| Separate app-action time | Included in task timeout | 1–300 seconds; default 30 | Not applicable |
| Ansight/app actions | 1–100; default 64 | At most one returned action per attempt | Helper-only sanitizer protocol |
| Retries | Caller-controlled new run | 1–5 host-owned attempts | No automatic handler retry |
| Captured stderr | 65,536 characters | 65,536 characters | 65,536 characters |
| Structured output | Task output and each tool result are bounded | 1,048,576 characters | 4 MiB response bound |
Trigger admission also uses a bounded host queue and configured concurrency. Limits protect host availability and audit size; they do not make malicious code safe.
Trust gates
| Module | Required trust decision |
|---|---|
| Task | The repository task must be explicitly invoked. Workspace tasks may be exposed to a test agent unless the run uses --no-workspace-tools. |
| Trigger | The repository catalog must be explicitly connected. CLI hosts must also enable repository automation. |
| Sanitizer | The custom module must be explicitly selected for sanitization, export, or sharing. |
Treat changes from forks, pull requests, generated patches, downloaded archives, and dependency updates as untrusted until reviewed. A harmless static descriptor does not prove that the default function, top-level module code, or an imported package is harmless.
Recommended controls
- Review the complete module and its local imports before enabling it.
- Pin and review dependencies; avoid install hooks and unnecessary packages.
- Keep workspace modules small and prefer the typed Ansight/app APIs over shell commands or direct network access.
- Run Studio or the CLI as a non-administrator user with least-privilege filesystem access.
- Use a dedicated development account, machine, VM, or OS sandbox when the repository is not fully trusted.
- Keep secrets outside the repository and do not load them manually from the user’s home directory inside workspace code.
- Inspect task and trigger run history, tool-call audits, and captured stderr after execution.
- Disconnect trigger catalogs when automatic reactions are no longer needed.
- Prefer the built-in sanitizer for untrusted repositories; custom sanitizer code sees sensitive evidence before it returns the redacted copy.
Node selection and diagnosis
Ansight resolves node from the configured executable path and normal platform
locations. The CLI can select an explicit runtime:
ansight host run --node-path /absolute/path/to/node
ansight doctor --json
Use a trusted, maintained Node installation. An executable selected through a
modified PATH or explicit --node-path runs with the same authority as the
Ansight host.