DeepSeek Harness: Sandbox e Aprovação
Última atualização: 2026-08-31
O poder de um Agent está em sua capacidade de executar operações, mas "pode executar" não significa "deve executar." Políticas de aprovação são os freios do Agent; sandboxes são as cercas do Agent. Juntos, eles permitem que o Agent aja livremente dentro de limites seguros.
📋 Pré-requisitos: Completou 13-effect.md e 22-capability.md
1. O Que Você Vai Aprender
- Política de aprovação
- Predefinições de permissão
- Popups de aprovação para operações perigosas
- Registro de backend de sandbox
- ctx.sandbox e ctx.shell
- Configuração de sandbox remoto
2. Política de Aprovação
(1) Modos de Política
O DSH fornece quatro modos de aprovação:
| Modo | Comportamento | Ideal Para |
|---|---|---|
always |
Sempre permite, sem popup | Operações seguras (leitura, busca) |
ask |
Requer aprovação, popup de confirmação | Operações perigosas (criar, editar, shell) |
ask_with_confirm |
Popup de confirmação dupla | Operações extremamente perigosas (excluir, sudo) |
deny |
Negar automaticamente | Operações que nunca devem rodar (rm -rf /) |
▶ Exemplo 2:
# dsh.config.yaml
approval:
default: ask
tools:
file_edit:
read: always
create: ask
edit: ask
delete: ask_with_confirm
shell:
safe: always
moderate: ask
dangerous: ask_with_confirm
forbidden: deny
search:
default: always
sandbox:
default: ask
▶ Exemplo 3:
approval:
tools:
file_edit:
# Whitelist de caminhos com auto-permissão
auto_allow_paths:
- /tmp/**
- /workspace/**
# Blacklist de caminhos com auto-negação
auto_deny_paths:
- /etc/**
- /var/**
shell:
# Whitelist de comandos
auto_allow_commands:
- ls
- cat
- grep
- head
- wc
- git status
- git log
# Blacklist de comandos
auto_deny_commands:
- rm -rf /*
- mkfs
- dd if=*
▶ Exemplo 4:
import { defineTool } from '@deepseek-ai/dsh'
export default defineTool({
name: 'db_query',
description: 'Execute SQL query',
parameters: { /* ... */ },
approval: {
level: 'ask',
rules: [
{ match: { query: /^SELECT/i }, level: 'always' },
{ match: { query: /^DROP/i }, level: 'deny' },
{ match: { query: /^INSERT|^UPDATE|^DELETE/i }, level: 'ask_with_confirm' }
]
},
async execute({ query }, ctx) {
return await ctx.database.query(query)
}
})
3. Predefinições de Permissão
(1) Predefinições Integradas
O DSH fornece três predefinições de permissão:
| Predefinição | Descrição | Uso Típico |
|---|---|---|
| trusted | Modo de confiança, maioria das operações auto-permitidas | Ambiente de desenvolvimento pessoal |
| standard | Modo padrão, operações perigosas precisam de aprovação | Configuração padrão |
| restricted | Modo restrito, aprovação rigorosa | Ambiente de produção |
(2) Comparação de Predefinições
# trusted — Modo de confiança
approval:
tools:
file_edit: always
shell: always
search: always
# standard — Modo padrão
approval:
tools:
file_edit:
read: always
create: ask
edit: ask
delete: ask_with_confirm
shell: ask
# restricted — Modo restrito
approval:
tools:
file_edit: ask_with_confirm
shell: deny
search: ask
(3) Escolhendo uma Predefinição
# Selecionar predefinição na inicialização
pnpm dsh web --preset trusted
pnpm dsh web --preset standard
pnpm dsh web --preset restricted
(4) Predefinições Personalizadas
# dsh.config.yaml
approval:
presets:
my-team:
tools:
file_edit:
read: always
create: ask
edit: ask
delete: deny
shell: ask
4. Popup de Aprovação para Operações Perigosas
(1) Mecanismo de Popup
Quando uma chamada de tool requer aprovação, o DSH pausa a execução e exibe um popup de aprovação:
⚠️ Approval Required: Execute shell command
Command: npm install bcryptjs
Working directory: /home/alice/project
Risk level: MODERATE
[Allow] [Always for npm] [Deny]
(2) Opções de Aprovação
| Opção | Descrição |
|---|---|
| Allow | Permitir esta operação |
| Always | Permitir este tipo de operação (sem mais popups) |
| Always for X | Permitir operações correspondentes a uma regra específica |
| Deny | Negar esta operação |
(3) Aprovação em Lote
Múltiplas operações podem ser aprovadas em lote:
⚠️ Batch Approval Required: 3 operations
1. file_edit: create src/utils.ts
2. file_edit: edit src/app.ts
3. shell: npm install bcryptjs
[Allow All] [Review Each] [Deny All]
(4) Log de Aprovação
Todas as decisões de aprovação são registradas:
[approval] ALLOWED: file_edit(read, src/config.ts) — policy: always
[approval] ASKED: file_edit(create, src/utils.ts) — user: allowed
[approval] DENIED: shell(rm -rf /tmp/test) — policy: deny
5. Registro de Backend de Sandbox
(1) Conceito de Sandbox
Uma sandbox é um ambiente isolado para execução de tools — operações do Agent rodam dentro da sandbox sem afetar o sistema host:
graph LR
AGENT[Agent] -->|chama tools| SANDBOX[Ambiente Sandbox]
SANDBOX -->|execução isolada| FS[Sistema de arquivos da Sandbox]
SANDBOX -->|execução isolada| SHELL[Shell da Sandbox]
SANDBOX -->|rede isolada| NET[Rede da Sandbox]
SANDBOX -.->|não permitido| HOST[Sistema host]
(2) Interface do Backend de Sandbox
interface SandboxBackend {
name: string
execute(command: string, options: ShellOptions): Promise<ShellResult>
readFile(path: string): Promise<string>
writeFile(path: string, content: string): Promise<void>
stat(path: string): Promise<FileStat>
readdir(path: string): Promise<DirEntry[]>
}
(3) Registrando um Backend de Sandbox
import { Service, Context } from '@deepseek-ai/cordis'
export default class DockerSandboxBackend extends Service {
constructor(ctx: Context) {
super(ctx, 'sandbox')
ctx.implement(SandboxCapability, {
name: 'docker-sandbox',
async execute(command, options) {
const container = await this.getContainer()
const result = await container.exec(command, options)
return result
},
async readFile(path) {
const container = await this.getContainer()
return await container.readFile(path)
},
async writeFile(path, content) {
const container = await this.getContainer()
await container.writeFile(path, content)
},
// ...
})
}
}
(4) Configurando uma Sandbox
# dsh.config.yaml
sandbox:
backend: docker
config:
image: dsh-sandbox:latest
workdir: /workspace
memory: 512m
cpus: 1
timeout: 30000
network: none
6. ctx.sandbox e ctx.shell
(1) ctx.sandbox
ctx.sandbox fornece operações de arquivo com isolamento de sandbox:
export const inject = ['sandbox']
export function apply(ctx: Context) {
ctx.tools.register(defineTool({
name: 'sandbox_read',
description: 'Read file in sandbox',
parameters: {
type: 'object',
properties: {
path: { type: 'string', description: 'File path in sandbox' }
},
required: ['path']
},
async execute({ path }, ctx) {
const content = await ctx.sandbox.readFile(path)
return { content }
}
}))
}
(2) ctx.shell
ctx.shell executa comandos dentro da sandbox:
export const inject = ['shell']
export function apply(ctx: Context) {
ctx.tools.register(defineTool({
name: 'sandbox_exec',
description: 'Execute command in sandbox',
parameters: {
type: 'object',
properties: {
command: { type: 'string', description: 'Command to execute' }
},
required: ['command']
},
async execute({ command }, ctx) {
const result = await ctx.shell.execute(command, {
cwd: '/workspace',
timeout: 30000
})
return {
stdout: result.stdout,
stderr: result.stderr,
exitCode: result.exitCode
}
}
}))
}
(3) sandbox vs fs Direto
| Operação | fs Direto | ctx.sandbox |
|---|---|---|
| Caminhos de arquivo | Caminhos do sistema host | Caminhos internos da sandbox |
| Permissões | Permissões do usuário host | Permissões do usuário da sandbox |
| Isolamento | Nenhum | Totalmente isolado |
| Performance | Rápido | Ligeiramente mais lento (através da camada de sandbox) |
(4) Princípios de Uso Seguro
// ❌ Acesso direto ao sistema de arquivos host
import { readFileSync } from 'fs'
const content = readFileSync('/etc/passwd')
// ✅ Através da sandbox
const content = await ctx.sandbox.readFile('/etc/passwd')
// → Se a sandbox tem isolamento de sistema de arquivos, esta chamada será restrita
7. Configuração de Sandbox Remoto
(1) Arquitetura de Sandbox Remoto
graph TB
DSH[DSH Agent] -->|HTTP API| API[Sandbox API Server]
API -->|gerencia| CONTAINER1[Container 1<br/>Agent A]
API -->|gerencia| CONTAINER2[Container 2<br/>Agent B]
CONTAINER1 --> FS1[Sistema de arquivos isolado 1]
CONTAINER2 --> FS2[Sistema de arquivos isolado 2]
(2) Configurando uma Sandbox Remota
# dsh.config.yaml
sandbox:
backend: remote
config:
endpoint: http://sandbox-server:8080
apiKey: sk-sandbox-xxx
defaultImage: dsh-sandbox:latest
maxContainers: 10
containerTimeout: 3600
allowedImages:
- dsh-sandbox:latest
- dsh-sandbox-python:latest
(3) Implementação de Backend de Sandbox Remoto
export default class RemoteSandboxBackend extends Service {
private endpoint: string
private apiKey: string
constructor(ctx: Context) {
super(ctx, 'sandbox')
this.endpoint = ctx.config.endpoint
this.apiKey = ctx.config.apiKey
}
async execute(command: string, options: ShellOptions): Promise<ShellResult> {
const response = await fetch(`${this.endpoint}/execute`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${this.apiKey}`
},
body: JSON.stringify({ command, ...options })
})
return await response.json()
}
async readFile(path: string): Promise<string> {
const response = await fetch(`${this.endpoint}/read`, {
method: 'POST',
headers: { 'Authorization': `Bearer ${this.apiKey}` },
body: JSON.stringify({ path })
})
const data = await response.json()
return data.content
}
// ...
}
(4) Ciclo de Vida da Sandbox
1. Sessão do Agent criada → Solicitar container de sandbox
2. Sandbox API cria container → Retornar ID do container
3. Operações do Agent executam dentro do container
4. Sessão do Agent destruída → Solicitar destruição do container
5. Sandbox API destrói container → Liberar recursos
❓ Perguntas Frequentes
--preset trusted a maioria das operações é auto-permitida. Mas não recomendado para produção.📖 Resumo
- Quatro modos de política de aprovação: always/ask/ask_with_confirm/deny
- Predefinições de permissão: trusted (auto-permitir), standard (precisa de aprovação), restricted (aprovação rigorosa)
- Popups de aprovação pausam a execução do Agent, aguardando decisão do usuário
- Backends de sandbox são registrados via interface SandboxCapability, suportando Docker/remoto/personalizado
- ctx.sandbox e ctx.shell executam operações dentro da sandbox, isoladas do sistema host
- Sandboxes remotas são gerenciadas via HTTP API, suportando isolamento com múltiplos containers
📝 Exercícios
1. ⭐ Básico: Configure o DSH com a predefinição standard, tente fazer o Agent executar ls (auto-permitido) e rm (precisa de aprovação), e observe o comportamento do popup de aprovação.
2. ⭐⭐ Intermediário: Adicione regras de aprovação a uma tool personalizada — consultas SELECT auto-permitidas, INSERT/UPDATE/DELETE precisam de aprovação, DROP auto-negado. Teste o comportamento de aprovação para cada tipo de SQL.
3. ⭐⭐⭐ Desafio: Implemente um backend de sandbox simples (usando isolamento via subprocess) e registre-o no DSH. Faça o Agent executar comandos dentro da sandbox, verificando: 1) operações de arquivo são restritas ao diretório da sandbox; 2) requisições de rede são bloqueadas; 3) arquivos são limpos após a destruição da sandbox.