O que é uma URL pré-assinada?
Uma URL pré-assinada concede autorização por tempo limitado para uma operação específica de armazenamento, como fazer download ou upload de um único objeto, sem fornecer ao destinatário as credenciais secretas de quem a assinou. Sua assinatura fixa a operação, o objeto e o prazo de validade.
Como funcionam as URLs pré-assinadas
Um serviço de pré-assinatura calcula uma assinatura sobre uma solicitação de armazenamento usando as credenciais que possui e coloca os dados de autorização resultantes na string de consulta da URL. O serviço de armazenamento calcula a assinatura novamente quando a URL é usada e verifica o método, o objeto, os cabeçalhos assinados e o prazo de validade, de modo que o segredo nunca precise chegar ao navegador ou ao cliente de download. A solicitação é executada com a autoridade de quem a assinou: o Amazon S3 afirma que uma URL pré-assinada usa as credenciais da entidade principal que a gerou e é limitada pelas permissões dessa entidade. O Amazon S3 chama essas URLs de URLs pré-assinadas, o Google Cloud Storage as chama de URLs assinadas e o equivalente no Azure Storage é a Shared Access Signature (SAS). Os detalhes específicos de armazenamento nesta entrada vêm da documentação desses três serviços; para um serviço compatível com S3 de outro provedor, consulte a documentação do próprio provedor. Uma URL assinada de CDN é um mecanismo diferente: a CDN a verifica com base nas chaves configuradas na CDN, e o serviço de armazenamento não participa dessa verificação. Em uma arquitetura de entrega, uma URL pré-assinada cria um caminho direto e temporário entre um cliente e o armazenamento de objetos, enquanto a aplicação decide quem recebe uma.
Informações essenciais
- Quem pode usar uma URL pré-assinada? Qualquer pessoa que tenha a URL completa, até que ela deixe de ser válida. A AWS descreve URLs pré-assinadas como tokens bearer, e o Google afirma que qualquer pessoa de posse de uma URL assinada pode usá-la enquanto estiver ativa, com ou sem uma conta. Uma URL pré-assinada do S3 pode ser usada repetidamente até expirar. Uma maneira de encerrar o acesso antecipadamente é invalidar o recurso usado para assinar a URL, o que encerra a validade de todas as URLs assinadas com ele: uma URL do S3 deixa de funcionar quando a credencial usada na assinatura é revogada, excluída ou desativada, e uma URL assinada do Google, quando a chave de assinatura é rotacionada. Outros controles dependem do serviço. Uma URL pré-assinada do S3 é limitada pelas permissões de quem a assinou, e a AWS inclui uma política de bucket que nega explicitamente o acesso ao objeto entre as causas de uma resposta 403 Forbidden a uma URL pré-assinada. Assim, essa negação impede solicitações dentro do escopo da política sem invalidar a credencial. O Azure recomenda associar uma SAS de serviço a uma política de acesso armazenada para que ela possa ser revogada sem regenerar as chaves da conta.
- Por que uma URL pré-assinada deixaria de funcionar antes do prazo de validade informado? Porque ela só é válida enquanto as credenciais usadas para assiná-la também forem. A AWS documenta que uma URL do S3 assinada com credenciais temporárias, como as de uma função assumida ou de uma função de instância ou contêiner, expira quando essas credenciais expiram, mesmo que uma validade mais longa tenha sido solicitada, e as solicitações passam a falhar com
ExpiredToken. Verifique o prazo de validade das credenciais de assinatura antes de prometer um prazo de validade para o link: a AWS permite definir a duração máxima da sessão de uma função do IAM assumida por meio de seu console, CLI ou API entre 1 e 12 horas (1 hora, a menos que um valor seja definido) e descreve as credenciais de funções de instância e contêiner como tendo uma duração típica de até cerca de 6 horas, enquanto as credenciais de um usuário do IAM podem assinar uma URL do S3 válida por até 7 dias com Signature Version 4. As soluções indicadas pela AWS são renovar as credenciais e gerar uma nova URL ou, quando apropriado, assinar com credenciais de maior duração. O S3 verifica a validade quando uma solicitação começa: um download iniciado antes do prazo continua, mas uma solicitação reiniciada após o prazo falha. - Por que uma URL que ainda não expirou falha com um erro de assinatura? A solicitação não corresponde mais ao que foi assinado. No S3, o método HTTP, os cabeçalhos assinados e a string de consulta devem corresponder exatamente entre a geração da URL e seu uso. Uma URL do S3 assinada com Signature Version 4 lista seus cabeçalhos assinados em
X-Amz-SignedHeaders, e a AWS exige que o cabeçalho host e todos os cabeçalhosx-amz-*enviados com a solicitação estejam entre eles. A AWS inclui um tipo de conteúdo diferente daquele informado no momento da assinatura entre as causas deSignatureDoesNotMatch, junto com uma URL modificada, a região incorreta, a defasagem do relógio na máquina que assina e proxies que alteram cabeçalhos ou strings de consulta. As URLs assinadas do Google indicam emX-Goog-SignedHeadersos cabeçalhos que uma solicitação deve incluir. - Por que uma URL pré-assinada válida falha no JavaScript do navegador? A autorização do serviço de armazenamento e o CORS são verificações separadas. A configuração de CORS do bucket deve permitir a origem da página, o método HTTP e os cabeçalhos da requisição; o Amazon S3 observa que as ACLs e as políticas continuam se aplicando quando o CORS está habilitado. Quando a configuração não permite uma requisição, o navegador interrompe a operação em uma verificação preflight malsucedida, antes de enviar a requisição efetiva, ou, se a requisição não exigir preflight (o que pode ocorrer com um POST com um tipo de conteúdo de formulário), envia a requisição e impede que o script acesse a resposta. Portanto, um erro de CORS por si só não demonstra que nenhum upload foi feito. Como o CORS restringe requisições entre origens feitas por scripts em um navegador, a mesma URL pode funcionar em um cliente do lado do servidor e falhar em uma página web.
- Uma URL pré-assinada de upload limita o que pode ser enviado? Apenas o que foi assinado. Uma URL pré-assinada do S3 para upload é criada a partir de um bucket, uma chave de objeto, um método HTTP e um prazo de validade. Fazer upload para uma chave que já existe substitui o objeto. O Azure alerta que um cliente com acesso de gravação pode fazer upload de um blob muito grande (o exemplo apresentado é de 200 GB) e recomenda validar os dados depois de gravá-los e antes de usá-los. Quando o serviço de armazenamento precisa impor um limite de tamanho, uploads POST baseados em formulário são o recurso documentado: o documento de política assinado aceita uma condição
content-length-rangeno Google Cloud Storage e no Amazon S3, e o AWS SDK for Python cria esse tipo de formulário assinado comgenerate_presigned_post. O limite do próprio serviço de armazenamento para uma única requisição continua se aplicando: um upload por uma URL pré-assinada do S3 usa PUT, o Amazon S3 documenta um máximo de 5 GB para um único PUT, e objetos maiores usam upload multipartes, no qual o objeto é enviado em partes. A referência de POST Object do Amazon S3 não informa um limite de tamanho para um único POST, portanto, teste um upload baseado em formulário com o maior arquivo esperado antes de depender desse recurso.
Quando as URLs pré-assinadas são importantes
Emita uma para uploads diretos pelo navegador ou downloads privados quando o tráfego não deve passar pelo servidor da aplicação. Uma validade excessiva, operações permissivas ou o vazamento da URL podem expor o objeto referenciado até a expiração.
Como a Transloadit ajuda com URLs pré-assinadas
A Transloadit pode retornar URLs pré-assinadas de download para arquivos que exporta para o Amazon S3. Definir sign_urls_for no Robot /s3/store adiciona signed_url e signed_ssl_url ao resultado, usando o valor do parâmetro como prazo de validade em segundos. As URLs são assinadas com as credenciais da AWS que você fornece ao Robot, por isso a documentação exige que essa identidade tenha permissão de leitura dos objetos, além da permissão de gravação usada para o upload.
Uma URL retornada por /s3/store não torna público um objeto privado, mas o parâmetro acl do Robot tem public-read como valor padrão. Para um bucket privado, a documentação orienta definir acl como bucket-default, não fornecer cabeçalhos de ACL nem de concessão de permissões e manter o S3 Block Public Access habilitado. O Robot não renova credenciais temporárias da AWS, e a AWS documenta que uma URL pré-assinada expira junto com as credenciais usadas para assiná-la, portanto, compare a validade delas com o valor de sign_urls_for. A Signature Authentication da Transloadit e as URLs assinadas do Smart CDN são mecanismos separados que usam seu Auth Secret da Transloadit, e não suas credenciais de armazenamento.
Fontes
- Amazon S3: baixar e fazer upload de objetos com URLs pré-assinadas
- Amazon S3: fazer upload de objetos com URLs pré-assinadas
- Amazon S3: fazer upload de objetos (limites de tamanho para um único PUT e para upload multipartes)
- Amazon S3: autenticar requisições usando parâmetros de consulta (cabeçalhos assinados em uma URL pré-assinada)
- Amazon S3: política de POST e suas condições
- Amazon S3: POST Object (uploads baseados em formulário)
- AWS IAM: duração máxima da sessão para uma função
- Google Cloud Storage: URLs assinadas
- Google Cloud Storage: assinaturas e documentos de política
- Azure Storage: visão geral e boas práticas de Shared Access Signature (SAS)
- Amazon S3: usar o compartilhamento de recursos entre origens (CORS)
- MDN: compartilhamento de recursos entre origens (CORS)
- AWS SDK for Python (Boto3): generate_presigned_post e suas condições de política
- Amazon CloudFront: como funcionam as URLs assinadas (URLs assinadas de CDN, para comparação)