Skip to content

Log de Riscos Aceitos — Plataforma OLP

Findings de scanner que NÃO serão remediados tecnicamente por decisão de produto/jurídico/negócio. Cada item exige reavaliação periódica.

Não confunda com SILENT_DATA_LOSS_AUDIT.md (bugs silenciosos) nem RLS_POLICIES.md §Pendências (remediação programada).


RA-001 — Vínculo cross-escola de responsável via portal

CampoValor
Finding origeminscricoes_portal_responsavel_scope (supabase_lov, level: error)
Tabelaaluno_responsaveis (INSERT via portal_responsavel_auto_vincular)
Aceito em2026-05-08
ReavaliaçãoApós retorno do alinhamento jurídico LGPD (em andamento)
OwnerProduto + Jurídico

Risco descrito pelo scanner

Sem WITH CHECK validando escola_id do aluno contra o JWT do responsável, um responsável autenticado pode se vincular a aluno de qualquer escola se conhecer matrícula + data de nascimento.

Por que é aceito hoje (decisão de produto)

É feature real, não bug. Um responsável pode legitimamente ter filhos em escolas diferentes, e o portal hoje opera com identidade global de responsável (vide architecture/identidade-global-responsavel). A informação necessária (matrícula + DN) é considerada conhecimento privilegiado do responsável real.

Mitigações em vigor (não remover sem substituir)

  • Rate limit em portal-responsavel-auto-vincular (escola + IP, via portal_check_guards).
  • OTP exigido para login portal.
  • Lockouts incrementais em portal_login_tentativas.
  • Leitura subsequente do responsável passa por get_alunos_responsavel() / responsavel_vinculado_aluno() — escopo é por responsavel_id, não por escola_id. A feature não vaza dados de outros alunos da mesma escola.
  • Mural por escola usa get_mural_publicacoes_responsavel_global() que já valida vínculo aluno_responsaveis antes de retornar.

Gatilhos para reabrir

  • Decisão jurídica de exigir prova adicional de parentesco (ex.: documento, autorização da escola).
  • Incidente de enumeração massiva detectado em portal_login_tentativas ou portal_rate_metrics.
  • Mudança de modelo: cada escola passar a gerenciar a lista de responsáveis (vínculo deixaria de ser auto-serviço).

Backlog técnico (quando reabrir)

  • Adicionar WITH CHECK em aluno_responsaveis exigindo que aluno_id pertença a alguma escola onde o responsável já tenha vínculo prévio aprovado, OU
  • Criar fluxo de aprovação assíncrono (responsável solicita, gestor escola confirma).
  • Reduzir teto diário de novos vínculos por responsavel_id (ex.: 5/dia) como guard de enumeração.

RA-002 — nivel_id IS NULL é válido em olimpíadas modo uniforme

CampoValor
Tabelasfases_olimpiada, inscricoes_olimpiada, importacao_resultados_sessoes, mural_dados_publicados, mural_liberacoes
Aceito em2026-05-27
ReavaliaçãoAnual (revisar se modo uniforme ainda existe)
OwnerProduto + Backend

Contexto

Após mudança de ON DELETE SET NULLON DELETE RESTRICT em FKs para niveis_competicao (2026-05-27), nivel_id IS NULL deixou de ser estado transiente pós-delete. Porém, permanece semanticamente válido quando olimpiadas.modo_config_fases = 'uniforme': nessas olimpíadas não há níveis, então fases/inscrições/sessões legitimamente têm nivel_id = NULL.

Estado pós-limpeza (2026-05-27)

  • fases_olimpiada: 50/53 NULL legítimos (uniforme), 3 órfãos reais deletados.
  • inscricoes_olimpiada: 0 órfãos reais (1 cancelado preservado).
  • importacao_resultados_sessoes: 11/11 NULL legítimos (todos OBB uniforme).

O que NÃO fazer

  • ❌ Adicionar CHECK (nivel_id IS NOT NULL) ou NOT NULL nas colunas — quebraria modo uniforme.
  • ❌ Filtrar WHERE nivel_id IS NULL em queries de cleanup sem JOIN com olimpiadas.modo_config_fases.
  • ❌ Tratar todo NULL como bug em auditorias futuras.

Backlog técnico (follow-up opcional)

  • Trigger cross-table garantindo: INSERT/UPDATE com nivel_id IS NULL só passa se a olimpíada estiver em modo uniforme. Bloqueador hoje: custo de leitura por linha.

Refs

  • Plano: .lovable/plan.md
  • Migration: supabase/migrations/20260527*cleanup_niveis_competicao_orphans*.sql
  • Comentários SQL aplicados nas colunas nivel_id das 5 tabelas
  • Memory: mem://architecture/olympics-phases-by-level-standard
  • Audit report: docs/audits/AUDIT_NIVEIS_RESTRICT_2026-05-27.md

Convenções

  • Toda entrada precisa: ID RA-NNN, finding origem, data de aceite, owner, reavaliação.
  • Marcar finding correspondente como ignore no scanner com reason referenciando o ID desta tabela.
  • Atualizar memory mem://security/<feature>-accepted-risk para o agente não tentar "corrigir" automaticamente.