Implementando uma sandbox segura para agentes locais

por Ani Betts, Yash Gaitonde & Alex Haugland em Pesquisa
Implementando uma sandbox segura para agentes locais

Agentes de código estão ficando muito melhores em executar comandos de terminal para explorar o ambiente e fazer alterações. Usuários que aprovam esses comandos automaticamente desbloqueiam agentes significativamente mais poderosos, mas ao custo de um risco maior. Um agente que comete erros pode apagar bancos de dados, colocar em produção código quebrado ou vazar segredos.

Exigir aprovação humana para cada comando mitiga esse risco, mas muitas vezes apenas temporariamente. À medida que as aprovações se acumulam, os usuários deixam de inspecioná-las com cuidado. Isso piora quando engenheiros executam vários agentes em paralelo e precisam alternar de contexto entre solicitações de aprovação. O resultado é fadiga de aprovação, o que mina o propósito das aprovações em primeiro lugar.

Nos últimos três meses, resolvemos isso lançando sandbox para agentes no macOS, Linux e Windows. Agentes em sandbox rodam livremente dentro de um ambiente controlado e só pedem aprovação quando precisam sair dele, geralmente para acessar a internet.

Isso reduz drasticamente as interrupções. Agentes em sandbox param 40% menos vezes do que agentes sem sandbox, economizando horas de revisão e aprovação manual para os usuários.

Agentes em sandbox param 40% menos vezes do que agentes sem sandboxAgentes em sandbox param 40% menos vezes do que agentes sem sandbox

Nossos objetivos com o sandbox

Iniciamos nosso trabalho de sandboxing com o objetivo de eliminar interrupções enquanto aprimorávamos a segurança. Queríamos fornecer aos agentes liberdade suficiente para serem eficazes, ao mesmo tempo em que negávamos a eles permissões que representam risco.

Encontrar esse equilíbrio é mais difícil do que parece. Muitos comandos de terminal exigem privilégios inesperados, mesmo para etapas básicas de teste ou build. Um sandbox ingênuo bloquearia esses comandos e interromperia o fluxo de trabalho do agente. Projetar um sandbox utilizável é um exercício de equilibrar segurança e usabilidade, trabalhando dentro dos parâmetros definidos por cada sistema operacional.

Implementação

Expomos uma API de sandbox unificada, implementada de forma diferente em cada plataforma. macOS, Linux e Windows oferecem primitivas de sandbox distintas, o que influenciou as escolhas de design subjacentes.

macOS

Avaliamos quatro abordagens de sandboxing no macOS: App Sandbox, containers, máquinas virtuais e Seatbelt. App Sandbox é projetado para a Mac App Store e exigiria que o Cursor assinasse todo e qualquer binário que um agente pudesse executar. Isso adicionaria complexidade significativa e abriria novos vetores de abuso ao permitir que binários gerados ou modificados por agentes herdassem a confiança do Cursor. Containers nos limitariam a binários Linux, e máquinas virtuais impõem uma latência de inicialização inaceitável e uma sobrecarga de memória.

Sobrava o Seatbelt, acessado via sandbox-exec. Ele foi introduzido em 2007 e tornado obsoleto em 2016, mas ainda é usado por aplicativos críticos de terceiros, como o Chrome. Ele permite que um comando seja executado sob um perfil de sandbox que restringe o comportamento de toda a árvore de subprocessos.

O perfil define permissões com alta granularidade, restringindo syscalls e leituras ou gravações em arquivos e diretórios específicos por meio de uma linguagem de definição de políticas idiossincrática. Geramos essa política dinamicamente em tempo de execução com base em configurações de nível de espaço de trabalho e de nível de administrador, juntamente com o .cursorignore do usuário.

(deny file-write* (regex "^.*\/\\\.vscode($|\/.*)")
)
(deny file-write* (require-all
    (regex "^.*\/\\\.cursor($|\/.*)")
    (require-not (regex "^.*\/\\\.cursor/(rules|commands|worktrees|skills|agents)($|\/.*)")))
)
(deny file-write* (regex "^.*\\\.code-workspace$"))
(deny file-write* (regex "^.*\/\\\.cursorignore$"))
(deny file-write* (regex "^.*\/\\\.git/config$"))
(deny file-write* (regex "^.*\/\\\.git/hooks($|\/.*)")
)
(deny file-write* (regex "^(/private)?/var/folders/.*-cursor(-[a-z]+)?-zsh($|\/.*)")
)

