Skip to content

Casos de uso

Condicionar funciones y ediciones

Desbloquea funciones exclusivas de Pro y por edición directamente desde la licencia firmada: define derechos en un nivel, léelos offline con el SDK y cambia lo que recibe un cliente sin publicar código nuevo.

Objetivo. Quieres que “Exportar”, “SSO”, “proyectos ilimitados” — cualquier capacidad exclusiva de Pro o específica de una edición — se active a partir de la licencia del cliente, verificada localmente sin llamada al servidor, y quieres cambiar quién recibe qué sin publicar una nueva compilación.

Cuándo usarlo

  • Úsalo si tu producto tiene funciones que dependen del plan que compró un cliente (un nivel gratuito frente a uno de pago, Pro frente a Enterprise, complementos), y quieres que la decisión viaje dentro de la licencia firmada para que funcione offline y no se pueda cambiar editando un archivo de configuración.
  • Úsalo si esperas que tu catálogo de planes cambie: condiciona por derechos con nombre en lugar de por la edición, y un futuro reempaquetado será una edición en el panel, no una release.
  • No lo uses si lo que vendes es consumo (renders, llamadas a la API, generaciones de IA) en lugar de una capacidad — mide eso con créditos. Y la cobertura de qué versiones del producto puede ejecutar una licencia es un eje aparte — consulta Cobertura de versiones.

Los derechos son el mecanismo detrás de toda esta página: una licencia lleva un pequeño mapa de indicadores con nombre y límites numéricos, firmado junto con el nivel, que tu aplicación lee en tiempo de ejecución. Como viven en la carga firmada, una licencia filtrada o editada a mano no puede otorgar un indicador que el servicio nunca firmó — la firma falla y el SDK falla de forma cerrada a Free.

Plantilla de la ediciónpro → puestos + derechosexport = truemax-projects = 10al emitirLicencia + lease firmadosnivel · derechos · vencimientofirmado con RSA, infalsificablevinculado a la máquinaofflineTu aplicaciónclient.IsEnabled("export")verificado con la clave integradasin llamada al servidorfunción desbloqueadafalta / mala→ ocultaCambia la plantilla → las nuevaslicencias la reciben. Las clavesexistentes conservan su instantánea.El indicador se lee del documento firmado, así que falla de forma cerrada: un indicador ausente es "off", una licencia manipulada es Free.Condiciona por el nombre del derecho, no por la edición, y reempaquetar tus planes nunca implica código nuevo en la aplicación.
Los derechos de una edición se incorporan a cada licencia al emitirla, se firman y se leen de vuelta localmente — la decisión sobre la función nunca sale del dispositivo.

Lo que haces tú (lado del proveedor)

Una edición (el término del panel para un nivel) lleva un número de puestos y una plantilla de derechos — los indicadores con nombre y los límites numéricos que se incorporan a cada licencia emitida a partir de ella. Defínelos una vez por edición; cada licencia de esa edición los hereda.

La página del producto Acme App en Keyright mostrando una tarjeta Editions con tres niveles y sus derechos: enterprise (25 puestos — export, sso, airgap, max-projects), pro (3 puestos — export, max-projects) y starter (1 puesto — max-projects), junto a una tarjeta Trial que dice '14-day trial · pro' y una tarjeta Signing key por producto.
Cada edición lleva su propia plantilla de derechos — starter recibe max-projects, pro añade export y enterprise añade sso y airgap — y cada licencia emitida desde una edición hereda esos indicadores.

En el panel: Products → tu producto → Editions → Add edition (añadir edición) (o edita una existente), y rellena los derechos — un indicador booleano como export, o un límite numérico como max-projects. Por la API es una sola llamada:

# define an edition with its entitlement template
curl -X POST $BASE/admin/products/acme-app/tiers -H "X-Admin-Token: $TOKEN" -H "content-type: application/json" \
  -d '{"name":"pro","seats":3,"entitlements":{"export":"true","max-projects":"10"}}'

# a higher edition that adds a flag and lifts the limit
curl -X POST $BASE/admin/products/acme-app/tiers -H "X-Admin-Token: $TOKEN" -H "content-type: application/json" \
  -d '{"name":"enterprise","seats":25,"entitlements":{"export":"true","sso":"true","max-projects":"unlimited"}}'

Los valores de los derechos son cadenas en el cable: "true"/"false" para un indicador, un entero o el literal "unlimited" para un límite. Cuando emites una licencia desde esa edición, la plantilla se aplica automáticamente — el mapa de derechos aparece en la licencia (GET /admin/licenses/{id} devuelve un objeto entitlements) y dentro del lease firmado que verifica la aplicación del cliente:

