Skip to content

Guía

Activación y desactivación

Cada ruta de activación y desactivación para licencias de prueba, anuales (por plazo) y perpetuas — en línea, sin conexión/aisladas (air-gapped) y del lado del proveedor — y exactamente lo que ve tu aplicación en cada caso.

Esta página recorre cada ruta de activación y desactivación que un proveedor encuentra en la práctica: licencias de prueba, anuales (por plazo) y perpetuas, activadas y desactivadas en línea, sin conexión / aisladas (air-gapped) y del lado del proveedor. Los fragmentos de código son C# (Keyright.NET), pero la forma del SDK es idéntica en los paquetes de Node, Python y Java — consulta el repositorio de samples ejecutable.

Las tres formas de licencia

Una licencia lleva un nivel, un número de puestos, una caducidad opcional y una marca de prueba opcional. Esas combinan en las tres formas que ven tus clientes:

FormaExpiryUtcIsTrialQué muestra tu aplicación
Perpetuanullfalse“Licensed — perpetual”
Anual / por plazouna fechafalse“Licensed — expires 31 Dec 2027”
Prueba / evaluaciónuna fechatrue“Evaluation — expires 31 Dec 2027 (N days left)”

Tu aplicación lee todo esto del LicenseInfo que devuelve Activate/Validate — nunca analizas una cadena de clave tú mismo:

var info = await client.ActivateAsync(licenseKey);
if (info.Status != LicenseStatus.Valid)      // fail closed
    return ShowUnlicensed(info.Message);

string banner = info.IsTrial
    ? $"Evaluation — expires {info.ExpiryUtc:d} ({info.DaysRemaining} days left)"
    : info.ExpiryUtc is null
        ? "Licensed — perpetual"
        : $"Licensed — expires {info.ExpiryUtc:d}";

Activación (en línea)

ActivateAsync(key) envía la huella digital de la máquina y la clave al servicio emisor. El servicio comprueba el número de puestos, vincula la licencia a esta máquina y devuelve un lease firmado que el SDK almacena en caché localmente. A partir de ahí Validate() funciona sin conexión contra ese lease en caché (consulta Seguridad y el modelo de lease).

Reactivar la misma máquina es idempotente — refresca el lease y nunca consume un segundo puesto. Llamar a ActivateAsync en cada arranque (cuando hay conexión) es el patrón recomendado: mantiene el lease fresco de forma silenciosa.

Activación de prueba

Una clave de prueba se activa exactamente como una clave de pago — misma llamada, mismo modelo de puestos — simplemente vuelve con IsTrial == true y una caducidad:

var info = await client.ActivateAsync(trialKey);
// info.IsTrial == true, info.ExpiryUtc == the trial end, info.DaysRemaining counts down

Muestra el banner de evaluación y restringe lo que quieras detrás de info.IsTrial. Cuando la fecha de prueba pasa, la activación/validación devuelve LicenseStatus.Expired y vuelves a tu estado sin licencia. Las pruebas también son conscientes de la duración desde la primera activación y de la manipulación del reloj — un cliente no puede recuperar tiempo retrasando el reloj (consulta la página de seguridad). Las pruebas normalmente se autogestionan desde tu propio sitio; consulta Pruebas gratuitas de autoservicio.

Activación perpetua

Una licencia perpetua no tiene caducidad. Actívala una vez; ExpiryUtc es null, así que se ejecuta tu rama “perpetual”. El lease sigue teniendo un TTL corto y se refresca en la siguiente activación en línea — la licencia nunca caduca, pero el lease sin conexión sigue siendo un token de gracia de vida corta (eso es lo que impide que una licencia perpetua se copie a máquinas ilimitadas sin conexión).

Activación anual / por plazo

Llamada idéntica; ExpiryUtc es la fecha hasta la que está pagada. Usa info.IsExpiringSoon() / info.DaysRemaining para avisar a los clientes antes de la renovación. Tras la fecha, la activación devuelve Expired. Renovar es un cambio del lado del proveedor en la licencia (/admin/licenses/{id}/renew) — el cliente conserva la misma clave y simplemente reactiva para recoger la nueva caducidad.

Cuando no quedan puestos

