Migrar de claves de licencia caseras a Keyright sin romperles nada a tus clientes
Un plan de migración paso a paso para dejar atrás un sistema de claves artesanal y pasarte a Keyright: inventaría lo que tienes, emite licencias firmadas para los clientes existentes, publica un cliente que lea ambos formatos durante una ventana de transición y luego retira el camino antiguo, todo sin obligar a un solo cliente a reactivar.
Todo sistema de licenciamiento casero empieza igual: un fin de semana, un GUID, una suma de control, quizá un poco de “cifrado” XOR y una comprobación que devuelve true. Se publica, funciona y luego, sin hacer ruido, se vuelve una pieza de carga. Años después quieres puestos de verdad, activación en línea, revocación y un portal de cliente, y chocas con la pregunta que frena en seco a la mayoría de los equipos: ¿cómo muevo a miles de clientes que ya ejecutan claves en producción hacia un sistema como es debido sin un cambio de bandera, un correo masivo de reactivación y una semana de tickets de soporte?
Puedes, y ningún cliente tiene por qué notarlo. El truco es tratar la migración como una ventana de transición en vez de un interruptor, y hacer que el cliente lea ambos formatos mientras, por debajo, reemites licencias en condiciones sin que nadie lo vea. Este artículo es el plan concreto.
Idea clave: Migra tras una sola interfaz. Publica un cliente que valide primero la nueva licencia firmada y recurra a tu clave heredada, emite una licencia firmada para cada cliente existente a partir de tus propios registros, entrégala como cualquier actualización y deja que cada app se pase sola en silencio en el siguiente arranque. Mantén el respaldo heredado durante un ciclo de renovación y luego bórralo. Sin reactivación, sin cambio de bandera.
Paso 1 — Inventaría qué codifican realmente tus claves actuales
Antes de poder mapear lo viejo a lo nuevo, tienes que saber exactamente qué significa tu clave artesanal. La mayoría de los esquemas caseros esconden una cantidad sorprendente de estado en una cadena o en un registro cercano. Escríbelo de forma explícita:
- Identidad — qué cliente, qué correo o identificador de pedido.
- Alcance — producto, edición/nivel y cualquier interruptor de función que activaras a mano.
- Vigencia — perpetua, o una fecha de caducidad (y dónde vive esa fecha de verdad: ¿en la clave, en un archivo de configuración, en tu base de datos?).
- Cantidad — número de puestos, si alguna vez los hiciste cumplir (la mayoría de los sistemas caseros no lo hacen, que suele ser por lo que estás migrando).
Este inventario es la especificación de la migración. Cada campo se convierte en un claim de la licencia firmada que vas a emitir. Si un dato no es recuperable de tus registros, decide ahora su valor por defecto —por ejemplo, “los clientes heredados desconocidos reciben un periodo de un año fechado desde la migración”— en vez de descubrir el hueco a mitad del despliegue.
Paso 2 — Entiende por qué tienes que reemitir (y quién lo paga)
Una clave casera la verifica la lógica dentro de tu app: la app decide que una clave es válida mirando su forma. Esa es la debilidad estructural que arregla una licencia firmada: la autoridad se traslada a una clave privada que nunca se distribuye (explicamos por qué en la anatomía de una clave de licencia firmada). La consecuencia para la migración es simple: tus claves antiguas no pueden importarse tal cual, porque nada las firmó. Tienes que acuñar una licencia firmada de verdad para cada cliente.
El replanteamiento importante: las emites tú, no tus clientes. Nadie pega nada. Traduces tu inventario a licencias firmadas de forma masiva y las entregas. El trabajo único es escribir el mapeo una vez; el coste por cliente es cero.
Paso 3 — Levanta Keyright y emite de forma masiva desde tus registros
Apunta tu proceso de emisión a tu tabla de clientes existente. Por cada registro activo, emite una licencia firmada con los claims del Paso 1. Desde un script o un trabajo nocturno esto es una llamada por cliente contra la API de administración:
POST /v1/licenses
Authorization: Bearer <token-admin>
Content-Type: application/json
{
"product": "acme-suite",
"tier": "pro",
"licensee": "pedidos+8831@cliente.example",
"expiresAt": "2027-01-31",
"seats": 3,
"entitlements": { "export": "true", "max-projects": "25" },
"externalId": "clave-heredada:4F2A-9C11-...",
"idempotencyKey": "clave-heredada:4F2A-9C11-..."
}
Dos campos hacen que un relleno masivo sea seguro de reejecutar. externalId registra qué clave heredada reemplaza esta licencia, así tienes rastro de auditoría y puedes reconciliar después. idempotencyKey significa que ejecutar el trabajo de migración dos veces no acuña licencias duplicadas: el segundo intento devuelve la licencia ya emitida. Lo vas a ejecutar más de una vez (un lote falla a medias, a un registro le faltaba un campo), así que hornea la idempotencia desde la primera línea. La misma disciplina importa al automatizar la entrega de licencias con webhooks para tus ventas nuevas.
Paso 4 — Publica un cliente que lea ambos formatos
Este es el corazón de una migración sin roturas. Pon ambas comprobaciones tras una sola interfaz, prueba primero la licencia firmada y recurre a la clave heredada solo cuando no haya nueva licencia presente:
public sealed class CompositeLicenseSource
{
private readonly KeyrightClient _keyright;
private readonly LegacyKeyReader _legacy;
public LicenseState Resolve()
{
// Prefiere la licencia de verdad. Validate() es offline y nunca lanza:
// una licencia ausente/caducada/revocada falla en cerrado a Free.
LicenseInfo info = _keyright.Validate();
if (info.IsValid)
return LicenseState.FromKeyright(info);
// Aún no hay licencia firmada: honra la clave heredada durante la transición.
if (_legacy.TryRead(out var legacyKey) && _legacy.IsAccepted(legacyKey))
return LicenseState.FromLegacy(legacyKey);
return LicenseState.Unlicensed; // falla en cerrado, como siempre
}
}
El orden importa: al comprobar Keyright primero, un cliente que ya recibió su licencia firmada deja de depender de inmediato del camino heredado, aunque la clave antigua siga en disco. El respaldo arrastra a los lentos. Cada punto de llamada le pregunta a CompositeLicenseSource en vez de tocar cualquiera de los lectores directamente, así que cuando borres el respaldo más adelante será un cambio de un solo archivo. Todo el conjunto se mantiene offline-first y falla en cerrado, exactamente las propiedades que tu comprobación casera seguramente nunca tuvo.
Paso 5 — Entrega, pásate y retira
Ahora la migración corre sola. Entrega cada licencia firmada igual que entregas cualquier actualización —empaquetada con la siguiente versión, descargada en el primer arranque o por correo— y el cliente de doble lectura la recoge y abandona en silencio el camino heredado. Secuéncialo para quitar riesgo:
- Pasa primero las ventas nuevas. Conecta el checkout para que emita licencias firmadas, de modo que cada cliente nuevo nazca en el sistema nuevo y nunca toque el formato heredado.
- Rellena a los clientes existentes por lotes. Ejecuta el trabajo idempotente del Paso 3 sobre tu tabla, primero los activos más antiguos, atento a huecos de mapeo.
- Mantén el respaldo durante un ciclo de renovación completo. Los clientes lentos de actualizar y los aislados (air-gapped) aún no han visto su nueva licencia; el camino heredado los mantiene funcionando hasta que la vean. No metas prisa.
- Borra el respaldo. Cuando las renovaciones o la telemetría anónima de actualizaciones muestren que el formato heredado está prácticamente en desuso, elimina
LegacyKeyReaderen una versión rutinaria. La migración terminó, y el único código que queda es el de verdad.
En ningún momento hubo un cambio de bandera, una reactivación forzada ni un correo de “por favor, vuelve a introducir tu clave”: las tres cosas que convierten una migración en un incendio de soporte.
Las advertencias honestas
Dos cosas que conviene ver con claridad. Primera: el respaldo heredado es, por definición, tan débil como lo era tu esquema antiguo, así que trata la ventana de transición como un plazo, no como un estado permanente, y mantenla solo mientras la cola larga la necesite de verdad. Segunda: cualquier dato de cliente que no puedas recuperar de tus registros se vuelve una suposición; decide esos valores por defecto por adelantado (Paso 1) para que los huecos sean una política deliberada y no una sorpresa. Ninguna de las dos es motivo para demorarse: son motivos para acotar la ventana y escribir el mapeo con cuidado.
Dónde encaja Keyright
Keyright está hecho justo para este movimiento: emite los archivos de licencia offline firmados y los arrendamientos de activación en línea de corta vida que tu esquema casero nunca tuvo, hace cumplir puestos y node-locking del lado del servidor, lleva derechos (entitlements) y niveles para que un solo binario desbloquee según el plan, y te da un portal de cliente alojado más SDKs para .NET, Node, Python y Java que fallan en cerrado por diseño. La API de administración y los campos externalId/idempotencia están ahí precisamente para que un relleno masivo desde tus registros antiguos sea seguro de reejecutar. Ejecútalo en nuestra nube gestionada o autoalojado en tu propia red: el mismo formato firmado en ambos casos.
Empieza con el plan gratuito y modela tu migración de principio a fin antes de pagar un céntimo — mira los planes o lee la guía de primeros pasos. Si aún estás sopesando si moverte siquiera, nuestro análisis de construir vs comprar desglosa qué dejas de mantener el día que te pasas.
Prueba Nebula.NET
Endurece tu código .NET en minutos — empieza con la edición gratuita.