Isolamento B2B2C

Cada cliente final num tenant. Cada pessoa numa memória privada.

Conta → Projeto → Tenant/schema → Agente → End user. Duas fronteiras complementares separam empresas e pessoas antes de o modelo decidir qualquer coisa.

Schema dedicado reduz o blast radius entre clientes; end_user_external_id separa a memória dentro de cada agente.

scope / server-sideno cross-tenant
01ContaFronteira comercial e de autenticaçãoaccount
02ProjetoAgrupa agentes, tenants e integraçõesproject
03Tenant + schemactc_agents_<uuid> dedicadodatabase
04AgenteIdentidade, Brain e ferramentas do fluxoagent
05End userMemória privada da pessoa atualprivate
A conta contém projetos; projetos contêm tenants com schema dedicado; agentes e usuários finais têm escopos adicionais.
Conta → Projetohierarquia explícita de posse
1 schemadedicado por tenant
server-scopedo modelo não escolhe de quem
403acesso fora da fronteira é negado

O risco real

Um WHERE esquecido não pode virar incidente entre clientes.

Produtos B2B2C carregam duas relações: sua empresa atende empresas, e essas empresas atendem pessoas. Tratar tudo como uma coluna numa tabela aumenta o blast radius de qualquer erro.

Cliente A enxerga cliente B

Uma query sem filtro ou um contexto reutilizado atravessa uma fronteira comercial e operacional.

Paciente A vira memória de B

Mesmo dentro do tenant certo, a personalização quebra se fatos não forem escopados por pessoa.

O modelo define posse

Se o LLM recebe company_id, tenant_id ou end_user como argumento livre, um prompt pode tentar mudá-los.

Mecanismo

O modelo escolhe o que buscar. O servidor decide de quem.

Identidade, autorização e escopo são resolvidos antes da tool call. O runtime embute company, agent, tenant e end user como literais e revalida a fronteira no endpoint interno.

Isolamento físico e lógico, em camadas

O tenant recebe schema dedicado. O Brain aplica prefixos de escopo e proteção contra traversal. A memória crítica usa a chave company + agent + end user.

Ler a arquitetura completa →
Conta
└── Projeto
    ├── Tenant A → schema A
    │   └── agent → end_user A
    └── Tenant B → schema B
        └── agent → end_user B

model args: what_to_search
server scope: whose_data
cross-tenant: 403

Uso real

A arquitetura nasceu para clientes dentro de clientes.

Um SaaS de gestão de clínicas roda agentes nossos em produção. Cada clínica é uma fronteira e cada paciente mantém seu próprio contexto.

schema por tenant

O provisionamento cria a camada de dados dedicada e mantém o vínculo de posse. O site não usa logo ou nome de cliente formal sem um case aprovado.

Ver agentes reais no Bench

Perguntas frequentes

Fronteiras explícitas, sem promessa vaga

É apenas um company_id em tabelas compartilhadas?

Não. Cada tenant recebe um schema MySQL dedicado, além do isolamento de vetores, storage e do escopo por usuário final.

O modelo pode escolher outro tenant?

Não. Company, agent, tenant e end user são derivados e revalidados no servidor. O modelo navega apenas dentro do escopo selado.

Excluir um tenant apaga o schema automaticamente?

Não. O delete lógico não executa DROP do schema. Remoções de dados precisam seguir uma operação explícita e auditável.

Arquitetura para escala B2B2C

Desenhe a fronteira antes de colocar o primeiro cliente dentro

Mapeamos conta, projeto, tenants, agentes e end users para o seu produto sem transformar isolamento em convenção informal.