Si una máquina nueva intenta activar una licencia cuyos puestos están todos usados, el servicio devuelve LicenseStatus.SeatLimit — muestra un mensaje claro de “todos los puestos en uso — libera uno primero”. (De nuevo, la misma máquina reactivándose nunca llega a esto.)


Desactivación

Iniciada por el cliente (en línea)

DeactivateAsync(key) libera el puesto de esta máquina y borra el lease local, de modo que el puesto queda disponible de inmediato en otro lugar. Así es como un cliente cambia de máquina:

await client.DeactivateAsync(key);   // on the old machine -> seat freed
// ...then on the new machine:
await client.ActivateAsync(key);     // takes the freed seat

Esto funciona igual para licencias perpetuas, anuales y de prueba. Tras la desactivación, Validate() devuelve NoLicense en esa máquina.

Del lado del proveedor (desactivación forzada)

Cuando una máquina muere, se reimagina o un cliente no puede acceder a ella, tú liberas el puesto desde tu backend — sin necesidad de cliente:

curl -X POST "https://keyright.delta1labs.com/admin/licenses/<KEY>/free-seat" \
     -H "X-Admin-Token: $KEYRIGHT_ADMIN_TOKEN" \
     -H "Content-Type: application/json" \
     -d '{"machineId":"KRM1:..."}'

Puedes ver y liberar las máquinas de una licencia desde la vista Licenses del panel, o mediante POST /admin/licenses/{id}/free-seat (Support+) / /deactivate (Admin+). El siguiente Validate() en línea de la máquina ve que el puesto ha desaparecido.


Activación sin conexión / aislada (air-gapped)

Para una máquina que no puede alcanzar el servicio en absoluto, el proveedor emite un lease firmado de larga duración vinculado a esa única máquina. Funciona de forma idéntica para licencias de prueba y de pago.

  1. En la máquina sin conexión, lee su ID:

    var machineId = MachineFingerprint.Current().ToBoundString();  // KRM1:...

    (o ejecuta keyright machine-id). Envía esa cadena al proveedor.

  2. El proveedor (con conectividad + un token de administrador) acuña un lease para esa máquina — TTL por defecto 365 días:

    curl -X POST "https://keyright.delta1labs.com/admin/licenses/<KEY>/offline-lease" \
         -H "X-Admin-Token: $KEYRIGHT_ADMIN_TOKEN" \
         -H "Content-Type: application/json" \
         -d '{"machineId":"KRM1:...","days":365}'   > offline-lease.json

    Esto confirma un puesto para esa máquina (así que las activaciones sin conexión también cuentan contra el límite de puestos — no puedes acuñar leases sin conexión ilimitados más allá del número de puestos).

  3. De vuelta en la máquina sin conexión, impórtalo — sin red de por medio:

    client.ImportOfflineLease(File.ReadAllText("offline-lease.json"));
    var info = client.Validate();   // Valid, fully offline

Como el lease está vinculado a la huella digital de esa máquina, el archivo es inútil en cualquier otra máquina (devuelve MachineMismatch). Consulta la página de seguridad para saber por qué esto se mantiene incluso sin conexión.

Totalmente sin conexión, sin servicio alguno

Si nunca quieres que la máquina (ni el proveedor) toque una red, firma un archivo de licencia sin conexión autónomo con la CLI y envíalo con el producto:

keyright license --sign --licensee "Acme Corp" --product yourapp --tier pro \
  --private-key yourapp.private.json --expiry 2027-12-31 --out license.json

El cliente lo valida de forma puramente sin conexión mediante Validate() (se descubre por ruta, por la variable de entorno KEYRIGHT_LICENSE o por la ubicación de datos de aplicación por defecto). En este modo no hay seguimiento de puestos — es la opción adecuada para despliegues genuinamente aislados (air-gapped) o embebidos.


Una nota sobre la desactivación sin conexión

Hoy no existe una “prueba de desactivación” generada por el cliente, así que una máquina aislada (air-gapped) no puede devolver su puesto por sí misma. Libéralo del lado del proveedor (desactivación forzada, arriba) una vez que tu backend tenga conectividad, o emite leases sin conexión con un TTL lo bastante corto para que el puesto de una máquina dada de baja vuelva por sí solo cuando el lease caduque. Consulta el repositorio de samples.