Segurança e criptografia
Usuários — /users

CRUD de usuários, com perfil de acesso, interfaces permitidas e assinatura de alertas. O login pode ser local (senha no CMS) ou via LDAP/Active Directory, conforme a configuração global.
O telefone só aparece no formulário quando o aceite de alertas está ligado — é o único lugar em que o número é usado, no payload que o canal WhatsApp entrega à automação (ver Alertas). Com o aceite ligado ele passa a ser obrigatório; desligar o aceite limpa o campo.
Recebe resumo diário é um aceite separado, e de propósito: ele liga o e-mail do Raio-X do Dia, que sai recortado pelas Aplicações e Interfaces que aquele usuário enxerga. Amarrá-lo ao aceite de alertas obrigaria quem só quer o resumo por e-mail a cadastrar celular, já que o aceite de alertas governa também o WhatsApp.
Interfaces permitidas
É o segundo eixo de permissão, independente do Perfil: o Perfil diz quais telas o usuário abre; as Interfaces permitidas dizem quais dados ele vê dentro delas. Um operador com a Ferramenta Mensagens liberada, mas com só duas Interfaces marcadas, enxerga as mensagens dessas duas.
A lista vem agrupada por Aplicação, e o cabeçalho de cada grupo tem uma caixa Todas que libera (ou tira) o grupo inteiro de uma vez — numa planta em que o usuário recebe a Aplicação inteira, marcar 18 interfaces uma a uma era o caminho normal, não a exceção. Com só parte do grupo marcada, a caixa fica em estado intermediário: dá para ver que a Aplicação está parcialmente liberada sem precisar abrir o grupo e conferir interface por interface.
Nenhuma interface marcada significa acesso irrestrito, não acesso nenhum — mesma convenção do administrador. É o padrão para quem cuida da instalação inteira; restringir é o ato explícito.
O recorte vale por rota, não só pela listagem: pedir um registro pelo id devolve 404 quando ele pertence a uma Interface fora do seu alcance, e o corpo de um POST não consegue apontar para uma Interface que você não tem. Vale também para a escrita, e não só para a leitura — criar, editar ou apagar um registro de uma Aplicação que você não enxerga é recusado, inclusive quando a edição tenta mover o registro para lá.
Onze telas foram alinhadas a essa regra ao longo de setembro de 2026 — Alertas, Erros de Negócio, o Cockpit, Credenciais, API Keys, Variáveis de Aplicação, Chaves de Criptografia, Regras de Criptografia, Transformadores, os logs de Coleta e de Envio e Conexões Externas —, então um usuário restrito pode notar que passou a ver menos do que via antes. É a correção, não uma regressão.
As três últimas entraram por caminhos diferentes, e vale saber qual é o de cada uma:
| Tela | O que passou a recortar |
|---|---|
| Transformadores | Sem Escopo o Transformador é global e todo mundo o vê; com Escopo, só quem tem uma das Interfaces escopadas. Vale também nas rotas por id — sem isso, o script de outra área estava a um GET de distância |
| Log de Coleta e Log de Envio | As mensagens já eram recortadas; vazava o eixo, que agrupa pela Aplicação que enviou — e quem envia para a sua Interface costuma ser a Aplicação de outra área. As origens fora do seu alcance viram uma barra agregada, sem nome. Some o nome, não o número: o total continua batendo com a tela de Mensagens |
| Conexões Externas | A conexão ganha dono pelo uso — o Keep Alive de uma Aplicação e as Coletas que buscam por ela. Conexão que ninguém usa ainda continua visível para todos, senão ela sumiria da tela no instante seguinte ao Salvar |
O que cada usuário vê sobre si mesmo
No popover do próprio usuário, no cabeçalho, qualquer pessoa consulta as suas Interfaces liberadas — agrupadas por Aplicação, com o tipo (Coleta ou Entrega) e o estado de bloqueio de cada uma. Não depende de ter a Ferramenta Usuários nem Aplicações no perfil: ver as próprias permissões é diferente de administrar as dos outros.
O mesmo popover permite trocar ou remover a foto do avatar. A imagem é reduzida a 256×256 JPEG no navegador antes de subir — a foto original da câmera nunca vai para o banco — e só data URL de imagem é aceita pelo servidor.
Perfis — /roles

