Segurança e honestidade

Segurança

O que sai do teu Mac, como funciona a regra ploy_tainted, o que o Ploy verifica e o que não protege.

O Ploy corre um modelo pequeno no teu Mac, e um modelo pequeno por vezes obedece a ordens escritas numa página web. Por isso a segurança depende de regras do programa que o modelo não consegue contornar, não de confiar nele. Aqui está o que cada regra faz e não faz. A fiabilidade do modelo está em Limites honestos.

O que sai do Mac e o que não sai

Ficam no Mac: o modelo (Ollama, em 127.0.0.1), as conversas e a sua memória, os teus ficheiros, a transcrição de voz (whisper.cpp), o áudio e o vídeo (ffmpeg) e a leitura em voz alta (vozes do sistema).

Saem do Mac, e só nestes casos:

  • as frases de pesquisa do Veta, para o DuckDuckGo e para a Wikipédia;
  • os pedidos de descarga das páginas que o Veta lê, sem cookies;
  • as páginas que o modelo abre no browser da janela.

O lançador desliga a verificação de atualizações, a descarga da lista de modelos e os modelos gratuitos alojados do OpenCode (ver Ambiente). Esta lista descreve o código do Ploy. Não é uma auditoria de rede de tudo o que veio do OpenCode.

A regra ploy_tainted

Uma página web pode trazer ordens escritas ("ignora as instruções anteriores e..."), e um modelo de 8 mil milhões de parâmetros nem sempre as ignora. A regra ploy_tainted assume que isso vai acontecer e limita o estrago.

Quando a conversa fica marcada

Uma conversa fica marcada quando texto da web entra nela: quando uma ferramenta de browser (browser_open, browser_read, browser_find, browser_click, browser_type) devolve uma página, e antes de o modelo de resposta do Veta receber o dossiê. A marca é uma regra guardada na própria conversa. Se a conversa não puder ser marcada, o texto da página não é entregue ao modelo e o Veta não usa o que leu.

O que muda

Em Permission.assert (packages/core/src/permission.ts), numa conversa marcada, três tipos de ação passam a perguntar sempre: criar ou editar ficheiros (edit, que inclui a ferramenta de media), correr comandos (shell, incluindo um redirecionamento simples como > ficheiro) e aceder a pastas fora do projeto (external_directory). As aprovações guardadas são ignoradas e o pedido não oferece "sempre". Tem de ser ali porque as aprovações guardadas são avaliadas em último lugar e, de outro modo, venceriam as regras da conversa.

O que acontece em cada caso

Situação O que acontece
Conversa sem marca Valem as regras normais e as aprovações guardadas.
Marcada: criar ou editar ficheiros, correr comandos, aceder a pastas fora do projeto Pergunta sempre, sem "sempre".
Marcada: ler um ficheiro dentro do projeto Segue as regras normais.
Marcada: abrir outro site no browser browser_open recusa e diz ao modelo para pedir à pessoa.
Marcada, e uma regra nega a ação Continua negada. A marca só transforma "permitir" em "perguntar".
Não foi possível marcar O texto da web não é usado.

As frases de pesquisa do Veta

O Veta envia ao motor de pesquisa até três frases curtas por ronda, e no máximo duas rondas. Antes de saírem, ficam sem caminhos de ficheiros, endereços web, e-mails, endereços IP, códigos parecidos com IBAN, números parecidos com telefones ou cartões, textos longos que parecem chaves e segredos conhecidos (tokens, Bearer, password=). Têm 110 caracteres, no máximo.

O gateway local e o token

Os modelos Ploy são servidos por um pequeno servidor dentro do serviço local. Escuta só em 127.0.0.1, aceita apenas POST /v1/chat/completions e responde 403 a qualquer pedido sem o cabeçalho x-ploy-token. O token é gerado de novo de cada vez que o serviço arranca e só é acrescentado aos pedidos do próprio serviço. Uma página web não o consegue adivinhar.

O serviço local tem ainda uma palavra-passe própria, guardada em ficheiros service-*.json. Não os partilhes nem os colas em pedidos de ajuda.

Os endereços são verificados duas vezes

Para o Veta descarregar uma página, o endereço tem de ser público. Primeiro verifica-se o texto: só http e https, sem credenciais, sem localhost, sem nomes .local, .internal ou .lan, sem formas numéricas e sem intervalos privados ou locais (como 10.x, 127.x, 192.168.x). Depois o nome é resolvido e todos os endereços devolvidos têm de ser públicos. Cada redirecionamento (até quatro) repete as duas verificações, o corpo é limitado a 1,5 MB e só se lê texto.

O que o motor do Nesko recusa correr

Cada passo de um projeto tem uma prova: um comando que o motor corre e que tem de passar. O motor recusa uma prova que:

  • não seja uma só linha curta (até 400 caracteres);
  • chame programas que mudam a máquina ou usam a rede (sudo, rm, curl, ssh, brew...) ou subcomandos como git push e npm install;
  • use caminhos absolutos, ~, $HOME ou .., substituição de comandos ou tarefas em segundo plano;
  • apague ficheiros, lance programas ou use a rede a partir de código inline;
  • não verifique nada.

É só um primeiro filtro. A salvaguarda é o sandbox do macOS (sandbox-exec): sem rede, sem escrita fora da pasta do projeto e das pastas temporárias, e sem leitura de pastas sensíveis (como .ssh, .aws, .config/ploy e os dados de browsers). Variáveis de ambiente com nomes que sugerem segredos são retiradas. Sem sandbox, nenhum comando corre.

O que isto não protege

  • A regra não impede, por si só, que as ferramentas de browser abram um segundo site. ploy_tainted só trata de edições, comandos e pastas fora do projeto. Quem recusa o segundo site é a regra própria do browser, em browser_open: depois de uma página ser lida, só abre sites já visitados nessa conversa.
  • A regra do browser tem buracos. Só começa depois da primeira página, e o primeiro endereço não é limitado por ela. Seguir uma ligação com browser_click também não passa por ela. E, num site já visitado, um endereço pode levar texto.
  • A janela entre as duas verificações de nome. Um nome feito apontar para esta máquina entre a resolução e o pedido real não é apanhado.
  • Os filtros de ordens são parciais. Apanham os casos óbvios, não toda a paráfrase.
  • A marca é por conversa. Uma conversa nova começa sem ela, mesmo que cites com @ a memória de uma conversa marcada.
  • Ler dentro do projeto não pergunta, mesmo numa conversa marcada.
  • O sandbox do Nesko lê quase todo o disco, e uma prova pode alterar ficheiros do projeto.
  • Aprovar sem ler desfaz a proteção.

Como a medição do browser foi feita, e o que não prova, está em Medições.