Use Case 024: License Key Management
Overview
| Property |
Value |
| Use Case ID |
UC-024 |
| Use Case Name |
License Key Management |
| Module |
Configuration Management — Licensing |
| Priority |
High |
| Status |
Implemented |
| Version |
1.0 |
| Last Updated |
April 17, 2026 |
Description
This use case describes how administrators import, view, validate, and revoke Riptide Platform license keys through the Application Manager web interface. License tokens are generated externally using the SDK LicenseGenerator tool and imported as opaque signed strings. Application Manager decodes the token metadata, stores it for future reference, and can optionally activate the license so connected applications begin using it.
Actors
| Actor |
Description |
Role |
| Administrator |
System admin with the "Admin" policy |
Primary |
| System |
Application Manager platform |
Supporting |
| Configuration Store |
File-based configuration tree in ConfigurationDbContext |
Supporting |
| SDK LicenseGenerator |
External tool that creates signed license tokens |
External |
Preconditions
- Application Manager is running and accessible
- Administrator is authenticated with the "Admin" policy
- A valid license token has been generated externally via
LicenseGenerator
- (For validation)
Riptide:Platform:License:PublicKey is configured in appsettings.json
Postconditions
Success Postconditions
- License key record persisted in ConfigurationDbContext.LicenseKeys
- Decoded metadata (IssuedTo, InstallationId, apps, features) stored for display
- If activated,
/platform/license.json updated in configuration file tree
- If activated, previously active license deactivated
- Activity logged in audit trail
Failure Postconditions
- No record created if token format is invalid or duplicate
- Error message displayed to administrator
- No configuration changes if activation is not selected or fails
UC-024A: Import License Key
Triggers
- Administrator navigates to
/license-keys/import
- Administrator pastes a license token and submits the form
Basic Flow
- Administrator navigates to License Keys > Import License
- System displays the import form with a textarea for the token, optional notes, and an "Activate this license now" checkbox (checked by default)
- Administrator pastes the full
RIPTIDE-PLATFORM-v2-{base64}:{base64} token
- Administrator optionally adds notes (e.g., customer name, PO number)
- Administrator chooses whether to activate immediately
- System validates token format (prefix, separator, base64 structure)
- System checks for duplicate tokens (rejects if already imported)
- System decodes the base64 payload to extract: InstallationId, IssuedTo, IssuedAt, ExpiresAt, Applications/Features
- System creates a LicenseKey entity with decoded metadata and Status = Active
- If the token is already past its ExpiresAt, Status is set to Expired instead
- If "Activate now" is checked and the license is not expired:
- System clears IsActiveLicense on any previously active license
- System writes the token and InstallationId to
/platform/license.json in the configuration file tree
- System redirects to the license detail page with a success message
Alternative Flows
- A1: Invalid token format — FluentValidation rejects the token; form redisplays with error
- A2: Duplicate token — Handler throws InvalidOperationException; error displayed to admin
- A3: Decode failure — Malformed base64 or JSON; error message shown
- A4: Expired on import — License stored with Status = Expired; not activated regardless of checkbox
UC-024B: View License Key List
Triggers
- Administrator navigates to
/license-keys
Basic Flow
- Administrator clicks Licenses in the navigation bar
- System queries all license keys ordered by import date (newest first)
- System auto-updates any Active licenses past their ExpiresAt to Expired status
- System displays a table with: Issued To, Installation ID, Expires, Status badge, Application count, Imported date, and action dropdown
- Active licenses show a "Active License" badge next to IssuedTo
- Action dropdown offers: View Details, Revoke (for active licenses only)
UC-024C: View License Key Details
Triggers
- Administrator clicks "View Details" from the list or navigates to
/license-keys/{id}
Basic Flow
- System fetches the license key by ID with full decoded metadata
- System displays:
- License Information card: IssuedTo, InstallationId, masked token, IssuedAt, ExpiresAt, Status
- Licensed Applications & Features card: tree showing each application with enabled/disabled status and nested features
- Import Details sidebar: ImportedAt, ImportedBy, RevokedAt/By (if applicable)
- Notes (if any)
- Header shows "Active License" badge if this is the active license
- Validate and Revoke buttons in the page header
UC-024D: Validate License Key
Triggers
- Administrator clicks Validate on the license detail page
Basic Flow
- Administrator clicks the Validate button
- System fetches the license token from the database
- System decodes the token payload
- System checks
Riptide:Platform:License:PublicKey configuration
- If public key is configured: system verifies the RSA-SHA256 signature
- System checks whether the license has expired
- System displays results in an alert: Valid/Invalid, signature verified/not, days remaining, error details
Alternative Flows
- A1: Public key not configured — Validation reports "signature not verified" but does not fail; expiry check still runs
- A2: Signature invalid — Validation reports "license may have been tampered with"
- A3: License expired — Validation reports "license has expired" with expiry date
UC-024E: Revoke License Key
Triggers
- Administrator clicks Revoke on the list or detail page
Basic Flow
- System prompts for confirmation ("Are you sure? This cannot be undone.")
- Administrator confirms
- System sets Status = Revoked, RevokedAt = now, RevokedBy = current admin
- If this was the active license, IsActiveLicense is cleared (no license is now active)
- System displays success message and refreshes the page
Alternative Flows
- A1: Already revoked — Operation is idempotent; no error
- A2: License not found — Error message displayed
Business Rules
| Rule |
Description |
| BR-1 |
Only one license can be the active license at a time |
| BR-2 |
Importing the same token twice is rejected (duplicate detection) |
| BR-3 |
Expired licenses cannot be activated |
| BR-4 |
Revocation is irreversible — a revoked license cannot be reactivated |
| BR-5 |
Licenses are installation-wide — no tenant scoping |
| BR-6 |
Auto-expiry: Active licenses past their ExpiresAt are automatically set to Expired on list retrieval |
Data Requirements
| Field |
Type |
Constraints |
| Id |
Guid (UUIDv7) |
Primary key, generated by application |
| Token |
string |
Max 8000 chars, required, unique |
| InstallationId |
string |
Max 500 chars, decoded from token |
| IssuedTo |
string |
Max 500 chars, decoded from token |
| IssuedAt |
DateTimeOffset |
Decoded from token |
| ExpiresAt |
DateTimeOffset? |
Null = perpetual |
| ApplicationsJson |
string (JSON) |
Serialized app/feature tree |
| Status |
LicenseKeyStatus |
Active, Revoked, Expired |
| IsActiveLicense |
bool |
Only one true at a time |
| ImportedAt |
DateTimeOffset |
Set on import |
| ImportedBy |
string? |
Max 256 chars |
| RevokedAt |
DateTimeOffset? |
Set on revoke |
| RevokedBy |
string? |
Max 256 chars |
| Notes |
string? |
Max 1000 chars |