Skip to content

feat(security): promove secure-upload de public para authenticated (re-target #68 → main)#72

Merged
adm01-debug merged 1 commit into
mainfrom
claude/harden-secure-upload-authenticated
Apr 30, 2026
Merged

feat(security): promove secure-upload de public para authenticated (re-target #68 → main)#72
adm01-debug merged 1 commit into
mainfrom
claude/harden-secure-upload-authenticated

Conversation

@adm01-debug
Copy link
Copy Markdown
Owner

@adm01-debug adm01-debug commented Apr 30, 2026

🎯 Re-targeted from #68 to main

PR #68 estava stacked sobre claude/fix-secure-upload-authz-logging (que veio de PR #67, já mergeado em main em 29/abr 0a5784e7). Esta PR é o mesmo conteúdo com base = main para permitir merge direto.

Contexto

Promove a edge function secure-upload da categoria public para authenticated no manifest SSOT. Essa edge usa SUPABASE_SERVICE_ROLE_KEY (bypassa RLS) e aceitava chamadas anônimas — vetor de abuso de Storage.

Mudanças

  • supabase/functions/_shared/edge-authz-manifest.ts: category: "public""authenticated"
  • supabase/functions/secure-upload/index.ts: adiciona authenticateRequest(req) no início + reusa auth.localServiceClient

Diff

23+ / 22- em 2 arquivos.

Compat

Caller Comportamento
SecureUploadManager.tsx ✅ idêntico (já manda JWT auto)
ImageUploadButton.tsx ✅ idêntico (já manda JWT auto)
Anônimos hipotéticos 🚫 401 (quebra esperada — vetor fechado)

Validação

Realizada em #68: typecheck, check-edge-authorization (85/85), check-edge-structured-logging, check-edge-request-id-propagation — tudo OK.

Closes #68 (re-targeted).

Summary by CodeRabbit

  • Security
    • The secure-upload feature now requires user authentication; anonymous uploads are no longer available.
    • All upload activities are now logged with user identification for audit purposes.

…ardening)

Fecha vetor onde a edge usa SERVICE_ROLE_KEY mas aceitava chamadas anônimas.

MUDANÇAS

1. edge-authz-manifest.ts
   - secure-upload: public → authenticated
   - rationale atualizado: "exige JWT (uso de SERVICE_ROLE_KEY interno;
     auditoria em file_scan_logs com user_id obrigatório)"

2. secure-upload/index.ts
   - Adiciona authenticateRequest(req) no início do handler
   - Retorna 401 imediato (via authErrorResponse) se anon ou JWT inválido
   - Reusa auth.localServiceClient (já é SERVICE_ROLE) em vez de criar
     supabaseAdmin manualmente
   - Tipo ScanLog.user_id: string | null → string (sempre presente)
   - Eventos do logger agora incluem user_id em todos:
     request_start / security_check_failed / upload_blocked_malware /
     upload_ok / upload_failed
   - Novo evento auth_failed para auditoria de tentativas anônimas

COMPATIBILIDADE

- Callers no frontend (SecureUploadManager, ImageUploadButton) já
  enviam JWT automaticamente via supabase.functions.invoke() —
  sem mudança necessária.
- Body de resposta inalterado para callers autenticados.
- Anônimos antes obtinham 200 com user_id=null no log; agora obtem
  401 com {error: "Token de autenticação ausente"}.

VALIDAÇÃO

- npm run typecheck: 0 erros
- check-edge-authorization: 85/85 (authenticated 24→25, public 22→21)
- check-edge-structured-logging: OK (84 legadas, 1 migrada)
- check-edge-request-id-propagation: OK (9 críticas validadas)

DEPENDS-ON: #67
Copilot AI review requested due to automatic review settings April 30, 2026 13:03
@adm01-debug adm01-debug merged commit fa6be12 into main Apr 30, 2026
7 of 12 checks passed
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 30, 2026

Caution

Review failed

The pull request is closed.

Warning

.coderabbit.yaml has a parsing error

The CodeRabbit configuration file in this repository has a parsing error and default settings were used instead. Please fix the error(s) in the configuration file. You can initialize chat with CodeRabbit to get help with the configuration file.

💥 Parsing errors (1)
Validation error: String must contain at most 250 character(s) at "tone_instructions"
⚙️ Configuration instructions
  • Please see the configuration documentation for more information.
  • You can also validate your configuration using the online YAML validator.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json
ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 482bbcb4-05de-4744-baf4-429215c873e8

📥 Commits

Reviewing files that changed from the base of the PR and between dc01a09 and d85d9d1.

📒 Files selected for processing (2)
  • supabase/functions/_shared/edge-authz-manifest.ts
  • supabase/functions/secure-upload/index.ts

📝 Walkthrough

Walkthrough

This PR promotes the secure-upload edge function from public to authenticated-only access by integrating a shared authentication utility, tightening user_id to a non-nullable type across audit logs, and replacing ad-hoc client instantiation with authenticated context clients for consistency and security.

Changes

Cohort / File(s) Summary
Authorization Manifest Update
supabase/functions/_shared/edge-authz-manifest.ts
Changes secure-upload category from "public" to "authenticated" and updates rationale to specify JWT requirement with internal SERVICE_ROLE_KEY usage and mandatory user_id auditing.
Secure Upload Function
supabase/functions/secure-upload/index.ts
Refactors authentication to use shared authenticateRequest() utility with early rejection of unauthenticated requests; obtains Supabase admin client from authenticated context instead of environment variables; updates ScanLog.user_id from nullable to non-nullable string; ensures all audit logs consistently include user_id for correlation with auth.users.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • #67: Predecessor PR that adds the initial secure-upload manifest entry and structured logging foundation; this PR depends on and builds directly upon those changes to promote authentication from public to authenticated.

Poem

🐰 A hop toward safety, the manifest's changed,
From open to guarded, the access rearranged!
JWT tokens now required to pass through,
Every scan logged with user_id so true.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/harden-secure-upload-authenticated

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
Review rate limit: 0/1 reviews remaining, refill in 60 minutes.

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Promove a edge function secure-upload para exigir autenticação (JWT) no SSOT de autorização, reduzindo o vetor de abuso de Storage causado por chamadas anônimas em uma função que opera com SERVICE_ROLE_KEY.

Changes:

  • Move secure-upload de category: "public" para "authenticated" no edge-authz-manifest.ts.
  • Adiciona autenticação obrigatória via authenticateRequest(req) no início da edge secure-upload.
  • Reaproveita auth.localServiceClient (service-role client) e inclui user_id nos logs/eventos e auditoria.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
supabase/functions/secure-upload/index.ts Passa a exigir JWT via authenticateRequest e registra user_id consistentemente, reutilizando o service client do helper de auth.
supabase/functions/_shared/edge-authz-manifest.ts Reclassifica secure-upload como authenticated no manifest SSOT.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 5 to 8
const corsHeaders = {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Headers": "authorization, x-client-info, apikey, content-type",
};
@adm01-debug adm01-debug deleted the claude/harden-secure-upload-authenticated branch May 9, 2026 21:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants