Droits et feature flags, pilotés par la licence
Comment activer des fonctionnalités et imposer des limites numériques selon le niveau de licence : modèles de droits signés, lecture des flags et des limites hors ligne dans votre app, application à la frontière de chaque capacité, et modifier ce qu'un niveau débloque sans publier une nouvelle version.
La plupart des tutoriels de licence s”arrêtent à un booléen : la licence est-elle valide ou non ? Cela répond à la question de savoir si le client peut exécuter votre logiciel. Cela ne répond pas à la question que votre produit pose réellement cent fois par jour : qu”est-ce que ce client précis a le droit de faire ? Peut-il utiliser le SSO ? Exporter en PDF ? Créer son onzième projet ? C”est le rôle des droits (entitlements) : des capacités nommées attachées à une licence, lues localement par votre app.
La forme d’un droit
Un droit est l”une de deux choses :
- Un feature flag — une capacité booléenne, nommée par ce qu”elle débloque :
sso,export,api-access,white-label. - Une limite numérique — un plafond que l”app impose :
max-projects,max-seats,api-calls-per-day.
Ceux-ci vivent sur un niveau (par exemple Free, Pro, Enterprise) sous forme de modèle. En émettant une licence à un niveau, elle hérite des droits de ce niveau, et ils sont intégrés dans la licence signée que le client active. Une licence Pro pourrait porter { sso: false, export: true, "max-projects": 25 } ; Enterprise, { sso: true, export: true, "max-projects": -1 } (en utilisant -1 pour illimité).
Lire les droits dans votre app
Après l”activation, le SDK met en cache une lease signée et analyse ses droits. Vous les lisez de façon synchrone, sans appel réseau :
var client = KeyrightClient.Initialize(options);
var info = await client.ActivateAsync(licenseKey); // once; the lease is then cached
// Later, anywhere in your app:
if (client.IsEnabled("sso"))
EnableSingleSignOn();
int maxProjects = client.GetLimit("max-projects", fallback: 1);
Deux propriétés rendent cela sûr. D”abord, cela échoue vers l”état bloqué : un flag inconnu renvoie false, et une limite absente renvoie le fallback que vous fournissez — vous passez donc la valeur la plus conservatrice, jamais une valeur optimiste. Ensuite, c”est hors ligne : le modèle de droits fait partie de la lease signée, vérifiée contre la clé publique que vous embarquez à la compilation. Modifiez une valeur et la signature ne correspond plus, de sorte que la vérification échoue au lieu d”accorder trop en silence.
Appliquez à la frontière de la capacité, pas seulement dans l’interface
Masquer un bouton « Exporter » grisé est une bonne UX, mais ce n”est pas de l”application : n”importe qui peut appeler la méthode derrière. Placez la vraie vérification à la frontière de la capacité elle-même : la fonction qui fait l”action.
public Report ExportToPdf(ExportOptions options)
{
if (!_license.IsEnabled("export"))
throw new FeatureNotLicensedException("export");
return _renderer.Render(options);
}
Les limites numériques s”appliquent au moment de la création, là où vous connaissez déjà le décompte actuel :
public Project CreateProject(string name)
{
int limit = _license.GetLimit("max-projects", fallback: 1);
if (limit >= 0 && _store.ProjectCount() >= limit)
throw new LimitReachedException("max-projects", limit);
return _store.Add(name);
}
Remarquez la garde limit >= 0 : une limite négative (-1) signifie illimité, donc le plafond est ignoré. Choisir une seule sentinelle pour « illimité » et l”appliquer de façon cohérente garde chaque point d”appel honnête.
Modifiez ce qu’un niveau débloque sans publier de version
Comme les droits sont définis sur le niveau, côté serveur, repackager est un changement de configuration, pas de code. Ajoutez api-access au niveau Pro et chaque licence Pro le récupère à sa prochaine actualisation : pas de nouvelle version, pas de clés réémises, pas d”action du client. Lancez un nouveau module complémentaire en activant un seul flag sur les niveaux qui doivent l”avoir. C”est la vraie récompense du modèle capacité-pas-plan : votre packaging et votre cadence de publication deviennent indépendants.
Cela rend aussi les expériences de tarification peu coûteuses. Déplacez export d”Enterprise vers Pro pendant un trimestre, mesurez la conversion, remettez-le : le tout sans toucher à l”application que vos clients exécutent.
Des règles de conception qui vieillissent bien
- Nommez les flags par capacité, pas par plan.
export, paspro-feature. Quand vous scinderez plus tard Pro en Pro et Team, rien dans votre code n”aura à changer. - Rendez les limites numériques et échouez au plancher. Le fallback que vous passez à
GetLimitdevrait être la valeur du niveau le plus bas, pour qu”un droit absent ou malformé se dégrade proprement au lieu de tout débloquer. - Ne réutilisez jamais le nom d”un flag retiré. Si vous supprimez
legacy-sync, ne recyclez pas la clé pour autre chose : d”anciennes leases en cache peuvent encore la porter. Traitez les clés de droits comme un vocabulaire en ajout seul. - Décidez de ce que fait l”expiration par capacité. Quand une licence entre dans sa période de grâce, certains produits laissent actives les fonctions en lecture seule et ne bloquent que l”écriture ; d”autres s”arrêtent net. Encodez cette politique là où vous lisez le flag, pas éparpillée dans l”interface.
Les droits transforment une licence d”une porte en un contrat que votre code peut interroger. Une fois que les fonctionnalités et les limites découlent d”un modèle signé, « faire monter ce client en gamme » et « livrer cette fonctionnalité à tous les Pro » cessent d”être des tâches d”ingénierie et deviennent un interrupteur — exactement là où ce contrôle doit se trouver.
Essayez Nebula.NET
Renforcez votre code .NET en quelques minutes — commencez avec l'édition gratuite.