Pular para o conteúdo

Documentação do Anonimal

O Anonimal detecta PII em texto e a substitui de acordo com um modo escolhido. Um detector apenas encontra trechos; a substituição é decidida separadamente. Tudo roda localmente — os dados originais nunca saem da máquina.

A detecção depende do motor ativo.

Dados estruturados (ambos os motores)

E-mails, números de telefone, cartões de crédito (validados com a verificação Luhn), URLs, endereços IPv4 e segredos comuns.

Identificadores LATAM (ambos os motores)

DNI, CUIT / CUIL (com dígito verificador) e números bancários CBU argentinos.

PII em texto livre (apenas motor ML)

Nomes de pessoas e endereços em prosa corrente, via NER — a parte que o regex não consegue enxergar.

Regras personalizadas

Regras fornecidas pelo usuário: listas de sempre-ocultar / nunca-ocultar e seus próprios padrões {regex, placeholder}.

Um detector expõe detect(text) → [Span]; sobreposições são resolvidas pelo trecho mais longo (empates resolvidos por prioridade de rótulo).

  • lite — apenas regex. Leve, offline, sem modelo. Cobre dados estruturados e os identificadores LATAM acima. Ele não enxerga nomes nem endereços em texto livre. Sempre presente, mesmo na imagem lite e na biblioteca anonimal_lite.
  • ml — encapsula o OpenAI Privacy Filter (OPF, Apache-2.0). Preciso para PII em texto livre. Pesado (~2,8 GB de checkpoint, ~3 GB de RAM), limitado por CPU, carregado de forma preguiçosa em segundo plano com inferência serializada. Opcional.

Selecione com ANONIMAL_ENGINE: auto (ML se pronto, senão lite) · lite · ml. Requisições podem sobrescrever o padrão por chamada com um campo engine.

Dois modos são opacos (de mão única) e um é reversível. Um único anonimizador é usado por documento, então o mesmo valor sempre recebe a mesma substituição (consistência).

ModoResultadoReversível
typed[EMAIL] (placeholder por categoria)não
anon«REDACTADO» (único token opaco)não
pseudoEMAIL_1 (pseudônimo numerado estável)sim (retorna um mapa)
maskj***@***.com / ****-****-****-1234 (consciente do tipo)não
hashEMAIL_a1b2c3d4e5 (HMAC determinístico)não

typed, anon, mask e hash produzem saída não reversível. Use-os quando você só precisa compartilhar ou armazenar texto com segurança. O modo hash é determinístico: configure ANON_HASH_KEY para que o mesmo valor gere o mesmo hash entre reinícios (vínculo estável sem armazenar um mapa).

pseudo é o modo reversível. Ele substitui cada valor por um token estável (EMAIL_1, PERSON_2, …) e retorna um mapa token → original. O fluxo:

  1. POST /anonymize com mode: "pseudo" → obtenha o output anonimizado mais o map.
  2. Envie output ao LLM (a PII original nunca chega a ele).
  3. POST /deanonymize com a resposta do LLM e o mesmo map → os valores originais são reidratados de volta no texto.

O Anonimal preserva o formato de arquivos que já são texto: txt, md, log, srt, html, CSV (células anonimizadas, colunas intactas) e JSON (valores string anonimizados, chaves nunca tocadas; a saída permanece JSON válido). Um único anonimizador por arquivo significa um mapa consistente para o documento inteiro.

Converter Word / Excel / imagens / áudio / URLs não é tarefa do Anonimal — isso pertence ao Escriba, ao Extracta e ao Fisherboy, que alimentam texto já convertido. O Anonimal, no entanto, oferece redação de PDF real (/redact_pdf): tarjamento genuíno dos trechos detectados mais remoção de metadados.

Todos os endpoints exceto /health são protegidos por require_auth (veja autenticação). A URL base é o seu deployment, por exemplo, http://localhost:8920.

