Voltar as noticias
perso — um motor de políticas WebAssembly que decide o que seu agente MCP pode fazer
MCP ProtocolAltaEN

perso — um motor de políticas WebAssembly que decide o que seu agente MCP pode fazer

Dev.to - MCP·20 de junho de 2026

Se você está construindo qualquer coisa em cima do MCP (Modelo de Protocolo de Contexto), você eventualmente se deparará com esta questão: uma vez que um LLM decide chamar uma ferramenta, quem realmente verifica se é permitido?

A especificação do MCP define como as ferramentas são descobertas e invocadas — não diz nada sobre quem pode chamar o que, ou sob quais condições. Isso fica inteiramente a cargo de quem constrói o host. Deixado sem resposta, o padrão padrão é totalmente aberto: qualquer função pode chamar qualquer ferramenta com quaisquer argumentos. Uma solução rápida geralmente resulta em um de dois padrões: lógica de autenticação espalhada por cada implementação de ferramenta, ou uma verificação de função grosseira que não consegue realmente olhar para os argumentos (então "agentes podem processar reembolsos" não tem como expressar "mas apenas até $500").

Nenhum dos dois escala uma vez que você tem mais do que algumas funções e ferramentas.

perso é um pequeno projeto em Rust que eu construí para dar uma resposta real a esse problema: um motor de aplicação de políticas para chamadas de ferramentas MCP, compilado em um único binário WebAssembly portátil.

A ideia

Você escreve suas regras de acesso como JSON simples — "agentes podem processar reembolsos, mas apenas até $500", "gerentes podem excluir registros que possuem", "esta ferramenta está bloqueada a menos que a MFA seja verificada" — e perso compila isso em um binário .wasm. Coloque esse binário em qualquer host (um servidor backend, um servidor MCP, uma função de borda, um CLI) e ele responde a uma pergunta, em microssegundos, para cada chamada de ferramenta: Permitir ou Negar.

O LLM nunca vê ou toca no token de função — o host possui isso, extraído de sua própria sessão/JWT. perso apenas avalia a chamada contra a política e devolve uma decisão mais uma razão legível por humanos.

json{ "tool_name": "process_refund", "roles": ["agent"],
"condition": { "NumericCheck": { "source": "Arguments", "field": "amount", "op": "Lte", "value": 500.0 } } }

Essa única regra é suficiente para impedir que uma função de agente aprove um reembolso de $800, não importa quão convincentemente o LLM tenha sido persuadido a tentar.

Condições podem verificar argumentos, atributos de agente ou atributos de recurso, e combinar com All/Any/Not. Todo o conjunto de regras é pré-expandido no momento do carregamento em um mapa plano, então cada avaliação real é uma busca O(1) mais uma pequena verificação de condição — sem correspondência global, sem varredura, no momento da solicitação.

A ação padrão é Negar: qualquer coisa não explicitamente permitida é rejeitada.

Vendo funcionar: perso-demo

Ler regras em um README só vai até certo ponto, então eu construí o perso-demo — um pequeno aplicativo de chat onde um LLM (Groq, llama-3.1-8b-instant) chama ferramentas contra um CRM B2B simulado, e perso intercepta cada intenção de chamada de ferramenta antes de ser executada.

Você escolhe uma função — agente, gerente ou administrador — e conversa naturalmente:

"Processar um reembolso de $200 para o pedido ORD-8821" → permitido, sob o limite de $500 do agente
"Tentar processar um reembolso de $800" → negado, NumericCheck falha
"Excluir o registro do cliente C-9001" como um gerente que não o possui → negado, FieldEquals falha (user_id != owner_id)
"Executar uma atualização em massa" como administrador sem MFA → negado, a condição All precisa tanto de env: produção quanto de mfa_verified

Cada decisão aparece inline no chat — verde para permitir, vermelho para negar — com a razão exata do motor de políticas. Há também uma barra lateral de políticas mostrando as regras brutas e um painel JSON ao vivo, para que você possa observar uma política não trivial baseada em RBAC + atributos sendo aplicada em tempo real sem uma única linha de código de autenticação dentro das próprias implementações de ferramentas.

O SDK que conecta tudo

O backend da demonstração não se comunica diretamente com o ABI WASM bruto — ele passa pelo @teknokeras/perso-sdk, o SDK oficial Node.js para perso.

As exportações WASM brutas são apenas quatro funções estilo C (alloc, dealloc, init, evaluate) que movem JSON prefixado por comprimento através da fronteira de memória WASM. O SDK envolve isso em uma API assíncrona limpa:

import { Perso } from '@teknokeras/perso-sdk'

const perso = await Perso.load('path/to/perso.wasm', {
  policy: 'path/to/policy.json',
})

const decision = await perso.evaluate({
  tool: 'process_refund',
  args: { order_id: 'ORD-8821', amount: 800 },
  role: 'agent',
  agentAttributes: { user_id: 'agt-099', env: 'production' },
})
// { decision: 'Deny', reason: '...' }

Ele também adiciona registro de auditoria estruturado por cima, com transportes plugáveis (consoleTransport, httpTransport, fileTransport, ou o seu próprio), para que cada decisão possa opcionalmente ser enviada para algum lugar durável para revisão posterior — útil quando você precisa mostrar por que um agente fez ou não fez algo, não apenas confiar em seu próprio relato.

Este é exatamente o SDK que o backend do perso-demo usa: uma instância compartilhada do Perso, carregada uma vez na inicialização, sentada em frente a cada chamada de ferramenta antes de chegar ao CRM simulado.

Por que eu acho que isso é importante

Uma camada de políticas como essa não torna um agente seguro por si só — não impede que um LLM seja manipulado para querer fazer algo prejudicial. O que ela faz é limitar o raio de explosão uma vez que isso acontece: um agente sequestrado ainda não pode chamar bulk_update sem env == produção e mfa_verified, não importa o que o prompt o convenceu a tentar. O padrão de negação significa que qualquer coisa que a política não cobre explicitamente falha. É um controle entre vários que você gostaria em um sistema agente de produção — ao lado da validação de entrada, barreiras de nível de modelo e monitoramento — e ainda é um controle que a maioria das integrações do MCP ainda não possui em vigor, mesmo onde ferramentas de autorização de uso geral (como OPA) poderiam, em princípio, ser adaptadas para cobri-lo.

Experimente

Motor: github.com/teknokeras/perso — workspace Rust, cargo build, compila para wasm32-unknown-unknown
Demonstração: github.com/teknokeras/perso-demo — pnpm install && pnpm dev, precisa de uma chave de API Groq gratuita
SDK Node: github.com/teknokeras/perso-

Contexto Triplo Up

A implementação do perso pode ajudar empresas brasileiras a garantir que suas integrações com agentes de IA sejam seguras e controladas. Com a crescente adoção de LLMs, ter um mecanismo de controle de acesso robusto é essencial para evitar ações indesejadas. Isso é especialmente relevante em setores regulados onde a conformidade é crítica.

Noticias relacionadas

Gostou do conteudo?

Receba toda semana as principais novidades sobre WebMCP.