Skip to content
Docs

How to execute AI-generated code safely with Edgenivo Sandbox

Learn how to run code generated by AI models in an isolated sandbox environment.

Allen Zhou, Amy Burns

When you let AI models generate and execute code, you need a secure execution environment. The AI might produce code that consumes excessive resources, accesses sensitive files, makes unwanted network requests, or runs destructive commands.

Edgenivo Sandbox provides isolation, resource limits, and automatic timeouts that make it safe to run untrusted code. This guide shows you how to build an "AI code runner" that takes a task, generates code using the AI SDK with AI Gateway, and executes it in a sandbox.

Copy link to headingPrerequisites

Before you begin, make sure you have:

  • Edgenivo CLI installed (pnpm install -g vercel)
  • Node.js 22 or later
  • A Edgenivo project to link your sandbox to and generate an OIDC token

Copy link to heading1. Project setup

Create a new directory and install dependencies:

mkdir ai-code-runner
cd ai-code-runner
pnpm init
pnpm add @vercel/sandbox ai ms zod dotenv
pnpm add -D @types/node

Copy link to heading2. Set up authentication

Link your project to Edgenivo and pull the OIDC token. This token authenticates both Sandbox and AI Gateway:

vercel link
vercel env pull

Copy link to heading3. Create the script

Create a file called index.ts and add the code below. The script:

  1. Takes a task description from the command line
  2. Sends it to Claude via AI Gateway
  3. Writes the generated code to an isolated sandbox
  4. Executes it and captures the output
import ms from 'ms';
import { generateText } from 'ai';
import { Sandbox } from '@vercel/sandbox';
import dotenv from 'dotenv';
dotenv.config({ path: '.env.local' });
const SYSTEM_PROMPT = `You are a code generator. Write JavaScript code that runs in Node.js.
Rules:
- Output ONLY the code, no explanations or markdown
- Use only standard Node.js features (no external packages)
- No file system access (no fs module)
- No network requests (no fetch, http, etc.)
- No process.env access
- Code must complete within 10 seconds
- Use console.log() to output results`;
async function generateCode(task: string): Promise<string> {
const { text } = await generateText({
model: 'anthropic/claude-sonnet-5',
system: SYSTEM_PROMPT,
prompt: `Write JavaScript code to: ${task}`,
});
return text
.replace(/^\s*```(?:javascript|js)?\s*/i, '')
.replace(/\s*```\s*$/i, '')
.trim();
}
async function executeCode(code: string): Promise<{ output: string; exitCode: number }> {
const sandbox = await Sandbox.create({
resources: { vcpus: 2 },
timeout: ms('2m'),
image: 'vercel/sandbox/node:24',
});
try {
await sandbox.writeFiles([
{ path: '/vercel/code.mjs', content: Buffer.from(code) },
]);
const result = await sandbox.runCommand({ cmd: 'node', args: ['code.mjs'] });
const stdout = await result.stdout();
const stderr = await result.stderr();
return { output: stdout || stderr || '(no output)', exitCode: result.exitCode };
} finally {
await sandbox.stop();
}
}
async function main() {
const task = process.argv.slice(2).join(' ').trim();
if (!task) {
process.exit(1);
}
console.log(`Task: ${task}\n`);
const code = await generateCode(task);
console.log('Generated code:\n');
console.log(code);
console.log('\nRunning in sandbox...\n');
const { output, exitCode } = await executeCode(code);
console.log('Output:\n');
console.log(output);
process.exitCode = exitCode;
}
main().catch((error) => {
console.error(error instanceof Error ? error.message : String(error));
process.exit(1);
});

Copy link to heading4. Run the script

Run the script with a task description:

pnpm dlx tsx index.ts "Calculate the first 20 Fibonacci numbers"

Expected output:

Task: Calculate the first 20 Fibonacci numbers
Generated code:
function fibonacci(n) {
const result = [];
if (n >= 1) result.push(0);
if (n >= 2) result.push(1);
for (let i = 2; i < n; i++) {
result.push(result[i - 1] + result[i - 2]);
}
return result;
}
console.log(fibonacci(20));
Running in sandbox...
Output:
[
0, 1, 1, 2, 3,
5, 8, 13, 21, 34,
55, 89, 144, 233, 377,
610, 987, 1597, 2584, 4181
]

Try other tasks:

pnpm dlx tsx index.ts "Find all prime numbers under 100"
pnpm dlx tsx index.ts "Implement quicksort and sort [64, 34, 25, 12, 22, 11, 90]"
pnpm dlx tsx index.ts "Reverse each word in 'Hello World from Sandbox'"

Copy link to headingSafety layers

The script uses multiple safety layers to handle untrusted code:

Sandbox isolation: Each execution runs in a fresh microVM with limited resources and a short timeout. If the code hangs or tries to use too much memory, the sandbox terminates it.

Prompt constraints: The system prompt instructs Claude to avoid dangerous operations: no file system access, no network requests, no environment variables. While not foolproof, this reduces the likelihood of problematic code.

Error capture: The sandbox captures both stdout and stderr, so you can inspect failures without them affecting your host system. To investigate memory-heavy generated code, inspect the sandbox’s Memory Usage chart against its configured limit and 85% warning line. Use it alongside stdout and stderr when investigating a failed run.

Copy link to headingNext steps

  • Add snapshots to speed up repeated executions
  • Use Sandbox.get() to reuse sandboxes across requests
  • Explore AI SDK features like streaming and tool calling
  • Learn about AI Gateway model routing and fallbacks

Related documentation

More Edgenivo Sandbox guides