Anwendungsfälle
Offline- und netzwerkisolierte Kunden unterstützen
Maschinen ohne Internet lizenzieren: eigenständige Offline-Lizenzdateien, langlebige netzwerkisolierte Leases, der Import eines signierten Abdeckungsblocks per Datei und wann Offline- statt Online-Aktivierung die richtige Wahl ist.
Ziel. Eine Maschine lizenzieren, die Ihren Service nicht erreichen kann — oder nicht erreichen soll: eine abgekoppelte Workstation, ein abgesichertes Unternehmensnetz, eine Embedded-Box. Alles, was der Kunde braucht, kommt als signierte Datei an, wird lokal verifiziert, und nichts telefoniert nach Hause.
Wann Sie es einsetzen
- Nutzen Sie es, wenn einige Kunden in isolierten Netzen arbeiten oder Sie in regulierte Umgebungen verkaufen, in denen ausgehende Verbindungen verboten sind.
- Nutzen Sie es, wenn ein normalerweise verbundener Kunde einen langen Ausfall überstehen muss und das 14-Tage-Lease-Fenster nicht ausreicht.
- Nicht, wenn Ihre Kunden regelmäßig verbunden sind — die normale Online-Aktivierung funktioniert zwischen den Verlängerungen bereits offline und gibt Ihnen Live-Platzdurchsetzung und Widerruf. Offline-Lizenzierung tauscht beides gegen Unabhängigkeit vom Netzwerk ein.
Es gibt drei Offline-Bausteine, und sie sind unabhängig voneinander — wählen Sie, was die Situation erfordert:
| Baustein | Was es ist | Plätze? | Widerrufbar? |
|---|---|---|---|
Offline-Lizenzdatei (license.json) | Eine eigenständige signierte Lizenz — nie ein Aktivierungs-Roundtrip | Keine Platzverfolgung | Nur über eine ausgelieferte Widerrufsliste |
| Offline-Lease (netzwerkisoliert) | Ein gewöhnlicher signierter Lease, für eine Maschine ausgestellt, mit langer TTL | Ja — bestätigt beim Ausstellen einen Platz | Bei erneuter Prüfung (gar nicht, wenn nie online) |
| Abdeckungsblock-Datei | Der signierte Release-Abdeckungsblock, als Datei zugestellt | — | Wird durch eine neuere Datei ersetzt |
Alle drei werden mit demselben eingebetteten öffentlichen Schlüssel verifiziert, den Ihre App bereits trägt, mit denselben RSA/SHA-256-Prüfungen wie Online-Leases — „offline“ ändert also nur, wie das signierte Dokument zugestellt wird, nie, wie ihm vertraut wird. Die ganze Tiefe des Lease-/Anti-Rollback-Modells finden Sie in Sicherheit & das Lease-Modell; diese Seite ist die Aufgabe.
Wann Offline statt Online
Greifen Sie standardmäßig zur Online-Aktivierung — sie gibt Ihnen Live-Platzdurchsetzung und Widerruf und läuft zwischen den Verlängerungen trotzdem das gesamte Lease-Fenster lang offline. Wählen Sie einen Offline-Pfad, wenn:
- Die Maschine Sie gelegentlich erreichen kann, aber nicht zuverlässig → Online-Aktivierung mit einer erweiterten Lease-TTL reicht meist aus; wechseln Sie nur dann zu einem netzwerkisolierten Lease (Standard 365 Tage), wenn sie länger ohne Verbindung sein könnte als jedes Lease-Fenster, mit dem Sie sich wohlfühlen.
- Die Maschine Sie nie erreichen wird → ein netzwerkisolierter Lease (behält die Bindung pro Maschine und die Platzzählung) oder eine eigenständige Lizenzdatei (kein Netzwerk für Sie oder den Kunden, keine Platzverfolgung — am besten für Embedded-Systeme und wirklich isolierte Deployments).
Was Sie tun (Anbieterseite)
Offline-Lease (netzwerkisoliert) — an eine Maschine gebunden
Der Kunde schickt Ihnen seine Maschinen-ID; Sie stellen dafür einen langlebigen Lease aus:
# der Kunde liest zuerst seine Maschinen-ID aus: keyright machine-id (oder MachineFingerprint.Current().ToBoundString())
curl -X POST $BASE/admin/licenses/LIC-…/offline-lease -H "X-Admin-Token: $TOKEN" -H "content-type: application/json" \
-d '{"machineId":"KRM1:…","days":365}' > offline-lease.json
# -> { "machineId":"KRM1:…", "ttlDays":365, "lease":"{…signierter Lease als JSON…}" }
Das Ausstellen eines Offline-Lease bestätigt einen Platz für diese Maschine, netzwerkisolierte Aktivierungen zählen also weiterhin gegen das Platzlimit — Sie können nicht unbegrenzt Offline-Leases über die Platzanzahl hinaus ausstellen. Der Lease ist an diesen einen Fingerabdruck gebunden, die Datei ist also auf jeder anderen Maschine nutzlos (MachineMismatch).
Im Dashboard ist das die Aktion License file (Lizenzdatei) der Lizenz — sie signiert den Offline-Lease für die von Ihnen angegebene Maschinen-ID und übergibt Ihnen das JSON zur Zustellung:
offline-lease-Aufruf oben —, den Sie der netzwerkisolierten Box per Datei zustellen.Eigenständige Offline-Lizenzdatei — ganz ohne Service
Für wirklich isolierte oder eingebettete Deployments signieren Sie eine Lizenzdatei mit der CLI und liefern sie mit dem Produkt aus — ohne jemals eine Aktivierung:
keyright license --sign --licensee "Acme Corp" --product acme-app --tier pro \
--private-key acme-app.private.json --expiry 2027-12-31 --out license.json
In diesem Modus gibt es keine Platzverfolgung; er ist die passende Wahl für netzwerkisolierte und Embedded-Boxen. Um einen solchen Build abzuschalten, liefern Sie mit Ihrem nächsten Update eine signierte Widerrufsliste (GET /admin/revocation-list) aus.
Abdeckungsblock-Datei — für netzwerkisolierte Maschinen, die Release-Abdeckung durchsetzen
Eine abgekoppelte Maschine kann ihren Abdeckungsblock nicht bei der Aktivierung empfangen, also stellen Sie ihn als Datei zu:
# eine Lizenz
curl $BASE/admin/licenses/LIC-…/coverage/block -H "X-Admin-Token: $TOKEN"
# -> { "block":"…signierter Umschlag…" }
# jede Lizenz eines Produkts, für die netzwerkisolierte Massenzustellung
curl $BASE/admin/products/acme-app/coverage/export -H "X-Admin-Token: $TOKEN"
# -> { "product":"acme-app", "count":5, "items":[ { "licenseId":"…", "coverageBlock":"…" }, … ] }
Eine Verlängerung für einen netzwerkisolierten Kunden ist einfach eine neuere Abdeckungsdatei: Sie trägt eine höhere Sequenznummer und ersetzt daher die zwischengespeicherte, während eine ältere Datei abgelehnt wird (Anti-Rollback). Der Export respektiert Ihr Entitlement genau wie die Aktivierung, er kann also nie jemanden aussperren.
In Ihrem Code
Alles unten verifiziert lokal, ohne Netzwerk, gegen den öffentlichen Schlüssel, den der Client bereits einbettet. Die drei Pfade sind in jedem SDK gezeigt (der Import des Abdeckungsblocks ist heute ein .NET-Aufruf — die anderen SDKs nutzen den Lease-Pfad oder verifizieren den Umschlag über rohes HTTP):
.NET
using Keyright.Client;
using Keyright.Coverage;
// (A) Eigenständige Lizenzdatei / Umgebungsvariable: einfach validieren, was vorhanden ist — Validate() findet sie über
// einen expliziten Pfad, die Umgebungsvariable KEYRIGHT_LICENSE, ConfigLicensePath oder den App-Data-Ort des Betriebssystems.
LicenseInfo info = License.Validate(); // offline, wirft nie; fällt bei jedem Problem fail-closed auf Free zurück
if (info.IsPaid) { /* lizenziert */ }
// (B) Netzwerkisolierter Lease: die Datei importieren, die der Anbieter für DIESE Maschine signiert hat. Dieser Aufruf WIRFT bei Ungültigkeit.
try
{
LicenseInfo leased = License.ImportOfflineLease(File.ReadAllText("offline-lease.json"));
// leased.Status == Valid, vollständig offline; falsche Maschine/Produkt/Signatur/Ablauf -> wirft
}
catch (InvalidOperationException ex) { ShowOfflineLeaseError(ex.Message); }
// (C) Abdeckungsblock-Datei: den signierten Umschlag importieren; verifiziert, bindet an die Lizenz, setzt Anti-Rollback durch.
CoverageVerifyResult r = License.ImportCoverageBlock(File.ReadAllText("acme.coverage.json"));
if (!r.Ok)
{
// r.Status: Malformed | UnknownKey | BadSignature | RolledBack | WrongBinding | UnsupportedVersion
ShowImportError(r.Status);
}
Node.js
const fs = require('fs');
// (A) Offline-Validierung — synchron, kein Netzwerk, wirft nie; Fehler lösen zu 'free' auf.
const { info } = license.validate();
if (info.isPaid) { /* lizenziert */ }
// (B) Netzwerkisolierter Lease: die Datei importieren, die der Anbieter für DIESE Maschine signiert hat. Wirft bei Ungültigkeit.
try {
const leased = license.importOfflineLease(fs.readFileSync('offline-lease.json', 'utf8'));
// leased.isValid === true, vollständig offline
} catch (err) { showOfflineLeaseError(err.message); }
// (C) Abdeckungsblock-Datei: kein SDK-Aufruf in Node — importieren Sie sie mit dem .NET SDK oder verifizieren Sie den
// signierten Umschlag selbst über rohes HTTP (unten).
Python
# (A) Offline-Validierung — kein Netzwerk, löst nie eine Exception aus; Fehler lösen zu Edition.FREE auf.
info = license.validate_info()
if info.is_paid:
... # lizenziert
# (B) Netzwerkisolierter Lease: die Datei importieren, die der Anbieter für DIESE Maschine signiert hat. Löst bei Ungültigkeit eine Exception aus.
try:
with open("offline-lease.json", encoding="utf-8") as f:
leased = license.import_offline_lease(f.read()) # leased.is_valid, vollständig offline
except ValueError as ex:
show_offline_lease_error(str(ex))
# (C) Abdeckungsblock-Datei: kein SDK-Aufruf in Python — nutzen Sie das .NET SDK oder verifizieren Sie den Umschlag über rohes HTTP.
Java
import java.nio.file.Files;
import java.nio.file.Path;
// (A) Offline-Validierung — kein Netzwerk, wirft nie; Fehler lösen zu Edition.FREE auf.
LicenseInfo info = client.validateInfo();
if (info.isPaid()) { /* lizenziert */ }
// (B) Netzwerkisolierter Lease: die Datei importieren, die der Anbieter für DIESE Maschine signiert hat. Wirft bei Ungültigkeit.
try {
LicenseInfo leased = client.importOfflineLease(Files.readString(Path.of("offline-lease.json")));
} catch (IllegalArgumentException | IllegalStateException ex) {
showOfflineLeaseError(ex.getMessage());
}
// (C) Abdeckungsblock-Datei: kein SDK-Aufruf in Java — nutzen Sie das .NET SDK oder verifizieren Sie den Umschlag über rohes HTTP.
Jede Sprache (rohes HTTP)
# (A/B) Ein Offline-Lease ist ein gewöhnlicher signierter Lease mit einem weit entfernten leaseExpiresUtc — verifizieren Sie ihn
# mit EXAKT demselben Code wie einen Online-Lease: kanonische Nutzlast neu aufbauen, RSA-verifizieren, dann
# Produkt / Maschine / Ablauf prüfen und bei allem fail-closed reagieren. Siehe „Die HTTP-API direkt verwenden“.
# (Offline-Leases werden nie als Testversion markiert, ein |trial-Suffix gilt also nicht.)
# (C) Eine Abdeckungsblock-Datei trägt ihren eigenen signierten Umschlag und eine monotone Sequenznummer:
# Signatur auf dieselbe Weise verifizieren, an die Lizenz binden und eine Sequenznummer ablehnen,
# die niedriger ist als die, die die Maschine bereits hält (Anti-Rollback).
Ein paar Dinge, die das SDK hier garantiert, damit Ihre UX korrekt ist:
Validate()und Abdeckungsprüfungen werfen nie bei Offline-/Netzwerkbedingungen;ImportOfflineLeasewirft bei einem ungültigen Lease sehr wohl, also kapseln Sie den Aufruf.- Ein fehlender Block bedeutet nie „uneingeschränkt“. Wird ein Abdeckungsblock von einer Maschine entfernt, ergibt das
UnavailableOffline(auf einem durchsetzenden Build) oder keine Abdeckung — nie ein stilles Durchwinken.CheckCoverageAsyncliefertUnavailableOffline, wenn nichts zwischengespeichert ist und der Service nicht erreichbar ist — das Signal, „eine aktualisierte Lizenzdatei importieren“ anzuzeigen. - Anti-Rollback ist eine Sequenznummer. Ein Import mit
RolledBackbedeutet, dass die Datei älter ist als das, was die Maschine bereits hält, und ignoriert wurde;WrongBindingbedeutet, dass sie für eine andere Lizenz bzw. ein anderes Produkt ausgestellt wurde;UnknownKeybedeutet einen Schlüssel, den Ihr Build nicht einbettet (behalten Sie während einer Schlüsselrotation den vorherigen öffentlichen Schlüssel inAdditionalPublicKeysBase64).
Konsumenten über rohes HTTP verifizieren einen Offline-Lease mit exakt demselben Code wie einen Online-Lease — er ist ein gewöhnlicher signierter Lease mit einem weit entfernten leaseExpiresUtc — nach dem Rezept für die kanonische Nutzlast in Die HTTP-API direkt verwenden.
Anti-Rollback & das Lease-Modell, kurz gefasst
Jedes Offline-Dokument ist an den Fingerabdruck einer Maschine gebunden (innerhalb der signierten Nutzlast, sodass eine Kopie auf eine andere Maschine mit MachineMismatch scheitert), und Abdeckungsblöcke tragen eine monotone Sequenznummer, sodass eine ältere Datei nicht erneut eingespielt werden kann, um abgelaufene Abdeckung wiederherzustellen. Das Ablaufdatum ist Teil der signierten Bytes — das Bearbeiten eines Datums bricht die Signatur —, und das Zurückstellen der Uhr wird bei Testversionen und befristeten Lizenzen von der Uhrmanipulationserkennung abgefangen. Das ist die Zusammenfassung; die vollständige Darstellung, einschließlich der Frage, warum eine Einzelplatzlizenz auch offline nicht auf zwei Maschinen laufen kann, finden Sie in Sicherheit & das Lease-Modell.
Cloud vs. selbst gehostet
- Die Offline-Abläufe sind identisch — dieselben Endpunkte, dieselben Dateien, dieselbe lokale Verifikation. Der Unterschied liegt nur in
$BASE/$TOKEN. - Eigenständige Lizenzdateien über die CLI benötigen zum Signieren den privaten Schlüssel des Produkts; beim Self-Hosting ist das selbstverständlich (Sie halten ihn), und auf Keyright Cloud würden Sie stattdessen typischerweise den netzwerkisolierten Lease-Pfad nutzen (serverseitig ausgestellt), da der private Schlüssel den gehosteten Service nie verlässt.
- Ein Hinweis zur Offline-Deaktivierung: Eine netzwerkisolierte Maschine kann ihren Platz nicht selbst zurückgeben. Geben Sie ihn anbieterseitig frei, sobald Ihr Backend Konnektivität hat, oder stellen Sie Offline-Leases mit einer TTL aus, die kurz genug ist, damit der Platz einer stillgelegten Maschine von selbst zurückkommt.
Überprüfen
- Lizenzdatei: Signieren Sie eine
license.json, richten SieKEYRIGHT_LICENSEauf einer abgekoppelten Maschine darauf und starten Sie die App —Validate()liefert „lizenziert“ ohne Netzwerk. - Netzwerkisolierter Lease: Lesen Sie die ID einer Testmaschine aus, stellen Sie dafür einen 365-Tage-Offline-Lease aus,
ImportOfflineLeaseauf dieser Maschine —Valid, offline. Kopieren Sie die Datei auf eine zweite Maschine —MachineMismatch. - Abdeckungsdatei: Exportieren Sie den Abdeckungsblock einer Lizenz, importieren Sie ihn mit
ImportCoverageBlockauf einem durchsetzenden Build, und bestätigen Sie, dass die abgedeckte Version läuft und eine Version außerhalb des Bereichs die Import-/Verlängerungsmeldung zeigt. - Anti-Rollback: Importieren Sie eine ältere Abdeckungsdatei nach einer neueren — erwarten Sie
RolledBackund keine Änderung. - Platzbuchhaltung: Bestätigen Sie, dass das Ausstellen des Offline-Lease einen Platz verbraucht hat (der Zähler
usedder Lizenz ist gestiegen) — der Beweis, dass Offline kein Platz-Schlupfloch ist.
Siehe auch
- Aktivierung & Deaktivierung — die vollständigen Schritte der Offline-/netzwerkisolierten Aktivierung und die anbieterseitige Platzfreigabe.
- Sicherheit & das Lease-Modell — Node-Locking, Anti-Rollback und die signierten Formate im Detail.
- Release-Abdeckung — Export und Import von Abdeckungsblöcken für netzwerkisolierte Maschinen.
- Die HTTP-API direkt verwenden — einen Offline-Lease in jeder Sprache verifizieren.
- .NET-SDK-Integration — Client-Einrichtung und Schlüsselrotation.