Trilogia CaraCore CSO — Parte 2 de 3
Sessões Opacas e Segurança Pragmática: Adeus JWT no Browser e a Blindagem do CaraCore CSO

A Fortaleza Relacional: A proteção de acessos corporativos por meio de sessões opacas, controle estrito de perfis e trilha de auditoria em banco de dados.
Tempo de leitura: 7 minutos
Nos últimos dez anos, a indústria de desenvolvimento de software foi engolida por um dogma quase inquestionável: "qualquer aplicação moderna deve utilizar JSON Web Tokens (JWT) armazenados no LocalStorage do navegador". O argumento parecia tentador: autenticação sem estado (stateless), sem tocar no banco de dados e supostamente mais escalável.
Entretanto, na linha de frente dos sistemas corporativos e da gestão operacional de frotas, a teoria do manual acadêmico costuma ruir diante do primeiro incidente de segurança. Se um colaborador é desligado da empresa em um sábado à tarde, como você revoga instantaneamente o acesso dele se o token JWT dele é válido pelas próximas 24 horas? A resposta usual do mercado é criar listas de bloqueio (blacklists) no Redis — transformando a arquitetura "stateless" em um sistema com estado, só que três vezes mais complexo e frágil.
Ao desenhar a segurança do CaraCore CSO, decidimos dar um passo atrás, abandonar modismos e adotar o modelo de Sessões Opacas com Estado no Banco Relacional.
1. Por que Tokens no Browser São um Risco Silencioso
Guardar credenciais ou tokens decodificáveis no cliente (como `localStorage` ou `sessionStorage`) expõe a aplicação a ataques clássicos de XSS (Cross-Site Scripting). Qualquer script malicioso injetado por uma dependência de terceiros tem acesso irrestrito ao token.
No CaraCore CSO, a estratégia de autenticação web adota premissas não negociáveis:
- Cookies HttpOnly, Secure e SameSite=Lax: O JavaScript do navegador sequer enxerga o identificador de sessão. Ele trafega exclusivamente no cabeçalho HTTP gerenciado pelo próprio browser.
- Identificadores Opacos (Tokens Aleatórios de Alta Entropia): O cookie `cso_sid` não contém perfil, nem ID de usuário, nem tenant ID codificados em Base64. Ele é apenas uma chave criptográfica aleatória.
- Estado no PostgreSQL (`tb_web_session`): A validação de quem é o usuário, qual o plano da frota e qual o perfil de acesso é resolvida diretamente no banco em uma consulta indexada ultrarrápida. Se o gestor desativa um usuário, a sessão morre no milissegundo seguinte.
2. O Governo de Acesso em Dois Mundos
Uma falha comum em SaaS B2B é misturar a administração da plataforma com o painel do cliente final. No CaraCore CSO, criamos uma separação estrita entre dois mundos:
- O Mundo do Tenant (Frota):
- ENTREGADOR: Acesso estritamente restrito ao registro de campo e checklist.
- GESTOR: Visão completa de operação, custos, manutenções e relatórios analíticos.
- ADMIN: Gestão de usuários do tenant, convites de equipe e aceite dos termos LGPD.
- O Mundo da Plataforma (Operador CaraCore — `/cso-ops`):
Uma área completamente isolada, acessível sob o cookie `cso_ops_sid`, protegida por captcha gráfico local, sem qualquer exposição de rotas na interface pública do cliente. É onde gerenciamos ativações de planos Pix, monitoramos tenants inativos e executamos resets assistidos de contingência.
3. Código em Linha de Frente: O Filtro Defensivo de Sessão
Veja como o filtro de autenticação intercepta as requisições no Quarkus, validando a sessão opaca e rejeitando qualquer desvio de perfil antes que a camada de visualização seja acionada:
package br.com.caracore.cso.core.security;
import br.com.caracore.cso.modules.auth.model.WebSession;
import jakarta.ws.rs.container.ContainerRequestContext;
import jakarta.ws.rs.container.ContainerRequestFilter;
import jakarta.ws.rs.core.Cookie;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.Provider;
import java.net.URI;
import java.time.LocalDateTime;
@Provider
public class WebAuthFilter implements ContainerRequestFilter {
@Override
public void filter(ContainerRequestContext requestContext) {
String path = requestContext.getUriInfo().getPath();
if (isRotaPublica(path)) {
return;
}
Cookie sessionCookie = requestContext.getCookies().get("cso_sid");
if (sessionCookie == null || sessionCookie.getValue().isBlank()) {
redirecionarParaLogin(requestContext);
return;
}
// Validação no PostgreSQL com verificação de expiração e revogação
WebSession session = WebSession.find("token = ?1 and expiraEm > ?2",
sessionCookie.getValue(), LocalDateTime.now())
.firstResult();
if (session == null || !session.usuario.ativo) {
redirecionarParaLogin(requestContext);
return;
}
// Propaga o contexto autenticado de forma imutável
requestContext.setProperty("cso.user", session.usuario);
requestContext.setProperty("cso.tenantId", session.usuario.tenant.id);
}
private void redirecionarParaLogin(ContainerRequestContext ctx) {
ctx.abortWith(Response.seeOther(URI.create("/login?expirado=true")).build());
}
private boolean isRotaPublica(String path) {
return path.equals("/") || path.startsWith("/login") || path.startsWith("/cadastro") || path.startsWith("/assets");
}
}
4. Conformidade e Trilha Auditável LGPD
Segurança não é apenas impedir invasões; é saber exatamente quem realizou cada operação. No CaraCore CSO, todas as ações sensíveis — cadastro de motoristas, exclusão de registros ou alterações de CNH — geram registros imutáveis na tabela de auditoria LGPD.
O gestor da frota tem acesso a uma tela dedicada de auditoria com filtros por período, usuário e ação, podendo imprimir o relatório em PDF para fins de compliance e fiscalização trabalhista.
Conclusão: Simplicidade é o Mais Alto Grau de Sofisticação
Ao substituir a parafernália de tokens JWT no frontend por sessões opacas gerenciadas pelo PostgreSQL, reduzimos o código em mais de 60%, eliminamos vetores críticos de ataque no navegador e ganhamos controle absoluto sobre o ciclo de vida do usuário.
No terceiro e último artigo desta série, abordaremos o aspecto financeiro e de negócio: como sustentamos planos acessíveis (de R$ 5 a R$ 49/mês), a integração com pagamentos Pix sem intermediários predatórios e a visão do futuro com o modelo Local-First (Bunker Digital).
Dicionário de Termos Técnicos
Termos essenciais para a compreensão da arquitetura de segurança abordada:
- Cookie HttpOnly
- Diretiva de segurança em cabeçalhos HTTP que impede scripts executados no navegador (como JavaScript) de lerem o conteúdo do cookie, neutralizando roubos de sessão via XSS.
- CSRF (Cross-Site Request Forgery)
- Tipo de ataque onde comandos maliciosos são transmitidos a partir de um usuário em quem a aplicação web confia, mitigado pelo uso de tokens sincronizados e SameSite cookies.
- JWT (JSON Web Token)
- Padrão aberto que define uma maneira compacta e autossuficiente para transmitir informações seguras entre partes como um objeto JSON codificado digitalmente.
- RBAC (Role-Based Access Control)
- Mecanismo de controle de acesso que restringe permissões de sistema com base nos papéis ou funções atribuídos a cada usuário na organização (ex.: Admin, Gestor, Entregador).
- Sessão Opaca
- Modelo de autenticação onde o cliente recebe apenas uma sequência aleatória de caracteres sem significado interno; os dados e privilégios do usuário ficam armazenados com segurança no banco de dados do servidor.
- XSS (Cross-Site Scripting)
- Vulnerabilidade em aplicações web que permite a invasores injetarem scripts maliciosos no navegador de outros usuários.