# issue a pro license — it inherits pro's entitlements
curl -X POST $BASE/admin/licenses -H "X-Admin-Token: $TOKEN" -H "content-type: application/json" \
  -d '{"licensee":"Acme Inc.","product":"acme-app","tier":"pro","seats":3,"email":"owner@acme.com"}'

Un cliente que necesita algo distinto recibe una anulación por licencia al emitir: pasa un mapa entitlements explícito en el cuerpo de POST /admin/licenses (el cajón Issue license del panel expone lo mismo bajo sus opciones avanzadas), de modo que puedes otorgar, por ejemplo, sso a una única cuenta Pro sin inventar una nueva edición. La anulación se incorpora a la carga firmada de esa única licencia exactamente igual que un indicador de plantilla.

Los derechos se capturan como instantánea y se firman cuando se emite la licencia — no existe una llamada “editar los derechos de una clave activa”, y volver a enviar /admin/licenses con un id existente se rechaza como duplicado. Para cambiar lo que desbloquea una clave ya emitida, emite al cliente una nueva licencia (con los derechos que quieras, o desde una edición actualizada) y haz que la active; la clave antigua puede revocarse una vez que cambie. Editar la plantilla de una edición solo cambia las licencias emitidas después de la edición.

En tu código

Tu aplicación integra solo la clave pública y lee los derechos de la licencia validada — offline, sin llamada al servidor (la activación/Validate() ya entregó y almacenó en caché el lease firmado). Los detalles de la inicialización del cliente están en la guía del SDK de .NET; aquí solo está el condicionamiento, en cada SDK y sobre HTTP puro.

Los mismos derechos que lees en el código son exactamente lo que el panel muestra en una licencia — los indicadores incorporados al emitir:

La tarjeta Details de la licencia de Stark Industries en Keyright, que lista EDITION pro, SEATS 3 (2 en uso), TERM perpetual y una fila ENTITLEMENTS con dos chips: 'export' y 'max-projects: 10' — los indicadores firmados que tu aplicación lee en tiempo de ejecución.
Los derechos de una licencia (aquí export y max-projects: 10 en una clave pro) se firman en su lease al emitir — IsEnabled("export") y GetLimit("max-projects", …) leen exactamente estos, offline.

.NET

using Keyright.Client;

// Edition-level gating: IsPaid is true for any edition above Free; switch on the edition for broad tiers.
LicenseInfo info = License.Validate();          // offline, never throws; failures resolve to Edition.Free
if (info.IsPaid)      ShowPaidChrome();          // trial OR paid — info.IsTrial tells them apart
if (info.Edition == Edition.Enterprise) ShowEnterpriseOnlyPanel();

// Feature-level gating: ask for the entitlement by name — this is the durable way to gate.
if (License.IsEnabled("export"))                 // boolean flag; a missing flag reads as false (fail closed)
    EnableExportCommand();

// Numeric limit: you pass the fail-closed fallback, so an absent/garbled value can never read as "more".
long maxProjects = License.GetLimit("max-projects", fallback: 1);
if (currentProjectCount >= maxProjects)
    PromptToUpgrade();

Node.js

const { info } = license.validate();                        // offline; failures resolve to the 'free' edition
if (info.isPaid) showPaidChrome();                          // trial OR paid
if (info.edition === 'enterprise') showEnterpriseOnlyPanel();

if (info.entitlements.isEnabled('export')) enableExportCommand();   // missing flag -> false
const maxProjects = info.entitlements.getLimit('max-projects', 1);  // 'unlimited' -> a huge number
if (currentProjectCount >= maxProjects) promptToUpgrade();

Python

from keyright import Edition

info = license.validate_info()                       # offline; failures resolve to Edition.FREE
if info.is_paid:
    show_paid_chrome()                               # trial OR paid
if info.edition == Edition.ENTERPRISE:
    show_enterprise_only_panel()

if info.entitlements.is_enabled("export"):           # missing flag -> False
    enable_export_command()
max_projects = info.entitlements.get_limit("max-projects", fallback=1)   # "unlimited" -> very large int
if current_project_count >= max_projects:
    prompt_to_upgrade()

Java

LicenseInfo info = client.validateInfo();            // offline; failures resolve to Edition.FREE
if (info.isPaid()) showPaidChrome();                 // trial OR paid
if (info.edition == Edition.ENTERPRISE) showEnterpriseOnlyPanel();

