Dev.to AI 🤖 Ai 👁 0 📖 7 min read

Quem responde por este agente de IA? Uma resposta com e-CNPJ e e-CPF, em código aberto.

Imagine uma loja ou uma API de pedidos e chega um pedido feito por um agente de IA. A requisição está bem formada, a chave confere, o pagamento está a caminho. Ainda assim, sobra a pergunta que importa: quem responde por

Imagine uma loja ou uma API de pedidos e chega um pedido feito por um agente de IA. A requisição está bem formada, a chave confere, o pagamento está a caminho. Ainda assim, sobra a pergunta que importa: quem responde por esse agente? E ele podia mesmo fazer esse pedido?

As ferramentas de "know your agent" que encontrei respondem outra coisa. Em geral provam que o agente controla uma chave e dão uma nota de confiança. Só que uma chave não responde na Justiça, e uma nota não diz até quanto o agente pode gastar.

Foi aí que me caiu a ficha de que no Brasil a gente tem uma vantagem rara: certificado digital com validade jurídica, em escala. Toda empresa tem e-CNPJ por causa do fisco, e milhões de pessoas (advogados, contadores, médicos, empresários) usam e-CPF no dia a dia. Então por que não usar isso para dizer quem está por trás de um agente?

Desse incômodo nasceu o KYA Brasil, um projeto open source (MIT) que liga a chave de um agente a uma empresa ou a uma pessoa, com um mandato explícito do que ele pode fazer: https://github.com/celfons/kya-brasil

Vou contar em duas partes: primeiro a peça que serve a qualquer dev brasileiro, com ou sem agentes, e depois como ela vira identidade de agente.

Parte 1: ICP-Brasil em JavaScript, sem sofrimento

Se você já precisou validar uma assinatura com certificado ICP-Brasil em Node, conhece as opções: um SDK fechado de certificadora, um serviço pago, ou alguns dias lendo a RFC 5652 e os documentos do ITI.

O @kya-brasil/core resolve isso com funções puras sobre Web Crypto, sem dependência nativa. Funciona em Node 18+, Cloudflare Workers, Deno e no navegador.

npm install @kya-brasil/core

Para validar uma assinatura com e-CNPJ sobre um texto:

`import { verifyIcpSignature } from "@kya-brasil/core";

const prova = await verifyIcpSignature({
cmsBase64, // o .p7s em base64
challenge: textoAssinado, // o texto que deveria ter sido assinado
expectedCnpj: "11222333000181",
anchors // raízes da ICP-Brasil (o repositório traz as do ITI)
});
// prova.cnpj, prova.certificate_sha256, prova.crl_urls`

A função confere a assinatura, a cadeia até a raiz, a validade do certificado e o CNPJ gravado nele. Ela também barra duas armadilhas comuns: um e-CPF no lugar de um e-CNPJ, e um .p7s com conteúdo anexado diferente do texto esperado. Sem essa segunda checagem, qualquer documento que a empresa já assinou poderia passar como consentimento.

Com e-CPF é igual, trocando a função: verifyIcpPersonSignature devolve o CPF lido do certificado. Para quem só quer ler o certificado, há também cnpjFromCertificate e cpfFromCertificate.

A biblioteca não faz chamadas de rede, então a lista de revogação (LCR) fica por sua conta: você baixa a lista e passa para checkRevocation. Assim o controle do que sai para a internet fica com você.

Para assinar, o caminho é o mesmo para A1, A3 e certificado em nuvem:

`import { openPfx, ecnpjSigner } from "@kya-brasil/core";

const a1 = await openPfx(pfxBytes, senha); // .pfx/.p12, inclusive os antigos
const p7s = await a1.sign(texto);

// token, cartão, HSM ou nuvem: basta uma função que assine bytes com a chave do certificado
const a3 = ecnpjSigner({ certificates: [certDer, ...cadeia], sign: (bytes) => meuToken.sign(bytes) });
`
Para tokens A3 em Node, o pacote @kya-brasil/agent-tools traz suporte a PKCS#11 e um comando de terminal, kya-sign. Esse caminho é testado a cada push contra um token de software.

Parte 2: do certificado ao agente

Como um agente ganha uma credencial

O fluxo foi pensado para quem tem o certificado não precisar escrever uma linha de código:

