AI Agent Sandboxing

Learn how to use Noid for safe, isolated execution of AI-generated code.

Overview

AI agents often need to execute arbitrary code in response to user requests. Noid provides fast, secure sandboxes for this use case with:

  • Instant isolation: New VM in seconds
  • State management: Checkpoint/restore for consistency
  • Resource limits: Prevent runaway processes
  • Quick cleanup: Fast VM destruction

Use Case: Code Interpreter

Execute user-provided Python code safely:

import { NoidClient } from '@noid/sdk';

const noid = new NoidClient({
  serverUrl: process.env.NOID_SERVER!,
  token: process.env.NOID_TOKEN!,
});

async function executeCodeSafely(code: string) {
  const vmName = `sandbox-${Date.now()}`;

  try {
    // Create isolated sandbox
    await noid.createVM({
      name: vmName,
      vcpus: 2,
      memory: 1024, // 1GB limit
    });

    // Install Python environment (or use golden snapshot)
    await noid.exec(vmName, 'apt-get update && apt-get install -y python3');

    // Execute user code with timeout
    const result = await noid.exec(
      vmName,
      `timeout 30s python3 -c "${code.replace(/"/g, '\\"')}"`,
      { timeout: 35000 }
    );

    return {
      success: result.exitCode === 0,
      output: result.stdout,
      error: result.stderr,
    };
  } finally {
    // Always cleanup
    await noid.destroyVM(vmName).catch(console.error);
  }
}

// Example usage
const result = await executeCodeSafely(`
print("Hello from sandbox!")
import os
print(f"Running as: {os.getuid()}")
`);

console.log(result.output);

Golden Snapshot Pattern

Pre-configure VMs with common dependencies:

async function createPythonGolden() {
  const baseVM = 'python-base';

  // Create base VM
  await noid.createVM({ name: baseVM });

  // Install Python environment
  await noid.exec(baseVM, 'apt-get update -y');
  await noid.exec(baseVM, 'apt-get install -y python3 python3-pip');
  await noid.exec(baseVM, 'pip3 install numpy pandas matplotlib');

  // Create golden checkpoint
  await noid.createCheckpoint(baseVM, 'golden', {
    label: 'Python 3 with data science libraries',
  });

  console.log('✓ Golden snapshot ready');
}

// Fast sandbox from golden snapshot
async function executeWithGolden(code: string) {
  const vmName = `sandbox-${Date.now()}`;

  // Restore from golden (< 5 seconds)
  await noid.restore('python-base', 'golden', { as: vmName });

  // Execute immediately
  const result = await noid.exec(vmName, `python3 -c "${code}"`);

  await noid.destroyVM(vmName);
  return result;
}

Multi-Agent Collaboration

Run multiple agents in parallel:

async function runAgentTeam(tasks: string[]) {
  const agents = tasks.map((task, idx) => ({
    name: `agent-${idx}`,
    task,
  }));

  // Create VMs in parallel
  await Promise.all(
    agents.map(agent =>
      noid.restore('python-base', 'golden', { as: agent.name })
    )
  );

  // Execute tasks in parallel
  const results = await Promise.all(
    agents.map(agent =>
      noid.exec(agent.name, `python3 -c "${agent.task}"`)
    )
  );

  // Cleanup
  await Promise.all(
    agents.map(agent => noid.destroyVM(agent.name))
  );

  return results;
}

// Example: parallel data processing
const results = await runAgentTeam([
  'import pandas as pd; df = pd.read_csv("data1.csv"); print(df.mean())',
  'import pandas as pd; df = pd.read_csv("data2.csv"); print(df.mean())',
  'import pandas as pd; df = pd.read_csv("data3.csv"); print(df.mean())',
]);

Tool Execution Sandbox

Safely execute agent tools:

interface Tool {
  name: string;
  description: string;
  execute: (args: any) => Promise<any>;
}

class SafeToolExecutor {
  private noid: NoidClient;
  private vmPool: string[] = [];

  constructor(noid: NoidClient, poolSize: number = 5) {
    this.noid = noid;
    this.initializePool(poolSize);
  }

  private async initializePool(size: number) {
    // Pre-create VM pool
    for (let i = 0; i < size; i++) {
      const vmName = `tool-vm-${i}`;
      await this.noid.restore('python-base', 'golden', { as: vmName });
      this.vmPool.push(vmName);
    }
  }

