feat: license validation commands + entitlements system (Rust) #46

Closed
opened 2026-04-09 01:52:54 +00:00 by maximus · 0 comments
Owner

Contexte

Infrastructure de licence offline pour l'édition Base de Simpl'Résultat.
Ref: spec-monetisation.md — Phase 1, Issue 1

Tâches

  • Ajouter jsonwebtoken (avec feature EdDSA) au Cargo.toml — c'est la dépendance primaire pour décoder/vérifier les JWT (pas ed25519-dalek seul)
  • Créer src-tauri/src/commands/license_commands.rs :
    • validate_license_key(key) -> Result<LicenseInfo, String> — décode JWT, vérifie signature Ed25519, vérifie claim exp
    • store_license(key) -> Result<(), String> — sauvegarde license.key + activation.token dans app data
    • read_license() -> Result<Option<LicenseInfo>, String> — lit la licence stockée
    • get_edition() -> Result<String, String> — retourne "free", "base", ou "premium"
    • get_machine_id() -> Result<String, String> — hash unique cross-plateforme (crate machine-uid ou équivalent, documenter que réinstall OS peut changer l'ID)
  • Créer un module entitlements côté Rust : mappe chaque feature à un tier (free, base, premium). Config centralisée, pas de checks dispersés dans le code. Commande Tauri check_entitlement(feature: String) -> Result<bool, String>
  • Embarquer la clé publique Ed25519 dans le code Rust (constante)
  • Le JWT DOIT inclure un claim exp (ex: 2 ans). L'app doit prompter une re-validation en ligne avant expiration (CWE-613)
  • Ajouter un token d'activation séparé (signé serveur avec machine_id) pour empêcher la copie de license.key entre machines
  • Enregistrer les commandes dans lib.rs + commands/mod.rs
  • Tests unitaires (licence valide, expirée, signature invalide, clé corrompue, entitlement checks)

Notes de révision

  • jsonwebtoken est la dépendance primaire, pas ed25519-dalek (review technique)
  • JWT sans exp = irrévocable offline (review sécurité, CWE-613)
  • license.key copiable sans activation token (review sécurité)
  • Stratégie get_machine_id cross-plateforme à documenter (review technique)
  • Le feature gating GPL est un honor system assumé (Open Core) — l'important est la modularité des accès par tier via le module entitlements
## Contexte Infrastructure de licence offline pour l'édition Base de Simpl'Résultat. Ref: `spec-monetisation.md` — Phase 1, Issue 1 ## Tâches - [ ] Ajouter `jsonwebtoken` (avec feature EdDSA) au Cargo.toml — c'est la dépendance primaire pour décoder/vérifier les JWT (pas `ed25519-dalek` seul) - [ ] Créer `src-tauri/src/commands/license_commands.rs` : - `validate_license_key(key) -> Result<LicenseInfo, String>` — décode JWT, vérifie signature Ed25519, vérifie claim `exp` - `store_license(key) -> Result<(), String>` — sauvegarde `license.key` + `activation.token` dans app data - `read_license() -> Result<Option<LicenseInfo>, String>` — lit la licence stockée - `get_edition() -> Result<String, String>` — retourne "free", "base", ou "premium" - `get_machine_id() -> Result<String, String>` — hash unique cross-plateforme (crate `machine-uid` ou équivalent, documenter que réinstall OS peut changer l'ID) - [ ] Créer un module `entitlements` côté Rust : mappe chaque feature à un tier (`free`, `base`, `premium`). Config centralisée, pas de checks dispersés dans le code. Commande Tauri `check_entitlement(feature: String) -> Result<bool, String>` - [ ] Embarquer la clé publique Ed25519 dans le code Rust (constante) - [ ] Le JWT DOIT inclure un claim `exp` (ex: 2 ans). L'app doit prompter une re-validation en ligne avant expiration (CWE-613) - [ ] Ajouter un token d'activation séparé (signé serveur avec `machine_id`) pour empêcher la copie de `license.key` entre machines - [ ] Enregistrer les commandes dans `lib.rs` + `commands/mod.rs` - [ ] Tests unitaires (licence valide, expirée, signature invalide, clé corrompue, entitlement checks) ## Notes de révision - `jsonwebtoken` est la dépendance primaire, pas `ed25519-dalek` (review technique) - JWT sans `exp` = irrévocable offline (review sécurité, CWE-613) - `license.key` copiable sans activation token (review sécurité) - Stratégie `get_machine_id` cross-plateforme à documenter (review technique) - Le feature gating GPL est un honor system assumé (Open Core) — l'important est la modularité des accès par tier via le module entitlements
maximus added this to the spec-monetisation milestone 2026-04-09 01:52:54 +00:00
maximus added the
status:ready
type:feature
source:human
labels 2026-04-09 01:52:54 +00:00
maximus added
status:approved
and removed
status:ready
labels 2026-04-09 12:50:50 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: maximus/Simpl-Resultat#46
No description provided.