O agente se registra com a chave dele, o CNPJ (ou a indicação de que age por uma pessoa) e um mandato.
Ele recebe um link de assinatura e o repassa a quem tem o certificado: o dono da empresa, o contador ou a própria pessoa.
Essa pessoa abre o link, vê exatamente o que está autorizando (qual agente, em nome de quem, com qual mandato) e assina com o próprio certificado. Com A1 a assinatura acontece no navegador, sem o arquivo sair da máquina; com A3 ou certificado em nuvem, usa o assinador de sempre.
O emissor confere tudo (assinatura do agente, cadeia, revogação e, para empresas, a situação na Receita pelos dados abertos) e emite uma credencial assinada, que pode ser verificada offline.
O mandato é um JSON que qualquer pessoa entende:

{
"actions": ["quote", "order"],
"max_per_operation": { "amount": 5000, "currency": "BRL" },
"max_per_day": { "amount": 20000, "currency": "BRL" },
"counterparties": ["12345678000190", "*.fornecedor.com.br"],
"valid_until": "2027-01-01T00:00:00Z"
}

A credencial não fica congelada. Todo dia o emissor confere de novo: se o certificado foi revogado, a credencial é revogada; se a empresa deixou de estar ativa na Receita, ela é suspensa.

Do lado de quem recebe o pedido

Voltando ao pedido: o agente assina cada requisição com a chave dele, e no seu servidor basta um middleware.

`import { createKyaAuth } from "@kya-brasil/agent-tools";

const auth = createKyaAuth();
app.use("/api/*", auth.hono()); // também há auth.express()

app.post("/api/pedidos", (c) => {
const kya = c.get("kya"); // quem é o agente, quem responde por ele, o mandato
const v = kya.check({ action: "order", amount: 4200, currency: "BRL" });
if (!v.allowed) return c.json({ erro: "fora do mandato", motivos: v.checks }, 403);
// segue o pedido
});`

O check() avalia o mandato na hora, sem custo. Se você quer algo para guardar como prova numa eventual disputa, o allowed() devolve um veredito assinado pelo emissor, com cada regra avaliada.

E quando o agente cria outros agentes?

Isso já é comum. Exigir uma assinatura com certificado para cada subagente não funciona na prática, e o atalho natural, compartilhar a chave, é pior ainda. Por isso o próprio mandato pode permitir delegação: o agente repassa a outro um pedaço do que ele pode fazer, nunca mais do que isso, com validade curta e até três níveis. Quem recebe o pedido confere a cadeia inteira, e a ação só passa se todos os níveis permitirem.

Pessoas físicas, sem virar uma base de CPFs

Pessoas também vão delegar a agentes: o advogado com o assistente do escritório, o contador com o agente que fala com a Receita, você com o agente que faz suas compras. Nesse caso, a pessoa autoriza com o próprio e-CPF, e o texto que ela assina já traz o consentimento.

A preocupação aqui foi não criar mais um banco de dados pessoais:

A credencial não mostra nada pessoal. Quem recebe o pedido sabe que há uma pessoa real, verificada pela ICP-Brasil, por trás do agente, mas não sabe quem.
O emissor guarda apenas um HMAC do CPF com chave secreta, nunca o CPF ou o nome. Um hash simples não bastaria: como só existem cerca de um bilhão de CPFs possíveis, ele seria revertido em minutos.
Quem já tem o CPF da pessoa (uma loja onde ela é cliente, por exemplo) pode perguntar se ele bate, e só recebe "sim" ou "não". Cada verificador recebe um identificador diferente para a mesma pessoa, para que serviços distintos não consigam cruzar dados. Depois de três respostas "não", o verificador é bloqueado, para ninguém usar o emissor como consulta de CPF.
A pessoa vê todas as suas credenciais e cada consulta feita sobre elas.
Quando a credencial é revogada ou vence, tudo é apagado.
Três jeitos de usar

Como biblioteca, dentro do seu sistema, com suas chaves e sua auditoria.
Rodando seu próprio emissor, em Docker ou no Cloudflare Workers.
Pelo serviço de referência, via HTTP ou MCP, com consulta grátis até 50 por dia e cobrança por chamada via x402. Quem usa Claude Desktop ou Cursor pode verificar um agente direto da conversa.
Queria ouvir vocês

O projeto está no começo, e o retorno de quem vive esses problemas vale mais do que qualquer feature nova:

Se você já integra com ICP-Brasil, o que faria falta na biblioteca? PAdES, carimbo do tempo, OCSP?
Se você usa e-CPF no trabalho, em que tarefa deixaria um agente agir em seu nome?
Se você constrói agentes ou recebe pedidos deles, o que faria você exigir uma credencial assim na sua API?

Se você é da área jurídica, como enxerga a responsabilidade por atos de um agente autorizado dessa forma?

Issues e PRs são bem-vindos, em português ou inglês: https://github.com/celfons/kya-brasil

📰 Read the original article on Dev.to AI

Originally published by Dev.to AI. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.