Um Perfil é um conjunto de Ferramentas liberadas. Cada Ferramenta corresponde a uma tela do sistema — é o que decide o que aparece no menu e o que a API autoriza.
Telas agrupadas por Aplicação e por Interface dependem das Ferramentas Aplicações e Interfaces para carregar suas listas. Um perfil sem elas vê a tela vazia, e não uma mensagem de permissão negada.
Nível de acesso por Ferramenta

Em cada Ferramenta o perfil recebe um nível, não um conjunto de métodos HTTP:
| Nível | O que permite |
|---|---|
| Sem acesso | A tela não aparece no menu, e a API recusa |
| Consultar | Abre a tela e vê os dados, sem alterar nada |
| Consultar e editar | Consulta, cria e altera — mas não exclui. Em Mensagens, é o nível que libera reprocessar e cancelar |
| Acesso total | Tudo o que a Ferramenta permite, inclusive excluir |
| Permitir | Executa a ação, nas Ferramentas que não têm tela própria — decifrar conteúdo, enviar por e-mail, instalar licença |
Cada Ferramenta oferece só os níveis que fazem sentido nela: o Log de Auditoria só pode ser consultado, e Instalar Licença só pode ser permitido ou não. Quem decide isso é a lista de métodos que aquelas rotas realmente aceitam, guardada no próprio cadastro da Ferramenta.
A tela mostrava as quatro caixas GET / POST / PUT / DELETE, e o problema não era de
estética: reprocessar uma mensagem é POST em /messages, não uma Ferramenta separada — então
marcar só GET liberava a tela e a deixava sem funcionar, sem nada explicando por quê. O Modo
avançado continua mostrando as quatro caixas, para as combinações que não cabem em nenhum nível.
Os perfis que já vêm no sistema
| Perfil | Para quem |
|---|---|
| CMS_Administrator | Acesso irrestrito. Nasce com isAdmin e não depende de Ferramenta nenhuma |
| CMS_Monitor | Acompanha mensagens e painéis, sem entrar em configuração |
| CMS_Monitor_Cripto | O mesmo, mais as Regras de Criptografia e o direito de decifrar conteúdo |
| CMS_Developer | Constrói e mantém integrações, sem administrar usuários, perfis ou segurança |
O CMS_Developer alcança o Laboratório de Integração inteiro — Banco de Testes, Planos de Teste e Simuladores —, além de decifrar conteúdo, das Sessões de IA e do MCP em leitura. Ele não tem Coleta, Definição de Mensagem nem o SAP SDK: são as portas por onde se muda o que roda em produção.
Eles são criados no boot em que faltam, e depois disso o CMS não mexe mais nas permissões deles: o que você tirar na tela continua tirado no restart seguinte. Para levar um ajuste destes perfis a uma instalação que já existe, há um script dedicado, que mostra o plano antes de gravar.
Numa instalação nova, três Ferramentas nascem desligadas em Configurações › Ferramentas — Definições de Coleta, Definições de Entrega e Workers —, como na instalação de referência. Ligar é um ato consciente de quem administra. Isso vale só na criação: o CMS nunca religa no restart o que um administrador desligou, porque desligar uma Ferramenta revoga o acesso de todos os perfis não administradores de uma vez.
Ações restritas a administradores
Ter a Ferramenta Perfis, Usuários ou Ferramentas autoriza administrar cadastros, não escalar privilégio. Nove operações exigem que quem chama já seja administrador, independentemente das Ferramentas do perfil:
| Operação | Tela |
|---|---|
Marcar um Perfil como administrador (isAdmin) | Perfis |
| Gravar a matriz de permissões de um Perfil | Perfis |
| Trocar o Perfil de um usuário | Usuários |
| Trocar o login de outra pessoa (o próprio login continua livre) | Usuários |
| Trocar a origem de autenticação (local ou LDAP) de qualquer conta | Usuários |
| Desativar ou reativar um usuário | Usuários |
| Excluir um usuário | Usuários |
| Redefinir a senha de outra pessoa — exige também confirmar a própria senha (e o código 2FA, se ativo) | Usuários |
| Criar, ativar/desativar ou remover uma Ferramenta | Ferramentas |
Fora do controle de acesso, duas ações com efeito na instalação inteira também exigem administrador desde setembro de 2026: Importar / Exportar configuração e enviar ou remover a SDK SAP (ver Ferramentas que não são telas).
O critério não é o campo, é a pergunta: esta operação altera o controle de acesso? Editar nome, descrição, telefone ou e-mail continua sendo trabalho de quem tem a Ferramenta. E a matriz de permissões só exige privilégio quando muda — a tela manda o formulário inteiro em toda edição, e reenviar o que já está gravado não é uma concessão.
Sem isso, um perfil de suporte com escrita em Perfis marcava a si mesmo como administrador; ou, sem
tocar em isAdmin, concedia ao próprio perfil todas as Ferramentas do sistema — o efeito prático é
o mesmo, porque a autorização olha a matriz, e isAdmin é só um atalho. E, com escrita em Usuários,
desativava um a um os administradores até não sobrar ninguém capaz de reverter: usuário inativo
perde acesso a tudo, inclusive a este controle. Toda tentativa, aceita ou negada, entra no Log de
Auditoria — assim como a concessão efetivada.
O campo endpoint de uma Ferramenta é imutável depois de criada: ele é a chave que a API usa para casar rota e permissão, e reapontá-lo mudaria o significado da Ferramenta para todos os perfis de uma vez. O flag ativo tem o mesmo peso — desligar uma Ferramenta a revoga de todos os perfis não administradores de uma vez, e religá-la desfaz uma revogação feita de propósito.
Política de senha e aviso de tentativas
Em Configurações › Parâmetros:
- Tamanho mínimo da senha — aplicado a novos cadastros e trocas. O sistema nunca aceita menos de 8 caracteres, mesmo com um valor menor configurado.
- Tentativas de login para alertar — erros de senha seguidos que disparam um e-mail aos administradores e ao dono da conta. Zero desliga o aviso.
A conta nunca é bloqueada por tentativas malsucedidas: bloquear no terceiro erro daria a
qualquer pessoa que conheça um login a possibilidade de derrubar o acesso administrativo de
propósito. Quem encarece a tentativa em massa é o limite por origem, aplicado nas rotas de login.
Todo erro de senha entra no Log de Auditoria com a ação LOGIN_FALHO e o IP de origem.
Primeiro acesso
A conta administrativa criada na primeira execução nasce com senha aleatória (impressa uma única vez no log da API) e senha expirada: o primeiro login não abre o sistema, exige definir uma senha nova. O mesmo vale para toda senha redefinida por um administrador para outra pessoa.
Ferramentas que não são telas
Nem toda Ferramenta corresponde a um item do menu. Algumas governam uma ação dentro de uma tela que o usuário já tem, e existem para poder ser concedidas separadamente:
| Ferramenta | O que libera |
|---|---|
| Decifrar Mensagem | O botão de decifrar no detalhe da mensagem |
| Enviar PDF da Mensagem | O envio da mensagem por e-mail |
| Instalar Pack e Assistente de Integração | Os assistentes que abrem de dentro de Aplicações |
| Agente de Integração | As abas Investigar e Configurar do Assistente de IA. A aba Pergunte é livre e não depende de Ferramenta nenhuma |
| Importar / Exportar | A seção de import/export dentro da Danger Zone — só para administrador: a Ferramenta sozinha não libera mais |
| SDK SAP | A aba de instalação da SDK, em Parâmetros — também só para administrador |
| Ferramentas | A aba que liga e desliga Ferramentas do sistema |
MCP Integration Tools (/mcp/integration-tools) | Deixa o token MCP de um usuário de serviço chamar as ferramentas do Servidor MCP de integrações. API Key e Credencial de Entrada não precisam dela |
Elas aparecem em Perfis agrupadas sob a tela a que pertencem — Decifrar Mensagem junto de Mensagens, Instalar Pack junto de Aplicações — e não numa lista solta no fim.
A separação existe para que ver não implique poder. Dar acesso a Mensagens é rotineiro; deixar alguém decifrar payload ou mandar o PDF para fora é outra decisão, e por isso é outra caixa de seleção.
Autenticação em duas etapas (2FA)
Quando o 2FA está ativado globalmente (Configurações), o login passa a ser:
POST /auth/login→ se o usuário tem 2FA ativo, retorna umtempTokende 5 minutos em vez do token de acesso;- o usuário informa o código TOTP do app autenticador;
POST /auth/2fa/validate(comtempToken+ código) → retorna o JWT definitivo.
Cada usuário ativa o 2FA na própria conta: POST /auth/2fa/generate devolve o QR code e
POST /auth/2fa/confirmar com o primeiro código conclui a ativação.
Com o 2FA ligado globalmente e ainda não ativado na sua conta, um ponto âmbar aparece no avatar do cabeçalho; o estado por extenso fica na linha 2FA do menu do usuário. Quando está tudo certo não há marca nenhuma — não existe ação a tomar, e um segundo selo verde competindo com o sino e com o contador do plantão só ensinaria a ignorar a cor âmbar naquela barra.
Criptografia de payload
Mensagens podem ser cifradas com AES-256-GCM antes de serem persistidas, sem afetar o payload realmente entregue ou coletado — o destino continua recebendo o conteúdo original.
Chaves de Criptografia — /encryption-keys