  async executeTool(tool: Tool, args: any): Promise<any> {
    const vm = this.vmPool.pop();
    if (!vm) throw new Error('No VMs available');

    try {
      // Execute tool in sandbox
      const code = `
import json
args = json.loads('${JSON.stringify(args)}')
result = ${tool.name}(args)
print(json.dumps(result))
      `;

      const result = await this.noid.exec(vm, `python3 -c "${code}"`);

      // Reset VM to clean state
      await this.noid.restore('python-base', 'golden');

      return JSON.parse(result.stdout);
    } finally {
      this.vmPool.push(vm);
    }
  }
}

// Usage
const executor = new SafeToolExecutor(noid);

const result = await executor.executeTool(
  {
    name: 'web_scraper',
    description: 'Scrape web content',
    execute: async (args) => {
      // Tool implementation
    },
  },
  { url: 'https://example.com' }
);

Resource Limits

Prevent resource exhaustion:

async function executeWithLimits(code: string) {
  const vmName = `sandbox-${Date.now()}`;

  await noid.createVM({
    name: vmName,
    vcpus: 1, // Single CPU
    memory: 512, // 512MB max
  });

  // Set additional limits inside VM
  await noid.exec(vmName, `
ulimit -t 30        # 30 seconds CPU time
ulimit -v 524288    # 512MB virtual memory
ulimit -f 10240     # 10MB file size
  `);

  try {
    const result = await noid.exec(
      vmName,
      `python3 -c "${code}"`,
      { timeout: 35000 }
    );
    return result;
  } finally {
    await noid.destroyVM(vmName);
  }
}

Security Best Practices

1. Network Isolation

// Create VM without network access
await noid.createVM({
  name: vmName,
  network: 'isolated',
});

// Or disable network inside VM
await noid.exec(vmName, 'iptables -P OUTPUT DROP');

2. Input Sanitization

function sanitizeCode(code: string): string {
  // Remove dangerous imports
  const dangerous = ['os.system', 'subprocess', 'eval', 'exec'];
  for (const keyword of dangerous) {
    if (code.includes(keyword)) {
      throw new Error(`Dangerous operation: ${keyword}`);
    }
  }
  return code;
}

3. Output Filtering

function filterOutput(output: string): string {
  // Remove sensitive information
  return output
    .replace(/\b(?:\d{1,3}\.){3}\d{1,3}\b/g, '[IP REDACTED]')
    .replace(/\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b/g, '[EMAIL REDACTED]');
}

Monitoring Agent Execution

Track agent performance and resource usage:

async function executeWithMetrics(code: string) {
  const vmName = `sandbox-${Date.now()}`;
  const startTime = Date.now();

  await noid.createVM({ name: vmName });

  try {
    const result = await noid.exec(vmName, `python3 -c "${code}"`);
    const duration = Date.now() - startTime;

    // Log metrics
    console.log({
      vm: vmName,
      duration_ms: duration,
      exit_code: result.exitCode,
      output_length: result.stdout.length,
    });

    return result;
  } finally {
    await noid.destroyVM(vmName);
  }
}

Example: LangChain Integration

import { Tool } from 'langchain/tools';

class NoidPythonREPLTool extends Tool {
  name = 'python_repl';
  description = 'Execute Python code in a safe sandbox';

  private noid: NoidClient;

  constructor(noid: NoidClient) {
    super();
    this.noid = noid;
  }

  async _call(code: string): Promise<string> {
    const vmName = `langchain-${Date.now()}`;

    try {
      await this.noid.restore('python-base', 'golden', { as: vmName });

      const result = await this.noid.exec(
        vmName,
        `python3 -c "${code.replace(/"/g, '\\"')}"`,
        { timeout: 30000 }
      );

      return result.stdout || result.stderr;
    } finally {
      await this.noid.destroyVM(vmName).catch(console.error);
    }
  }
}

// Use with LangChain agent
import { initializeAgentExecutorWithOptions } from 'langchain/agents';
import { ChatOpenAI } from 'langchain/chat_models/openai';

const tools = [new NoidPythonREPLTool(noid)];
const llm = new ChatOpenAI({ temperature: 0 });

const executor = await initializeAgentExecutorWithOptions(tools, llm, {
  agentType: 'openai-functions',
});

const result = await executor.run(
  'Calculate the factorial of 10 using Python'
);

Next Steps