Objetivos de aprendizaje
Después de leer este artículo podrás:
- Entender cómo una URL prefirmada da acceso sin login
- Generar una URL prefirmada de descarga y de subida en Python
- Saber cuándo usar una URL prefirmada y cuándo un enlace revocable
En esta página
Imagina que guardas facturas, contratos o fotos de usuarios en un storage privado. Nadie de afuera debe abrirlos, pero de vez en cuando un usuario necesita descargar el suyo. No quieres crearle una cuenta en el storage ni hacer pasar el archivo por tu servidor.
La URL prefirmada resuelve eso: entrega un enlace que funciona por poco tiempo y solo para ese archivo. En inglés se llama presigned URL (también signed URL o pre-signed URL). Amazon S3 y Google Cloud Storage la ofrecen, y Azure Blob Storage tiene un equivalente llamado shared access signature (SAS).
¿Cómo funciona una URL prefirmada?#
Una URL prefirmada es una URL normal con parámetros extra en la query string. Indican el archivo, el método HTTP (GET para descargar, PUT para subir) y hasta cuándo vale el enlace. El último parámetro es la firma: un hash calculado con una clave secreta que solo conoce el dueño del storage.
Cuando alguien abre el enlace, el storage repite el cálculo con los mismos datos. Si la firma coincide y el plazo no venció, entrega el archivo. Si alguien cambia el nombre del archivo o alarga el plazo en la URL, la firma deja de coincidir y la petición se rechaza.
Dos detalles importan en la práctica:
- La URL lleva la autoridad de quien la generó. En Amazon S3 la URL usa las credenciales del usuario que la firmó. Quien recibe el enlace no necesita credenciales ni permisos.
- Firmar no llama al storage. Tu backend firma de forma local, sin red. Solo quien abre el enlace habla con el storage.
¿Para qué sirve una URL prefirmada?#
- Descargar un archivo privado: el usuario autenticado hace clic en "descargar factura" y recibe un enlace que vale unos minutos.
- Subir directo desde el navegador: la app genera una URL de PUT y el navegador envía el archivo al storage. El archivo no pasa por tu servidor, lo que ahorra ancho de banda y memoria.
- Enviar un archivo a terceros: un socio necesita recibir un informe una vez, sin cuenta ni contraseña.
- Contenido protegido: imágenes o videos que solo ven los usuarios de pago.
¿Cómo generar una URL prefirmada en Python?#
El ejemplo usa boto3, el SDK de AWS para Python, que también funciona con storages compatibles con S3. Instálalo con pip install boto3 requests. Las credenciales vienen de variables de entorno, nunca del código.
import os
import boto3
import requests
from botocore.config import Config
s3 = boto3.client(
"s3",
region_name=os.environ.get("S3_REGION", "us-east-1"),
endpoint_url=os.environ.get("S3_ENDPOINT"), # omítelo en AWS S3; defínelo en otro storage compatible con S3
aws_access_key_id=os.environ["S3_ACCESS_KEY"],
aws_secret_access_key=os.environ["S3_SECRET_KEY"],
config=Config(signature_version="s3v4"),
)
download_url = s3.generate_presigned_url( # descarga, vale 10 minutos
ClientMethod="get_object",
Params={"Bucket": "mi-bucket", "Key": "facturas/2026-10.pdf"},
ExpiresIn=600,
)
upload_url = s3.generate_presigned_url( # subida, vale 5 minutos
ClientMethod="put_object",
Params={"Bucket": "mi-bucket", "Key": "uploads/foto.jpg"},
ExpiresIn=300,
)
print(requests.get(download_url).status_code) # 200
with open("foto.jpg", "rb") as f:
print(requests.put(upload_url, data=f).status_code) # 200Si omites ExpiresIn, boto3 usa 3600 segundos (1 hora). El método HTTP de la petición debe ser el mismo para el que se generó la URL: una URL de GET no sirve para PUT.
Para probar sin Python, copia la download_url y ejecuta curl -o factura.pdf "<url>". Las comillas son obligatorias porque la URL tiene varios &.
¿Cuánto dura una URL prefirmada y se puede revocar?#
El plazo lo defines tú, dentro del límite del storage. En Amazon S3, la documentación oficial da estas cifras: hasta 12 horas si el enlace se crea en la consola, y hasta 7 días con el SDK o la CLI usando credenciales de usuario IAM. Con credenciales temporales, como las de un rol, la URL expira junto con ellas aunque hayas pedido más tiempo. Los 7 días valen para la firma SigV4; otros storages tienen topes propios (Google Cloud Storage también admite como máximo 7 días).
Revocar es el punto débil. La URL no queda registrada en ningún lugar: vale por su firma, y no hay un botón para cancelar un enlace concreto. Las opciones reales son desactivar o borrar la credencial usada para firmar (lo que invalida todas las URL firmadas con ella), borrar o mover el archivo, o usar un mecanismo de enlace revocable en lugar de una URL prefirmada.
Por eso la regla práctica es generar URL de vida corta en el momento en que el usuario las pide y nunca guardar la URL ya hecha en la base de datos.
¿Qué precauciones de seguridad tomar?#
- Trata la URL como una contraseña. Quien la tenga accede al archivo. Mantenla fuera de logs, analytics y mensajes públicos.
- Usa plazos cortos. Minutos para una descarga en pantalla, algo más para subir archivos grandes.
- Limita los permisos de quien firma. Una URL solo puede lo que puede la credencial que la firmó. Usa una credencial restringida al bucket necesario.
- Valida la subida después. Una URL de PUT acepta lo que se envíe. Revisa tamaño y tipo del archivo en tu backend tras el envío, o usa un POST prefirmado (
generate_presigned_post), que acepta condiciones de tamaño y de tipo de contenido. - Mantén el reloj sincronizado. Un reloj desfasado puede invalidar la firma y causar errores como
SignatureDoesNotMatchen S3. Sincroniza el servidor con NTP.
¿URL prefirmada o enlace para compartir: cuál usar?#
| URL prefirmada | Enlace para compartir | |
|---|---|---|
| Validez | Corta, definida al crearla | Más larga |
| Revocable | No | Sí |
| Quién la crea | Tu código, al momento | Tú, una vez, por archivo |
| Ideal para | Descarga o subida puntual, por usuario | Archivo que compartes y quizá quieras cancelar |
Si el enlace se usa en segundos o minutos, la URL prefirmada es la opción correcta. Si compartes el enlace con varias personas durante días y quizá necesites cancelarlo, usa un mecanismo revocable. Para decidir qué dejar público y qué privado, mira archivos públicos o privados. Para ver dónde encaja boto3, lee qué es S3 y el almacenamiento compatible con S3 y, para archivos grandes, carga multiparte y reanudable.
Cómo hacerlo en Square Cloud#
En el Blob Storage de Square Cloud, el caso del inicio (facturas y contratos que solo su dueño descarga) va en el bucket private, y el código Python de este artículo funciona con tres cambios: el endpoint https://s3-blob.squarecloud.app, la región auto y las claves S3 que generas a partir de una API key en la pestaña "Acceso S3" del panel. Las URL prefirmadas SigV4 valen hasta 7 días y sirven para descargar (GET) y para subir directo desde el navegador (PUT): el CORS acepta PUT desde cualquier origen, siempre que la API key tenga permiso de escritura.
Cuando el enlace sale del panel y no de tu código, la elección es la misma de la tabla anterior. El enlace temporal vale hasta 24 horas y no se puede revocar. El enlace para compartir vale hasta 30 días y se puede revocar en cualquier momento; la contraseña y los metadatos en el enlace están en los planes Pro y Enterprise.
El Blob no cobra tarifa de salida ni de entrada, y la cuota incluida va de 5 GB a 250 GB según el plan. Para probarlo, genera las claves S3 en el panel, define S3_ENDPOINT y S3_REGION=auto y ejecuta el ejemplo contra el bucket private. Conoce el Blob Storage y revisa la cuota de cada plan en Precios.
Blob Storage
Object storage compatible con S3, sin tarifas de salida
Preguntas frecuentes
¿Cuánto dura una URL prefirmada?
Depende del storage y de cómo se firmó la URL. En Amazon S3, el máximo es de 7 días con el SDK o la CLI y credenciales de usuario IAM, y de 12 horas desde la consola. Con credenciales temporales, la URL expira junto con ellas.
¿Se puede cancelar una URL prefirmada antes de que expire?
En general no. La URL sigue siendo válida mientras lo sean su firma y las credenciales que la crearon. Si necesitas revocar el acceso, usa un enlace para compartir revocable o un plazo muy corto.
¿Cualquiera con la URL puede descargar el archivo?
Sí. La URL prefirmada funciona como un token al portador: quien la tenga accede al archivo hasta que expire. Trátala como una contraseña temporal y no la publiques en lugares abiertos.
¿La URL prefirmada sirve para subir archivos?
Sí. Generas una URL para el método PUT y el navegador o la app del usuario envía el archivo directo al storage, sin pasar por tu servidor.
Más en Storage
Ver los 15 artículos- Qué es S3 y qué significa 'compatible con S3'S3 es el almacenamiento de objetos de Amazon y su API se volvió el estándar del sector. Aprende qué significa ser compatible con S3 y cómo conectarte.
- Subir archivos grandes: carga multiparte y reanudableLa carga multiparte divide un archivo grande en partes que se envían en paralelo y se reintentan por separado. Mira el paso a paso en Python y cómo reanudar.
- Reglas de ciclo de vida: expirar y limpiar archivos automáticamenteUna regla de ciclo de vida borra archivos sola después de un plazo. Aprende a crear reglas de caducidad por carpeta en S3 con boto3 y a comprobar que funcionan.
- Archivos públicos o privados: cómo controlar quién accedeUn archivo público abre para quien tenga la URL; uno privado, solo con un enlace autorizado. Aprende a elegir, probar el acceso y compartir con seguridad.