6.4 KiB
Correções de Segurança — Sem Impacto em Produção
Objetivo: eliminar todos os erros e warnings listados mantendo 100% do comportamento atual (provisionamento automático, webhooks Railway/Telegram, polling Hermes, painéis admin/usuário). Cada mudança é defensiva: bloqueia chamadas externas não autorizadas, mas mantém os caminhos internos legítimos funcionando ao adicionar um header de segredo compartilhado já configurado.
1. Erros de endpoints abertos (agent_security)
1.1 provision-agent
- Adicionar verificação de header
X-Internal-Secretno topo do handler. - Segredo novo:
INTERNAL_FUNCTION_SECRET(request viaadd_secret). - Atualizar todos os callers internos para enviar o header:
supabase/functions/validate-telegram-bot/index.ts(chamada async)supabase/functions/payments-webhook/index.ts(se chamar)src/routes/admin.*→ painel admin chama viasupabase.functions.invokeautenticado por JWT de admin: aceitar OU JWT de admin OU o segredo.trigger_provision_agent()(função PL/pgSQL via pg_net): adicionar header com o segredo lido dovault.decrypted_secrets.
1.2 railway-webhook
- Adicionar verificação do header
X-Railway-Signature(HMAC SHA-256 do body cru) usando segredoRAILWAY_WEBHOOK_SECRET. - Como Railway pode não estar configurado com webhook signature ainda: modo permissivo controlado — se
RAILWAY_WEBHOOK_SECRETestiver vazio, loga warning e aceita (mantém produção). Quando o usuário configurar o segredo no Railway, valida estritamente.
1.3 managed-bot-webhook
- Validar
X-Telegram-Bot-Api-Secret-TokencontraTELEGRAM_MANAGER_BOT_WEBHOOK_SECRET. - Mesma estratégia permissiva: se segredo não existe, mantém aberto + log (já estava aberto antes; não regride).
1.4 generate-skill-markdown
- Remover
verify_jwt = falsedoconfig.toml(volta ao padrãotrue). - Não é mais chamado por sistemas externos; o painel usa o cliente Supabase autenticado, então JWT vai naturalmente.
1.5 suspend-agent / resume-agent
- Adicionar extração do JWT + checagem
agent.user_id === auth.uid()OUhas_role(uid, 'admin')OU headerX-Internal-Secret(para trigger pg_nettrigger_suspend_or_resume_agent). - Atualizar
trigger_suspend_or_resume_agent()para passar o segredo.
2. Warning: keep-alive-agents
- Adicionar verificação
X-Internal-Secret. Atualizar cron pg_net que invoca (se existir) para enviar o header. Se não houver cron configurado (chamada manual), o admin pode configurar.
3. Warnings de RLS (supabase_lov)
Adicionar policies apenas para service_role em tabelas que já são usadas só pelo backend (não muda comportamento, documenta intenção e silencia o linter):
oauth_state_tokens— policyservice_role ALLpaddle_webhook_events— policyservice_role ALLstripe_webhook_events— policyservice_role ALLtelegram_rate_limit_bucket— policyservice_role ALL
Não adicionar policies novas para user_integrations/vps_pool (warnings informativos sobre design intencional — aceitos como estão, vamos ignorá-los via manage_security_finding com justificativa).
Realtime
- Adicionar policies em
realtime.messagesrestringindo subscribe por tópico:- Tópico de
subscriptions:<user_id>→ apenas seauth.uid() = user_id - Tópico de
telegram_messages_log:<user_id>→ idem
- Tópico de
- Se hoje o frontend não usa nomes de tópico baseados em
user_id, não introduzir — apenas marcar como ignorado documentando que as queries Realtime atuais ainda passam pela RLS da tabela base. Vou verificar uso real antes de aplicar.
4. Warnings Supabase linter
extension_in_public: mover extensões fora depublicquebra muita coisa. Marcar comoignorecom razão "extensãopg_net/vaultinstalada por padrão pelo Supabase, mover requer downtime e não traz ganho real".- SECURITY DEFINER executable: revisar cada função SECURITY DEFINER. As que devem ficar acessíveis (
has_role,has_active_subscription) — REVOKE deanon, manterauthenticated. As de uso interno (vault_*,trigger_*,enforce_*,handle_new_user,cleanup_*) — REVOKE deanoneauthenticated. rls_enabled_no_policy: resolvido pelas policies novas acima.
Detalhes técnicos
Segredos novos a criar
INTERNAL_FUNCTION_SECRET(gerado, 32 bytes hex)RAILWAY_WEBHOOK_SECRET(opcional — modo permissivo até configurar)TELEGRAM_MANAGER_BOT_WEBHOOK_SECRET(opcional — modo permissivo)
Vault entry para o trigger pg_net
Inserir internal_function_secret em vault.secrets para que trigger_provision_agent / trigger_suspend_or_resume_agent leiam e enviem como header.
Arquivos editados
supabase/config.toml(remoververify_jwt = falsede generate-skill-markdown)supabase/functions/provision-agent/index.tssupabase/functions/railway-webhook/index.tssupabase/functions/managed-bot-webhook/index.tssupabase/functions/suspend-agent/index.tssupabase/functions/resume-agent/index.tssupabase/functions/keep-alive-agents/index.tssupabase/functions/validate-telegram-bot/index.ts(adicionar header)- Migration nova: policies service_role, REVOKE de funções SECURITY DEFINER, update das triggers para enviar header.
Rollout em ordem (evita downtime)
- Criar segredos + migration (vault entry + policies + revokes + triggers atualizados).
- Deploy das edge functions com checagem opcional (se segredo ausente, aceita). Isso garante que mesmo se o trigger antigo chamar sem header, continua funcionando durante a janela.
- Após confirmar deploy, próxima migration torna a checagem obrigatória (remove o modo permissivo). Posso fazer isso já se preferir — mas o modo "primeiro permissivo" é mais seguro.
Findings que serão marcadas como ignore (com justificativa em update_memory)
user_integrationswrite policies — intencional, escrita feita só por backendvps_pool— intencional, somente adminextension_in_public— Supabase default
Confirmação necessária
Posso prosseguir com:
- (a) Plano completo, modo permissivo nos webhooks externos (Railway/Telegram manager) até você configurar os segredos lá → zero risco em produção.
- (b) Estrito desde o início (mais seguro, exige configurar Railway/Telegram webhook secrets agora).
Diga (a) ou (b) e eu executo. Se aprovar sem escolher, vou de (a).