Deux modèles de licensing

Il existe deux grandes familles de licences logicielles professionnelles : les licences par poste (named user / per seat) qui lient une licence à une machine ou un utilisateur précis, et les licences flottantes (concurrent / floating) qui autorisent N utilisateurs simultanés parmi un plus grand groupe.

Une organisation de 100 personnes dont 20 utilisent le logiciel en même temps peut acheter 20 licences flottantes plutôt que 100 licences par poste — économie de 80%. C'est le cas d'usage central des licences flottantes.

Licences par poste

La licence par poste est le modèle d'IronLock par défaut. Elle est liée au fingerprint hardware d'une machine précise. Simple à implémenter, simple à auditer, mais rigide : si un utilisateur change de poste, la licence doit être re-générée.

  • Avantages : pas de serveur central requis, fonctionne offline, implémentation simple.
  • Inconvénients : inflexible pour les organisations avec du télétravail ou des postes partagés.

Licences flottantes

Les licences flottantes nécessitent un serveur central (licence server) qui gère un pool de N slots disponibles. Chaque client checke out un slot au démarrage et le restitue à la fermeture.

Checkout / Checkin

# Serveur de licences flottantes (FastAPI)
from fastapi import FastAPI, HTTPException
import asyncio
from datetime import datetime, timezone, timedelta

app = FastAPI()
POOL_SIZE = 20  # 20 licences flottantes

# sessions = {session_id: {user, machine, expires_at}}
sessions: dict = {}
lock = asyncio.Lock()

@app.post("/checkout")
async def checkout(user: str, machine_id: str):
    async with lock:
        # Nettoyer les sessions expirées
        now = datetime.now(timezone.utc)
        expired = [sid for sid, s in sessions.items()
                   if s['expires_at'] < now]
        for sid in expired: del sessions[sid]

        if len(sessions) >= POOL_SIZE:
            raise HTTPException(429, f"Pool plein ({POOL_SIZE}/{POOL_SIZE} licences utilisées)")

        session_id = generate_token()
        sessions[session_id] = {
            'user': user, 'machine': machine_id,
            'expires_at': now + timedelta(minutes=30)
        }
        return {"session_id": session_id, "pool_used": len(sessions)}

@app.post("/checkin")
async def checkin(session_id: str):
    async with lock:
        sessions.pop(session_id, None)
    return {"released": True}

Timeout et heartbeat

Un client qui plante sans faire de checkin bloquerait un slot indéfiniment. Le heartbeat résout ce problème : le client envoie un signal régulier, et les sessions sans heartbeat expirent automatiquement :

@app.post("/heartbeat")
async def heartbeat(session_id: str):
    async with lock:
        if session_id not in sessions:
            raise HTTPException(404, "Session expirée")
        sessions[session_id]['expires_at'] = (
            datetime.now(timezone.utc) + timedelta(minutes=30)
        )
    return {"renewed": True}

# Côté client — heartbeat toutes les 10 minutes
import threading
def heartbeat_loop(session_id, url):
    while True:
        threading.Event().wait(600)  # 10 min
        requests.post(f"{url}/heartbeat", json={"session_id": session_id})

Haute disponibilité

Pour éviter qu'une panne du serveur de licences bloque tous les utilisateurs, deux approches :

  • Token local de secours — au checkout, le serveur délivre aussi un token local valable 4h. Si le serveur tombe, les clients en cours continuent à fonctionner pendant la durée du token.
  • Réplication active-passive — deux serveurs de licences, le secondaire prend le relais si le primaire est indisponible. Les sessions sont répliquées via Redis ou une base PostgreSQL partagée.

Quand choisir quoi ?

CritèreFlottantPar poste
Utilisation simultanée faible✓ ÉconomiqueCoûteux
Fonctionnement offline requis✗ Serveur nécessaire✓ Natif
Utilisateurs nomades✓ FlexibleRebind requis
Simplicité d'implémentationModéré✓ Simple
Audit d'utilisation précis✓ Logs serveurEstimé

Conclusion

Les licences flottantes sont idéales pour les organisations avec un taux d'utilisation faible (20-40% des utilisateurs actifs simultanément). Elles nécessitent un serveur de licences — mais ce serveur peut être léger (FastAPI + SQLite suffit pour 500 clients). IronLock v2 supporte les deux modèles : le mode par poste nativement, le mode flottant via un serveur de licences IronLock dédié.

🔐
PRODUIT LIÉ
IronLock v2.0
← Article précédent Article suivant →