if (info.entitlements.isEnabled("export")) enableExportCommand();   // missing flag -> false
long maxProjects = info.entitlements.getLimit("max-projects", 1);   // "unlimited" -> EntitlementSet.MAXLONG
if (currentProjectCount >= maxProjects) promptToUpgrade();

Cualquier lenguaje (HTTP puro)

# No SDK call — read the flags straight out of the lease you already verified.
# After the lease's signature checks out (see "Verify the lease offline"), the signed
# lease JSON carries an "entitlements" object; the flag is part of the signed payload (the
# |ent= segment), so a lease that verifies is one whose entitlements you can trust:
#
#   "entitlements": { "export": "true", "max-projects": "10" }
#
# export enabled  = entitlements["export"] is "true"/"1"/"yes"   (absent -> off, fail closed)
# project limit   = int(entitlements["max-projects"])           ("unlimited" -> no cap; absent -> your fallback)

IsEnabled y GetLimit validan cada uno en el momento y fallan de forma cerrada: un indicador ausente está desactivado, un límite ausente o no analizable devuelve tu valor de reserva, y "unlimited" se lee como long.MaxValue. Cuando compruebas varios derechos a la vez, valida una vez y reutiliza el resultado:

LicenseInfo info = License.Validate();
bool canExport = info.Entitlements.IsEnabled("export");
long maxSeats  = info.Entitlements.GetLimit("max-seats", 1);

Lo que LicenseInfo expone para tu interfaz: IsPaid, Edition, IsTrial, StatusBadge (p. ej. “Enterprise” / “Pro Trial”), ExpiryUtc, DaysRemaining, Status y un Message legible para personas, además del propio mapa Entitlements. Condiciona la función por el derecho; usa la edición solo para el aspecto general de la interfaz.

Los consumidores de HTTP puro (Go, Rust, PHP…) leen los mismos derechos del lease verificado: el JSON del lease firmado lleva un objeto entitlements, y tras verificar la firma del lease lees los indicadores directamente de él. Los derechos forman parte de la carga canónica firmada (el segmento |ent=), así que un lease que verifica es uno cuyos derechos puedes confiar — la receta completa de verificación está en Usar la API HTTP directamente.

Cambiar lo que recibe un cliente existente. Editar la plantilla de una edición cambia solo las licencias futuras — las licencias emitidas conservan los derechos con los que se firmaron, la misma regla de instantánea que usa la cobertura. Para cambiar una licencia que ya está en producción tienes dos rutas confirmadas: añadir una anulación por licencia (reemite la licencia desde su página del panel / POST /admin/licenses con el mismo id), lo que la vuelve a firmar con el nuevo mapa de derechos y el cliente la recoge en el siguiente refresco del lease; o, para toda una edición, cambia la plantilla y reemite las licencias afectadas. Una renovación extiende el plazo y vuelve a firmar, pero se limita al vencimiento y a los puestos — reemitir es la ruta cuando el conjunto de derechos en sí debe cambiar.

Cloud vs autoalojado

Los derechos funcionan de forma idéntica en ambos modos — misma plantilla, mismas llamadas del SDK, misma carga firmada. Las únicas diferencias son las habituales:

  • $BASE y $TOKEN. Cloud: https://keyright.delta1labs.com con un token de equipo/sesión. Autoalojado: la URL de tu instancia con tu KEYRIGHT_ADMIN_TOKEN.
  • Qué derechos puedes repartir tú depende de tu propio plan (Cloud) o de tu edición autoalojada — los nombres de los derechos los inventas tú y significan lo que tu aplicación decida; no hay un vocabulario fijo. (No confundir con los derechos de la autolicencia de la propia instancia, que condicionan funciones de Keyright como SSO — consulta Licenciamiento y ediciones.)

Verificar

  1. Define una edición pro con {"export":"true"} y un producto sin free; emítete una clave pro.
  2. Antes de activar, Validate() devuelve Free e IsEnabled("export") es false — el comando permanece oculto.
  3. Activa la clave. La insignia cambia a Pro, IsEnabled("export") devuelve true y aparece el comando de exportación. Desconecta la red y reinicia — la decisión se mantiene desde el lease en caché, lo que demuestra que es offline.
  4. Añade "sso":"true" a la edición (o pásalo como anulación por licencia) y emite una nueva licencia desde ella; activa esa clave y refresca — el nuevo indicador aparece sin una nueva compilación de la aplicación. (Los derechos quedan fijados en la clave original al emitir, así que esto es una clave nueva, no una edición de la antigua.)
  5. Edita a mano un archivo de lease en caché (invierte un indicador) y vuelve a validar: la firma falla y la aplicación cae a Free, lo que confirma que la condición no se puede falsificar.

Véase también