Material simétrico gerado (ou informado) pelo usuário, guardado cifrado em repouso por envelope
encryption (CREDENCIAL_ENCRYPTION_KEY). Cada chave registra quem a criou e pode ter uma lista
de usuários autorizados a decifrar.
Lista vazia é fail-closed: apenas usuários com perfil administrador conseguem decifrar.
Regras de Criptografia — /encryption-rules

Associam uma Chave a uma Definição de Entrega ou de Coleta, condicionadas a um texto coringa e a um sentido (Envio, Retorno ou Ambos). Também é possível vincular uma chave incondicional diretamente na Definição.
Numa Entrega com Transformador por Aplicação produtora, a mensagem guarda também o que a produtora mandou, num formato que não é o da Entrega — e a regra casa pelo texto. Se o texto coringa aparece nesse conteúdo, a regra vale como em qualquer payload. Se não aparece, mas a regra casou com o convertido, o conteúdo da produtora é cifrado inteiro com a chave dela: sem isso, o convertido ficaria cifrado e o original, com o mesmo dado, em claro ao lado. A regra Parcial não se transfere, porque o trecho que ela cifraria não existe no outro formato.
A listagem também diz quem criou e quem alterou por último cada regra, com data. É a mesma autoria de Conexões e Transformadores: o autor é sempre quem estava autenticado na hora, guardado como e-mail, e não um campo enviado no formulário. Regra criada antes de o campo existir aparece com um traço.
Decifra sob demanda
O payload cifrado só é revertido quando alguém clica em Decifrar no detalhe da mensagem — nunca automaticamente em listagem ou exportação. No clique, o CMS exige:
Autorização
Estar na lista de autorizados da chave usada (ou ser administrador).
Reautenticação
Informar a própria senha — e o código 2FA, se ativo.
Justificativa
Um texto não vazio explicando por que o conteúdo precisa ser visto.
Log de Auditoria — /reports/audit-log

Toda tentativa de decifra — autorizada ou não, com senha certa ou errada — gera um evento com usuário, ação, resultado (sucesso/negado), motivo técnico da negação, a justificativa digitada, a entidade afetada e o IP de origem.