sandbox
js/ai/sandbox.ts
fino:ai/sandbox — capability-gated execution for model-written TypeScript.
An AISandbox runs source in a separate process Realm with a deny-all import
map. The child can import only fino:ai/sandbox/capabilities; every operation
in that synthetic module is checked and executed by the parent. Ambient
network globals are removed before user source evaluates.
Grants are explicit values, not booleans: filesystem grants name roots, network grants name origins and methods, subprocess grants name binaries, and environment/secret grants contain only the names visible to the child. Resource limits bound capability calls and transferred bytes. Subprocesses additionally use the runtime's strict process sandbox and fail closed when the host cannot enforce it.
Audit events are published on fino:ai/sandbox. They contain capability
names and targets but never environment or secret values.
import { AISandbox } from 'fino:ai/sandbox';
const code = `
import { environment, readText } from 'fino:ai/sandbox/capabilities';
export default async (path: string) => ({
mode: await environment('MODE'),
text: await readText(path),
});
`;
using sandbox = new AISandbox(code, {
environment: { MODE: 'analysis' },
filesystem: { read: ['/srv/input'] },
});
console.log(await sandbox.call('/srv/input/prompt.txt'));Interfaces
interface SandboxFilesystemGrant {
Filesystem roots visible to sandbox code.
Properties
read?: string[]
Absolute roots from which readText() may read.
write?: string[]
Absolute roots beneath which writeText() may write.
interface SandboxNetworkGrant {
HTTP requests visible to sandbox code.
Properties
origins: string[]
Exact URL origins such as https://api.example.com.
methods?: string[]
Allowed methods. Defaults to GET.
interface SandboxSubprocessGrant {
Strictly sandboxed child-process access.
Properties
commands: string[]
Exact executable paths the child may request.
environment?: Record<string, string>
Replacement environment for spawned commands. Defaults to empty.
sandbox?: ProcessSandboxOptions
Strict runtime sandbox policy. A fail-closed default is used when omitted.
timeoutMs?: number
Maximum command runtime. Defaults to 30 seconds.
interface SandboxResourceGrant {
Limits shared across one sandbox lifetime.
Properties
maxOperations?: number
Maximum parent-side capability calls. Defaults to 100.
maxReadBytes?: number
Maximum bytes returned by one file read. Defaults to 1 MiB.
maxWriteBytes?: number
Maximum bytes accepted by one file write. Defaults to 1 MiB.
maxNetworkBytes?: number
Maximum bytes returned by one HTTP response. Defaults to 1 MiB.
maxProcessOutputBytes?: number
Maximum combined stdout and stderr bytes. Defaults to 1 MiB.
wallClockMs?: number
Maximum elapsed time for one call(). Defaults to 30 seconds.
interface AISandboxOptions {
Capability grants supplied by trusted parent code.
Properties
filesystem?: SandboxFilesystemGrant
Scoped file access. Omit to deny all filesystem operations.
network?: SandboxNetworkGrant
Scoped outbound HTTP access. Omit to deny all network operations.
subprocess?: SandboxSubprocessGrant
Scoped subprocess access. Omit to deny all process creation.
environment?: Record<string, string>
Exact environment variable names and values visible to the child.
secrets?: Record<string, string>
Exact secret names and values visible to the child. Values are never audited.
resources?: SandboxResourceGrant
Operation, byte, and elapsed-time limits.
interface SandboxAuditEvent {
Event published for sandbox capability use, denial, and execution results.
Properties
capability: string
Capability such as filesystem.read, secret, or execute.
target?: string
Requested name, path, origin, or executable. Never a secret value.
outcome: 'used' | 'denied' | 'error'
Whether the operation was used, denied, or failed after authorization.
timestamp: number
Unix timestamp in milliseconds.
reason?: string
Human-readable denial or failure reason.
Classes
class SandboxDeniedError extends Error {
Structured error for a denied capability or exhausted resource grant.
Readonly Properties
readonly capability: string
Capability that rejected the request.
readonly target?: string
Requested target, when one is safe to expose.
Constructors
constructor(capability: string, message: string, target?: string)
Create a capability denial. Applications normally receive these from an AISandbox.
class AISandbox<F extends (...args: any[]) => any = (...args: any[]) => any> {
A single-use, process-isolated, parent-capability-backed TypeScript execution context. Single-use execution avoids retaining a privileged RPC channel after model-written code returns.
Call terminate() or use explicit resource management when done.
Constructors
constructor(source: string, options: AISandboxOptions = {})
Validate grants and prepare source for a deny-by-default process Realm.
Invalid grants throw during construction. Source transpilation and process
creation happen when call() starts. Capability operations fail with
SandboxDeniedError; child failures reject call().
Methods
async call(...args: Parameters<F>): Promise<Awaited<ReturnType<F>>>
Invoke the source module's default export.
The elapsed-time limit rejects and terminates the sandbox. Capability counters and byte limits apply to this single execution.
terminate(): void
Stop the process Realm. Repeated calls are harmless.