Segurança

E se o seu concorrente
também for cliente nosso?

Ele continua sem ver nada seu, e o que garante isso não é a gente ter escrito um if com cuidado. É o banco de dados recusar. Esta página mostra os quatro mecanismos que sustentam essa frase, cada um com o arquivo do código que o cumpre.

  • Papel sem privilégioa aplicação conecta por um papel que não pode contornar a política
  • Ver nadasem contexto de empresa, a consulta devolve zero linha, nunca todas
  • 25 testescada um tentando vazar dado de outra empresa de um jeito diferente

01

Isolamento é do banco, não do código

A separação entre empresas quase sempre é uma condição escrita em cada consulta. Funciona até o dia em que alguém escreve uma consulta e esquece, e esse dia não avisa. Aqui a regra mora no PostgreSQL: toda tabela com dado de cliente tem política de linha ligada e forçada, e a consulta que chega sem contexto de empresa devolve zero linha.

  • a aplicação conecta por um papel próprio, criado sem poder de contornar a política
  • o PostgreSQL ignora política de linha para superusuário, por isso o papel da aplicação não é um
  • “não encontrei” é a mesma resposta para o que não existe e para o que é de outra empresa
  • política ligada e forçada em cada tabela alembic/versions/0005_agents_conversations.py:557
  • papel da aplicação criado sem contorno alembic/versions/0001_extensions_roles_context.py:42
  • a aplicação usa esse papel, nunca o de migração src/nexo/db/session.py:22
  • o contexto da empresa entra por transação src/nexo/db/session.py:59
  • o teste que existe só para pegar o erro mais caro tests/test_rls.py:40

O que já foi tentado contra isso, e falhou

Controle sem teste de ataque é comentário. Estes rodam na suíte; se qualquer um deixar de passar, o sistema não sobe.

Pedir sem dizer de quem

Consulta sem contexto de empresa. Devolve zero linha.

tests/test_rls.py:73

Passar o id de outra empresa

Filtrar explicitamente pela organização alheia não vaza nada.

tests/test_rls.py:83

Forjar o contexto

Escrever um id de empresa inventado na sessão continua vendo nada.

tests/test_rls.py:140

Escrever na empresa alheia

Inserção bloqueada, e alteração em linha de outro não afeta nenhuma.

tests/test_rls.py:92 :107

Mudar a própria linha de dono

Mover um registro seu para outra empresa é recusado.

tests/test_rls.py:117

Usar o trabalhador de fundo como atalho

Quem processa a fila só enxerga a empresa do trabalho que pegou.

tests/test_rls.py:129

Levar um link de agenda para outro tenant

Um endereço de calendário conhecido não atravessa empresa, e ninguém revoga nem publica feed na organização alheia.

tests/test_rls.py:195 :207 :223

Esticar o papel de sistema

O papel que descobre a qual empresa um compromisso pertence lê essa coluna e nada mais: não faz SELECT *, não escreve e não alcança outra tabela.

tests/test_rls.py:360 :380 :392 :412

02

O que não dá para desfazer não acontece sem você

Cada ferramenta declara o próprio risco. A que não tem volta, emitir, cancelar, apagar, é declarada como confirm, e aí ela não executa: ela pede. Você decide, e o que você decidiu fica registrado com quem decidiu e quando.

  • rebaixar uma ação de risco é decisão de produto escrita, não conveniência de quem programou
  • um agente consultado por outro nunca executa ação de risco, mesmo com o pedido bem escrito
  • “peça pro financeiro emitir minha nota” não é um caminho para pular a fila de aprovação
  • risco é declarado pela ferramenta src/nexo/engine/tools.py:143
  • o que é confirm exige aprovação src/nexo/engine/tools.py:190
  • execução delegada recusa ação de risco src/nexo/engine/tools.py:226
  • a decisão do dono e o registro dela src/nexo/engine/approvals.py:65

03

Nenhum limite de gasto nasce ausente

O jeito mais comum de uma conta de IA explodir não é ataque: é um laço com defeito rodando num fim de semana, numa conta que ninguém configurou. Aqui o padrão protege e é o plano que afrouxa. Conta sem plano usa o teto padrão; “sem teto” existe, mas só como decisão cadastrada por alguém, nunca como esquecimento.

  • a verificação roda antes de começar a execução, não depois da fatura
  • custo, número de execuções e número de mensagens têm teto próprio
  • o teto padrão é largo para um piloto e ainda assim limita o estrago de um defeito
  • os tetos que valem sem plano src/nexo/security/quota.py:55
  • ausência de plano começa do padrão src/nexo/security/quota.py:132
  • “sem teto” é decisão cadastrada src/nexo/security/quota.py:138
  • a verificação antes da execução src/nexo/security/quota.py:252

04

Texto que vem de fora é informação, nunca ordem

Mensagem de cliente, descrição de produto, conteúdo de documento: tudo que não foi escrito por nós entra no prompt entre marcadores, e a instrução do sistema manda tratar aquilo como informação, inclusive quando o texto lá dentro pede para ignorar as regras. E o identificador que o modelo devolve não vira acesso antes de passar por uma checagem de posse.

  • a mensagem do cliente é embrulhada antes de virar mensagem do modelo
  • nome de tabela vindo do modelo não vira consulta: o formato é validado antes
  • item inexistente e item de outra empresa dão a mesma resposta, do contrário, a ferramenta viraria um detector de ids alheios
  • os marcadores do conteúdo externo src/nexo/engine/context.py:48
  • a regra que entra em toda execução src/nexo/engine/context.py:164
  • a mensagem do cliente já chega embrulhada src/nexo/engine/context.py:304
  • checagem de posse do id do modelo src/nexo/engine/resources.py:52
  • a mesma resposta para ausente e alheio src/nexo/engine/resources.py:87

Perguntas

O que perguntam sobre isso

E se o meu concorrente for cliente de vocês também?

Ele continua sem ver nada seu. A separação não é uma checagem no código da aplicação: é política do PostgreSQL, ligada e forçada em cada tabela que guarda dado de cliente. Uma consulta sem contexto de empresa não devolve nada.

Vocês têm SOC 2, ISO 27001 ou selo de conformidade com a LGPD?

Não. Nenhuma auditoria externa foi feita e nenhum selo foi emitido, e por isso não há nenhum nesta página. O que existe é o mecanismo, com o arquivo do código que o cumpre e o teste que cai se ele sumir.

O agente pode apagar ou emitir alguma coisa sozinho?

A ferramenta que não dá para desfazer é declarada como confirm e não executa sem sua aprovação. E um agente que foi consultado por outro nunca executa ação de risco, mesmo que o pedido tenha vindo com todas as palavras certas.

E se alguém mandar uma mensagem tentando dar ordem ao agente?

Todo conteúdo que vem de fora entra no prompt entre marcadores, e a instrução do sistema diz para tratar aquilo como informação e nunca como ordem, inclusive se o texto pedir para ignorar as regras. Identificador que o modelo devolve passa por uma checagem de posse antes de virar acesso a qualquer coisa.

Conferir

Toda frase daqui tem um arquivo.

A lista completa, cada afirmação desta página e da home, com o arquivo:linha que a sustenta e o que teve que sair do ar, está em web/landing/AFIRMACOES.md, no repositório. Tem um verificador junto: se uma frase perder a prova, ele acusa.