Segurança e Auditoria
Entenda como o sistema protege os dados com Row Level Security, logs de auditoria e boas práticas de segurança.
O Que É RLS (Row Level Security)#
Row Level Security é um mecanismo do PostgreSQL que permite definir regras de acesso no nível de linhas da tabela. Cada query executada pelo Supabase passa automaticamente por essas regras, garantindo que o usuário só veja os dados permitidos.
Por que RLS é essencial
- Protege dados no nível do banco — mesmo com bug no frontend, os dados ficam protegidos
- Garante que operadores só vejam tickets das filas permitidas
- Previne acesso não autorizado via API direta
- É obrigatório por segurança e LGPD
Como funciona
Quando o Supabase recebe uma query do cliente, o PostgreSQL automaticamente adiciona um filtro WHERE baseado nas políticas RLS ativas. O frontend nunca precisa desses filtros — eles são transparentes.
Funções Helper do RLS#
get_user_role()
Retorna o papel (role) do usuário autenticado. Usada nas policies para aplicar regras diferentes por papel.
CREATE POLICY "Managers can see all tickets" ON tickets
FOR SELECT USING (get_user_role() = 'manager');
is_admin_manager()
Retorna true se o usuário logado é admin ou manager. Usada para permitir bypass de filtros de fila em dashboards gerenciais.
CREATE POLICY "Admin manager bypass" ON tickets
FOR SELECT USING (is_admin_manager() = true);
Políticas RLS Ativas por Tabela#
| Tabela | SELECT | INSERT | UPDATE | DELETE |
|---|---|---|---|---|
| tickets | Filas do usuário + admin | Sistema | Assignee + gestor | Apenas admin |
| ticket_messages | Filas do usuário + admin | Membro da fila | Nenhum | Apenas admin |
| ticket_comments | Filas do usuário + admin | Membro da fila | Author | Apenas admin |
| ticket_history | Filas do usuário + admin | Sistema | Nenhum (imutável) | Nenhum (imutável) |
| profiles | Próprio perfil + admin | Próprio perfil | Próprio perfil + admin | Apenas admin |
| queues | Todos autenticados | Apenas admin | Apenas admin | Apenas admin |
| email_accounts | Apenas admin | Apenas admin | Apenas admin | Apenas admin |
| agents | Apenas admin | Apenas admin | Apenas admin | Apenas admin |
| audit_log | Apenas admin | Sistema | NENHUM | NENHUM |
Logs de Auditoria#
Toda mudança em tickets e dados do sistema é registrada na tabela ticket_history com informações detalhadas sobre quem fez o quê.
Ticket #000042 — status: "open" → "in_progress"
Ator: Pedro Santos (pedro@endotech.com.br)
Ticket #000042 — queue_id: "Triagem" → "Faturamento"
Ator: Classificador Faturamento (conf: 0.92)
Ticket #000042 — created: novo ticket a partir de e-mail
Ator: workflow-email-processor
Ticket #000042 — assignee_id: null → "Pedro Santos"
Ator: Pedro Santos (assumiu o ticket)
Tipos de ator (actor_type)
- user: Ação manual de um operador, coordenador, gestor ou admin
- system: Ação automática do backend (ex: atribuição automática)
- ai: Ação do agente de IA (classificação, extração)
- n8n: Ação do workflow n8n (criação de ticket, processamento)
Dados registrados
- Timestamp, ator, ação, valores antigo/novo
- IP address e user agent (para ações de usuário)
- old_data e new_data em JSONB para dados complexos
Chaves de API: service_role vs anon#
⚠️ service_role key
A service_role key bypassa TODAS as policies RLS. Tenha extremo cuidado ao usá-la.
- NUNCA exponha no browser (código client-side)
- Use APENAS em server-side (Route Handlers, Server Actions)
- Use para operações de sistema (n8n, processamento de e-mail)
- Rotacione periodicamente se houver suspeita de vazamento
✓ anon key
A anon key é segura para uso no browser, pois passa por todas as policies RLS.
- Segura para client-side (browser)
- Sujeita a todas as policies RLS
- Usuário precisa estar autenticado para acessar dados
Variáveis de Ambiente#
https://x•••••.supabase.co
eyJhbGciOiJIUzI1NiIs•••••
eyJhbGciOiJIUzI1NiIs•••••
smtp.gmail.com
587
atendimento@endotech.com.br
Senha de app (16 caracteres)
imap.gmail.com
sk-••••••••••••••••
Boas Práticas de Segurança#
1. Nunca exponha service_role no browser
Sempre use createClient do @supabase/ssr no server e createBrowserClient no browser. O client do browser usa a anon key por padrão.
2. Valide todos os inputs
Nunca confie em dados do client. Valide em Server Actions e Route Handlers usando Zod ou validação manual.
3. Use queries parametrizadas
Supabase client usa queries parametrizadas por padrão, mas se usar SQL raw, sempre use placeholders para prevenir SQL injection.
4. Princípio do menor privilégio
Crie usuários com o papel mínimo necessário. Se um operador precisa ser gestor temporariamente, altere e reverta depois.
5. Revise acessos periodicamente
Semanalmente, verifique lista de administradores e permissões de filas. Desative contas sem login há mais de 30 dias.
6. Rotacione senhas de API
Troque senhas de app de e-mail e chaves de API periodicamente (a cada 90 dias). Mantenha registro da última rotação.
Conformidade LGPD#
Dados pessoais tratados
- Nome e e-mail de clientes (contido nos e-mails)
- Nome, e-mail e papel de usuários internos
- IPs de acesso (audit_log)
Direitos do titular
- Acesso: Cliente pode solicitar seus dados via e-mail
- Retificação: Admin pode corrigir dados do perfil
- Exclusão: Admin pode deletar tickets e dados vinculados
- Portabilidade: Exportar dados via Supabase CSV
Medidas implementadas
- RLS protege dados de acesso não autorizado
- Audit log registra todas as ações para rastreabilidade
- Política de retenção define prazos de armazenamento
- Senhas de app e chaves API rotacionadas periodicamente
- Sessões com expiração automática (JWT)
Política de Senhas e Sessões#
Autenticação
O sistema usa magic links para autenticação. Não há senhas tradicionais — o usuário recebe um link por e-mail que expira em 24 horas. Admins podem gerar novos magic links a qualquer momento.
Sessões
JWT com expiração configurável (padrão: 1 hora). O Supabase gerencia refresh tokens automaticamente. Sessões são invalidadas ao desativar o usuário.
Verificação em 2 etapas
Recomendado para contas de administrador. Pode ser habilitado no Supabase Dashboard → Authentication → Providers.
✅ Resumo
- ✓ RLS protege dados no nível do banco de dados
- ✓ get_user_role() e is_admin_manager() são os helpers de RLS
- ✓ audit_log é imutável — INSERT apenas
- ✓ actor_type: user, system, ai, n8n
- ✓ service_role key NUNCA no browser, apenas server-side
- ✓ Nunca commite .env.local no git
- ✓ Princípio do menor privilégio ao criar usuários
- ✓ Conformidade LGPD: acesso, retificação, exclusão, portabilidade