MétodoCaminhoO que faz
GET/healthStatus + disponibilidade do motor ML. Sempre aberto.
POST/detect{text} → trechos detectados.
POST/anonymize{text, mode, engine?}{output, map, summary}.
POST/deanonymize{text, map} → texto original.
POST/anonymize_fileUpload de arquivo + mode → conteúdo anonimizado (mesmo formato).
POST/redact_pdfPDF → PDF redigido (tarjado + metadados apagados).

Requisição:

{
"text": "email juan@acme.com, CUIT 20-12345678-6",
"mode": "pseudo",
"engine": "auto",
"rules": null
}

Resposta:

{
"engine": "lite",
"mode": "pseudo",
"output": "email EMAIL_1, CUIT ID_1",
"spans": [
{ "label": "EMAIL", "start": 6, "end": 19, "text": "juan@acme.com" }
],
"map": { "EMAIL_1": "juan@acme.com", "ID_1": "20-12345678-6" },
"reversible": true,
"summary": { "EMAIL": 1, "ID": 1 }
}

O map só é preenchido para pseudo; reversible reflete isso.

{ "text": "reply to EMAIL_1", "map": { "EMAIL_1": "juan@acme.com" } }

{ "output": "reply to juan@acme.com" }. Um map ausente ou vazio retorna 422.

Chamar POST /anonymize sem um mode retorna o contrato legado usado pelo Anonimal incorporado — {text, detected_spans, redacted_text, summary} com um placeholder por trecho. Isso permite que o Escriba e o Fisherboy apontem seu ANONIMAL_URL para o novo serviço sem mudar uma linha de código.

Retorna status, o motor e o modo padrão, e um bloco ml com available, ready e error. Usado pelo healthcheck do contêiner.

401 (token ou sessão ausente/inválido), 413 (texto ou PDF acima do limite de tamanho), 422 (modo inválido / mapa ausente / rules_json inválido), 503 (motor ML ou suporte a PDF indisponível).

O Anonimal aceita duas credenciais independentes na API:

  • Token de serviço — configure ANONIMAL_TOKEN. Toda requisição deve então carregá-lo, seja como Authorization: Bearer <token> ou como o cabeçalho X-Anonimal-Token. É assim que o Escriba e o Fisherboy se autenticam pela rede interna.
  • Sessão de navegador — quando ANONIMAL_AUTH_ENABLED=true, um cookie assinado da página /login também satisfaz a barreira da API (para a interface web).

Se nenhum dos dois estiver configurado, a API fica aberta (ela assume localhost). /health está sempre acessível para healthchecks.

O Anonimal é o único responsável pela anonimização na Escriba Suite; os satélites delegam a ele.

  • Modo serviço — um produto com ANONIMAL_URL configurado chama o Anonimal via HTTP (cobertura ML completa), autenticando com X-Anonimal-Token.
  • Fallback de biblioteca — sem ANONIMAL_URL, um produto recorre à anonimal_lite incorporada (apenas regex, stdlib puro), de modo que ainda pode anonimizar de forma autônoma.
Terminal window
pip install "anonimal-lite @ git+https://github.com/diegoparras/anonimal.git@v0.4.0"
from anonimal_lite import LiteEngine, Anonymizer, deanonymize
eng = LiteEngine()
out = Anonymizer("pseudo").process(text, eng.detect(text))

Há dois fluxos para dentro do Anonimal: um caminho humano (Extracta/Fisherboy entregam ao Escriba via sessionStorage['escriba.handoff'], e o botão “Anonymize” do Escriba chama a API) e um caminho automático (um worker não supervisionado chama a API diretamente). De qualquer forma, o Anonimal permanece o único lugar onde a anonimização acontece.

/detect, /anonymize (campo rules) e /anonymize_file (rules_json) aceitam um objeto de regras: always (sempre ocultar), never (nunca ocultar) e patterns ({regex, placeholder}). Os padrões são um superconjunto das regras do Escriba, com RE2 opcional para proteger contra ReDoS.