Linux

Linux é ao mesmo tempo mais simples e mais complicado do que o macOS. O kernel expõe os primitivos necessários via Landlock e seccomp, mas o userspace é responsável por compô-los em um sandbox utilizável. Embora vários projetos de código aberto combinem esses mecanismos de forma eficaz, nenhum oferece suporte a recursos como .cursorignore.

Decidimos usar Landlock e seccomp diretamente. Seccomp bloqueia syscalls inseguras, enquanto Landlock aplica restrições de sistema de arquivos, permitindo que tornemos arquivos ignorados completamente inacessíveis para o processo em sandbox. Mapeamos os workspaces do usuário em um sistema de arquivos em overlay (overlay filesystem) e sobrescrevemos os arquivos ignorados com cópias sob Landlock que não podem ser lidas ou modificadas.

Encontrar e remontar esses arquivos é a parte mais lenta do sandboxing no Linux. Seria mais fácil filtrar operações de sistema de arquivos de maneira preguiçosa, como o macOS faz, mas o Linux não fornece acesso simples ao caminho do arquivo em um contexto seccomp-bpf.

Windows

No Windows, executamos nosso sandbox Linux dentro do WSL2. Criar um sandbox nativo equivalente no Windows é significativamente mais difícil porque a maioria das primitivas de sandboxing existentes foi criada para navegadores e não oferece suporte a ferramentas de desenvolvimento de uso geral. Estamos trabalhando com a Microsoft para garantir que as primitivas necessárias se tornem disponíveis.

Ensinando agentes a usar o sandbox

Um sandbox só é eficaz se os agentes conseguirem antecipar quais comandos provavelmente vão funcionar dentro do sandbox e reconhecer quando é necessário elevar permissões. Tornar os modelos conscientes do sandbox exigiu mudanças no harness do agente.

Começamos atualizando as descrições da ferramenta Shell para explicar as restrições do sandbox: se os comandos são executados com acesso ao sistema de arquivos, ao git ou à rede com base nas configurações do usuário, e como o agente pode solicitar permissões elevadas quando necessário. Chegar a uma alteração básica no harness com a qual ficássemos satisfeitos exigiu muitos testes manuais, em que executávamos alguns rollouts comuns, percebíamos onde as coisas saíam do esperado, ajustávamos o prompt e executávamos os rollouts novamente.

Depois avaliamos o impacto dessas mudanças usando nosso benchmark interno, o Cursor Bench, comparando agentes com e sem sandbox ativado. Rapidamente percebemos um padrão de falha comum: o agente tentava repetidamente o mesmo comando de terminal sem alterar as permissões.

Para resolver isso, atualizamos a forma como os resultados da ferramenta Shell são exibidos, destacando explicitamente a restrição de sandbox responsável por uma falha e, em certos casos, recomendando que o agente solicite elevação de permissões. Depois de disponibilizar esses lembretes, os agentes passaram a se recuperar de forma muito mais consistente de falhas relacionadas ao sandbox e o desempenho nas avaliações offline melhorou significativamente.

No entanto, as avaliações offline mostram apenas uma pequena parte da história. Para obter confiança adicional de que o sandbox não degradaria a experiência do usuário, fizemos um rollout gradual do sandbox em produção. O feedback que recebemos, tanto interno quanto externo, nos deu confiança para lançar o recurso. Agora vemos um terço das solicitações em plataformas compatíveis sendo executadas com o sandbox e já atendemos muitos clientes Enterprise, como a NVIDIA.

À medida que os agentes passam de gerar código para operar sistemas de produção, fornecer limites de execução se torna fundamental. Nossa implementação atual é um passo nessa direção. Olhando para frente, estamos especialmente empolgados com agentes nativos de sandbox treinados levando em conta as restrições de seu ambiente. Esses agentes podem receber a liberdade de escrever scripts e programas diretamente, em vez de ficarem limitados a chamadas de ferramentas.

Se você tiver interesse em trabalhar em problemas técnicos profundos relacionados ao futuro da programação, entre em contato pelo e-mail hiring@cursor.com.

Classificado em: Pesquisa

Autors: Ani Betts, Yash Gaitonde & Alex Haugland

Implementando uma sandbox segura para agentes locais · Cursor