Abre la zona CDN → pestaña Settings en my.cubepath.com.

Dominio personalizado

Cada zona recibe un dominio generado por el sistema (<nombre>.cubecdn.io) que funciona de inmediato. Para servir el tráfico bajo tu propio hostname:

  1. 1
    Apunta un CNAME a la zona
    En tu DNS, crea un CNAME desde tu hostname (p. ej. cdn.example.com) al dominio de sistema de la zona.
  2. 2
    Define el dominio personalizado
    Introduce el hostname en Custom Domain y guarda.
  3. 3
    Espera al SSL
    El certificado se solicita automáticamente en cuanto el CNAME resuelve.

SSL

SSL Status muestra Valid, Pending, Error o Not configured. Hay dos tipos:

  • Automatic (Let's Encrypt) — gratuito, aprovisionado y renovado por nosotros. La opción correcta salvo que tengas un motivo concreto para no usarla.
  • Custom Certificate — elige uno de los tuyos en Certificados SSL, o sube uno nuevo. Disponible en planes superiores, y necesario para certificados EV o para uno que deba coincidir con el que usas en otro sitio.

URLs firmadas (Token Auth)

Token Auth sirve el contenido de la zona solo a quien tú autorices. Cada enlace que publicas lleva una firma criptográfica y una caducidad; quien pida sin una URL firmada válida recibe 403 Forbidden.

Es el patrón estándar para vídeo de pago, descargas restringidas, galerías privadas, enlaces temporales y para mantener el contenido fuera de los buscadores y lejos del hotlinking.

Cómo funciona

Al activar Token Auth, CubePath genera un secreto compartido para la zona. Tu backend calcula un HMAC-SHA256 sobre la ruta más una marca de caducidad más el secreto, lo codifica en base64url y añade ?token=...&expires=... a la URL. El edge recalcula el mismo HMAC con su copia del secreto y compara: si coincide, sirve; si no, 403. El secreto nunca viaja en la URL.

Activarlo

Abre la tarjeta Signed URLs (Token Auth) y activa Enable Token Auth. El secreto se genera y se muestra una sola vez.

Firmar URLs en tu backend

La operación es HMAC-SHA256(secreto, ruta + str(expires)), codificado en base64url sin relleno.

import hmac, hashlib, base64, time

SECRET = "<secreto_de_tu_zona>"

def sign(path: str, ttl_seconds: int = 3600) -> str:
    expires = int(time.time()) + ttl_seconds
    msg = f"{path}{expires}".encode()
    mac = hmac.new(SECRET.encode(), msg, hashlib.sha256).digest()
    token = base64.urlsafe_b64encode(mac).rstrip(b"=").decode()
    return f"https://tu-zona.cubecdn.io{path}?token={token}&expires={expires}"
const crypto = require('crypto');
const SECRET = process.env.CDN_SECRET;

function sign(path, ttlSeconds = 3600) {
  const expires = Math.floor(Date.now() / 1000) + ttlSeconds;
  const mac = crypto.createHmac('sha256', SECRET).update(`${path}${expires}`).digest();
  const token = mac.toString('base64url').replace(/=+$/, '');
  return `https://tu-zona.cubecdn.io${path}?token=${token}&expires=${expires}`;
}
function sign($path, $ttlSeconds = 3600) {
    $secret = getenv('CDN_SECRET');
    $expires = time() + $ttlSeconds;
    $mac = hash_hmac('sha256', $path . $expires, $secret, true);
    $token = rtrim(strtr(base64_encode($mac), '+/', '-_'), '=');
    return "https://tu-zona.cubecdn.io{$path}?token={$token}&expires={$expires}";
}

La tarjeta de Settings incluye además un subformulario Generate signed URL: pegas una ruta, defines una ventana de validez y obtienes una URL lista para usar. Es para pruebas y envíos puntuales — el tráfico de producción debe firmarse en tu backend, sin una llamada a la API por URL.

Elegir la caducidad

ValidezCaso de usoCompromiso
5 minutosDescargas puntuales, respuestas de API protegidasRefrescar pasada la ventana obliga a volver a firmar
1 horaSesiones de reproducción de vídeoLos vídeos largos la superan; el reproductor debe refirmar
24 horasRotación diaria de contenidoUna URL filtrada sirve durante un día
7 díasMedios estáticos cacheables, bundles de appExposición larga si se filtra; considera el IP binding

La validez está limitada a 7 días (604800 s) para acotar el daño de una filtración.

Vincular tokens a la IP del cliente

El conmutador Bind tokens to client IP incorpora la IP de origen a la firma, de modo que una URL filtrada solo funciona desde la IP a la que se emitió. Es una defensa fuerte frente a enlaces compartidos en chats y foros.

El coste es real: los clientes cuya IP cambia a mitad de sesión — redes móviles con CGNAT, WiFi de hotel, VPNs, saltos entre 4G y WiFi de casa — pierden el acceso en mitad de la reproducción.

Si lo activas, pasa la IP pública del cliente al firmar (normalmente la primera entrada de X-Forwarded-For si estás detrás de un proxy). Las IPv6 deben ir en forma canónica comprimida (2001:db8::1, no [2001:db8::1]).

Rotar el secreto

  1. 1
    Rota
    Pulsa Rotate secret y confirma.
  2. 2
    Copia el secreto nuevo
    Se aplica la misma regla de mostrar una sola vez.
  3. 3
    Actualiza tu backend
    Sustituye CDN_SECRET y redespliega para que la aplicación lo recoja.

La rotación es inmediata y retroactiva: todas las URLs firmadas con el secreto anterior empiezan a devolver 403 al instante, y el contenido que se esté reproduciendo en ese momento se corta. Planifica las rotaciones en una franja de poco tráfico, o mantén caducidades cortas para que la interrupción sea mínima.

Qué no hace Token Auth

  • No es un WAF. No filtra bots, no limita la tasa, no bloquea por país — eso son las reglas WAF.
  • No es autenticación de usuarios. Autoriza una URL contra un secreto compartido; quien tenga esa URL puede usarla, salvo que el IP binding esté activo.
  • No cifra el contenido. El transporte es HTTPS, pero los bytes son los mismos que hay en tu origen.

Diagnóstico

SíntomaCausa probable
403 en todas las URLsToken Auth está activo pero las peticiones no llevan ?token=, o el token se calculó con el secreto equivocado
403 en algunas URLsLa ruta firmada y la pedida no coinciden — barra final, mayúsculas o codificación de URL. Firma y pide exactamente la misma cadena
403 justo tras rotarURLs firmadas con el secreto anterior. Vuelve a firmarlas
Funciona en escritorio y falla en móvilEl IP binding está activo y el cliente cambió de red. Desactívalo o acorta la caducidad
403 aleatorios durante la reproducciónLa URL caducó a mitad de stream. Alarga la caducidad, o haz que el reproductor pida una URL nueva antes de que expire

CORS

CORS (cross-origin fetch) permite que JavaScript de otros dominios descargue contenido de esta zona. Lo necesitas para reproductores HLS/DASH, llamadas fetch() y cualquier XHR entre dominios — sin él el navegador bloquea la respuesta aunque el CDN la haya servido correctamente.

Actívalo y define los Allowed origins: o bien * para cualquier origen, o una lista de orígenes completos, uno por línea o separados por comas. Cada uno debe incluir el esquema (https://example.com) y ninguna ruta.