DevGuideTK
← Trilha Backend

Armazenamento de objetos

Onde guardar arquivos, com URLs assinadas e envio direto do navegador.

As decisões sobre arquivos são cinco: onde guardar, como receber, como entregar, como proteger e como organizar o ciclo de vida.

Onde guardar

OpçãoBom paraCuidados
Serviço de nuvem (S3, Cloud Storage, Azure Blob)A maioria dos sistemasCusto de saída de dados (transferência para a internet)
Compatíveis sem custo de saída (Cloudflare R2, Backblaze B2)Muito download, como mídia e arquivos públicosRecursos e regiões diferentes do S3
Servidor próprio compatível com S3 (Ceph, SeaweedFS, Garage)Infraestrutura própria, exigências de localização dos dadosOperar o armazenamento, inclusive a durabilidade
Disco do servidorArquivos temporários de processamentoNunca como armazenamento definitivo
Banco de dadosArquivos minúsculos e poucos, que precisam de transação com os dadosBanco e backups maiores

Programe contra a API do S3: os SDKs funcionam com quase todos os serviços, trocando o endereço, como os exemplos da Implementação fazem.

Como receber arquivos

FormaComo funcionaQuando usar
Pela aplicação, em memóriaA aplicação recebe o arquivo inteiro e depois enviaArquivos pequenos e poucos; ainda assim, limite o tamanho
Pela aplicação, em fluxoA aplicação repassa as partes conforme chegamQuando precisa inspecionar ou transformar no caminho
Direto, com URL assinada por PUTO navegador envia direto, com o tipo fixadoArquivos sem limite rígido de tamanho
Direto, com POST e políticaO navegador envia um formulário com condições assinadas: tipo, prefixo da chave, faixa de tamanhoQuando o tamanho precisa de limite (fotos, documentos)
Envio em partes (multipart upload)O arquivo vai em partes, que podem ser reenviadas sozinhasArquivos grandes, acima de dezenas de MB, e conexões instáveis

No teste do nível Conceito, repassar 300 MB pela aplicação custou 716 MB de memória em memória e 139 MB em fluxo; o envio direto não custa nada à aplicação.

Depois do envio direto, a aplicação não sabe o que chegou. Ela confere o objeto (existência, tamanho, tipo) antes de registrar, e pode processá-lo numa tarefa em segundo plano: gerar miniaturas, conferir se a imagem é mesmo uma imagem, procurar vírus.

Como entregar arquivos

FormaQuando usarCuidados
URL assinada de downloadArquivos privados: notas fiscais, documentos, anexosValidade curta, gerada a cada acesso autorizado
CDN na frente de um bucket privadoArquivos públicos muito acessados: imagens de produtosA CDN acessa o bucket com credencial própria; o bucket continua privado
Bucket públicoQuase nuncaTudo o que for gravado lá fica exposto, inclusive por engano
Pela aplicaçãoQuando a autorização precisa ser conferida a cada byte, ou o arquivo é gerado na horaA aplicação carrega o tráfego inteiro

Como proteger

RiscoDefesa
Upload de HTML ou SVG servido como página do seu domínio (XSS armazenado)Tipo fixado na assinatura, download com Content-Disposition: attachment, arquivos de usuários num domínio separado
Arquivos enormes enchendo o armazenamento e a contaPOST com content-length-range, ou conferência do tamanho depois do envio
Chaves adivinháveis (notas/1.pdf, notas/2.pdf)Chave gerada pela aplicação, com identificador aleatório; autorização antes de gerar a URL
URLs assinadas compartilhadas e reutilizadasValidade curta: minutos para envio, minutos a horas para download
Bucket público por enganoBloqueio de acesso público na conta (S3 Block Public Access e equivalentes)
Credenciais na aplicação vazandoPapéis da nuvem (IAM) em vez de chaves fixas, com permissão só no bucket e nas operações necessárias
Arquivo com conteúdo maliciosoConferir o tipo real pelo conteúdo, não pela extensão; antivírus para arquivos que outros usuários vão abrir

Um domínio separado para os arquivos de usuários (como usercontent.exemplo.com) é a defesa mais forte contra XSS por upload: mesmo que um HTML seja aberto no navegador, ele não tem acesso aos cookies do domínio principal.

Ciclo de vida

ConfiguraçãoPara quê
Classes de armazenamento (frequente, infrequente, arquivo)Arquivos antigos e pouco lidos custam menos em classes mais frias
Regras de ciclo de vidaMover para classes frias depois de N dias; apagar arquivos temporários; apagar envios em partes abandonados
VersionamentoRecuperar arquivos apagados ou sobrescritos por engano
Bloqueio de objeto (object lock)Backups que nem um administrador consegue apagar antes do prazo, contra ransomware
Replicação entre regiõesRecuperação de desastres

Os envios em partes que nunca foram concluídos ficam guardados e cobrados, invisíveis numa listagem comum. Uma regra de ciclo de vida que os apaga depois de alguns dias evita a surpresa na conta.

Resumo da decisão

  1. Armazenamento de objetos para os arquivos; o banco guarda só os dados sobre eles.
  2. Envio direto do navegador, com URL assinada que fixa o tipo, ou POST com política que também limita o tamanho.
  3. Bucket privado, com URLs assinadas de validade curta ou CDN com credencial própria.
  4. Download como anexo e domínio separado para arquivos de usuários.
  5. Chaves geradas pela aplicação, com autorização antes de cada URL.
  6. Regras de ciclo de vida, versionamento onde importa, e papéis da nuvem no lugar de chaves fixas.

O próximo nível mostra a geração de URLs de envio e de download nas cinco linguagens, com os SDKs oficiais.

Prompts para aprofundar

Ao abrir no ChatGPT ou no Claude, o prompt é enviado ao serviço escolhido pela URL e também fica copiado na sua área de transferência.

  • Desenhar o upload de arquivos do meu sistema

    Quero desenhar o envio e a entrega de arquivos no meu sistema.
    
    Pergunte quais arquivos são enviados, os tamanhos, quem pode ver cada um, se há processamento depois (miniaturas, antivírus) e qual nuvem ou armazenamento eu uso.
    
    Proponha:
    1. A forma de envio, com o fluxo completo.
    2. O que a assinatura fixa (tipo, tamanho, chave).
    3. Como os arquivos são entregues (URL assinada, CDN), com as validades.
    4. As defesas contra XSS por upload.
    5. O que a tabela do banco guarda sobre cada arquivo.
  • Configurar um bucket com segurança

    Quero configurar um bucket do zero, com segurança.
    
    Pergunte qual serviço eu uso e para que o bucket serve.
    
    Monte comigo:
    1. O bloqueio de acesso público.
    2. A permissão mínima para a aplicação, com papéis em vez de chaves fixas.
    3. A regra de CORS para o envio direto do navegador.
    4. O versionamento e as regras de ciclo de vida, inclusive para envios em partes abandonados.
    5. A criptografia e os registros de acesso.
  • Escolher onde guardar arquivos

    Estou escolhendo onde guardar os arquivos do meu sistema.
    
    Pergunte o volume, quanto é baixado por mês, se os arquivos são públicos ou privados, exigências de localização dos dados e se prefiro serviço gerenciado ou infraestrutura própria.
    
    Compare para o meu caso S3, Cloud Storage, Azure Blob, Cloudflare R2, Backblaze B2 e um servidor próprio compatível com S3, quanto a custo de armazenamento, custo de saída, recursos e operação. Recomende uma opção.