arcadiasuite/migrations/README_RLS.md

3.3 KiB

Migrações RLS - Row Level Security

Esta pasta contém as migrações para habilitar Row Level Security (RLS) no PostgreSQL, garantindo isolamento de dados entre tenants (multi-tenancy).

Arquivos

Arquivo Descrição
001_enable_rls.sql Habilita RLS em todas as tabelas com tenant_id
002_create_policies.sql Cria políticas CRUD por tenant
003_tenant_context.sql Funções de contexto e triggers de validação

Como Aplicar

Opção 1: Aplicar via psql (Produção)

# Configurar variáveis de ambiente
export DATABASE_URL="postgresql://user:pass@host:5432/arcadia"

# Aplicar migrações
psql $DATABASE_URL -f migrations/001_enable_rls.sql
psql $DATABASE_URL -f migrations/002_create_policies.sql
psql $DATABASE_URL -f migrations/003_tenant_context.sql

Opção 2: Aplicar via script Node.js

npm run db:apply-rls

(Nota: este script precisa ser criado no package.json)

Opção 3: Aplicar via Docker

docker exec -i arcadia-db psql -U arcadia -d arcadia < migrations/001_enable_rls.sql
docker exec -i arcadia-db psql -U arcadia -d arcadia < migrations/002_create_policies.sql
docker exec -i arcadia-db psql -U arcadia -d arcadia < migrations/003_tenant_context.sql

Tabelas Protegidas

Productivity & Workspace

  • workspace_pages, quick_notes, activity_feed
  • conversations, knowledge_base, chat_threads, manus_runs

Low-Code / Dev Center

  • arc_doctypes, arc_layouts

Multi-Tenancy Core

  • tenant_empresas, tenant_users, partner_clients, partner_commissions

Process Compass

  • pc_clients, pc_projects, pc_crm_stages, pc_crm_leads
  • pc_crm_opportunities, pc_crm_activities, pc_pdca_cycles, pc_requirements

CRM Expandido

  • crm_partners, crm_contracts, crm_channels, crm_threads
  • crm_quick_messages, crm_campaigns, crm_events, crm_products
  • crm_clients, crm_pipeline_stages, crm_leads, crm_opportunities, crm_proposals

Funções Disponíveis

-- Obter tenant atual do contexto
SELECT get_current_tenant_id();

-- Verificar se é admin
SELECT is_tenant_admin();

-- Setar contexto (deve ser chamado pela aplicação)
SELECT set_tenant_context(1, 'user-uuid', 'member');

-- Verificar acesso
SELECT can_access_tenant('user-uuid', 1);

-- View de resumo
SELECT * FROM tenant_security_summary;

Integração com a Aplicação

O middleware da aplicação deve chamar set_tenant_context após autenticação:

// server/middleware/tenant-context.ts
import { db } from "../db";

export async function setTenantContext(req, res, next) {
  if (req.user?.tenantId) {
    await db.execute(
      sql`SELECT set_tenant_context(${req.user.tenantId}, ${req.user.id}, ${req.user.tenantRole})`
    );
  }
  next();
}

Rollback

Para desabilitar RLS (emergência apenas):

-- Exemplo para uma tabela
ALTER TABLE workspace_pages DISABLE ROW LEVEL SECURITY;
DROP POLICY workspace_pages_tenant_select ON workspace_pages;
-- ... etc

Notas

  • As políticas usam get_current_tenant_id() que lê do contexto da sessão
  • Triggers validam se tenant_id corresponde ao contexto antes de INSERT/UPDATE
  • Tabelas sem tenant_id (users, tenants, profiles) NÃO têm RLS (acesso global)
  • A view tenant_security_summary mostra estatísticas por tenant