
License Keys, Cryptographically Sealed
A full-stack licensing platform with RSA-256 signed JWT tokens, optional JWE encryption, per-machine activation with seat enforcement, heartbeat-based renewal, hierarchical pricing tiers with feature inheritance, and OpenID-style discovery for consuming applications.
// RSA-256 Signed JWT License Token
{
"alg": "RS256",
"typ": "JWT",
"kid": "rdn-lic-2025"
}
// Claims
{
"sub": "customer-id",
"aud": "rdn-identity",
"tier": "enterprise",
"features": ["sso", "passkeys", "mfa"],
"max_users": 500,
"max_tenants": 50,
"heartbeat_required": true,
"exp": 1735689600
}
8
Domain Entities
12
API Controllers
45
MediatR Handlers
38
Permissions
36
Components
30
Web Pages
32
API Routes
26
Test Files
Key Capabilities
Everything you need to issue, activate, enforce, and manage software licenses at scale.
JWT License Tokens
RSA-256 signed JWTs with optional JWE encryption (RSA-OAEP + A256CBC-HS512). Feature flags, tier info, and enforcement policy embedded directly in claims.
Per-Machine Activation
Track activations by machine identifier and IP address. Enforce seat limits with MaxUsers. Sibling key auto-revocation ensures one active key per customer per product.
Heartbeat Renewal
Consuming applications call /heartbeat periodically. The server returns a fresh token with configurable TTL (default 48h). No heartbeat means the token expires and the application goes dark.
Pricing Tier Hierarchy
Tiers inherit features from parent tiers via IncludesTierId with circular reference protection. Configure monthly/annual pricing, user limits, tenant limits, and billing periods per tier.
Feature Gating
Named feature keys embedded in JWT claims. Consuming applications read these at runtime to gate functionality without a network call. Display-only features for marketing pages.
Token Discovery
OpenID-style /.well-known/jwks.json and /.well-known/license-configuration endpoints. Consuming apps verify tokens locally using the published RSA public keys.
Three-Panel Web Dashboard
A Next.js 16 application with 30 pages across three distinct route groups, each serving a different audience.
Public Catalog
(site) route group
- Product catalog with pricing tiers
- Monthly/annual pricing toggle
- Feature comparison across tiers
- Self-service registration flow
- Privacy policy and terms pages
User Portal
(dashboard) route group
- My Licenses with credentials display
- Client ID and Token copy-to-clipboard
- License claiming for free tiers
- Profile management (name, company)
- Product browsing and subscriptions
- Discord integration and support
Admin Panel
(admin) route group
- Dashboard with stats and recent licenses
- Product CRUD with logo and audience
- Pricing tier management with feature assignment
- License generation with cascading form
- Revoke, regenerate, audit license actions
- Customer management and pending claims
- System logs with log level control
Full-Stack Architecture
A .NET 10 backend API with CQRS and a Next.js 16 dashboard, connected via OIDC.
Backend API
.NET 10 / ASP.NET Core
- CQRS with MediatR 14 — 45 command/query handlers
- Entity Framework Core 10 + Dapper for raw queries
- RSA-256 JWT signing with Azure Key Vault support
- Dual auth: JWT Bearer + API Key (X-Api-Key)
- Data Protection encryption of stored tokens
- FluentValidation 12 with assembly-scanned validators
- AutoMapper 16 for entity/DTO projection
- API versioning with Swagger documentation
- Rate limiting and HSTS with preload
- Serilog structured logging (console + file + SQL)
Web Dashboard
Next.js 16 / React 19
- NextAuth.js v5 with OIDC via Rdn.Identity
- Three route groups: (site), (dashboard), (admin)
- 36 components across 30 pages
- License generation with cascading product/tier selects
- Feature checklist with sticky sidebar
- Sortable lists with drag-and-drop (@dnd-kit)
- DataGrid pagination, sorting, and search
- Copy-to-clipboard for credentials display
- Tailwind CSS 4 responsive design
- TypeScript 5.9 with App Router
Cryptographic Token Security
License tokens are built on industry-standard JWT cryptography with multiple layers of protection.
> Token Signing
Algorithm: RS256
Key Size: RSA 2048-bit
Key Source: Azure Key Vault / Local PEM
Discovery: /.well-known/jwks.json
> Token Encryption (Optional)
Algorithm: RSA-OAEP
Encryption: A256CBC-HS512
Consumer Key: Provided at activation
> Storage Protection
Encryption: ASP.NET Data Protection
Attribute: [Protected]
Scope: LicenseKey.KeyToken
Converter: Custom EF Core value converter
> Key Vault Integration
Provider: Azure Key Vault
Signing: Remote (key never leaves vault)
Rotation: Configurable refresh interval
Fallback: Local PEM for development
Signed Tokens
Every license token is RSA-256 signed. Consuming applications verify signatures against the published JWKS endpoint without contacting the license server.
Encrypted Tokens
When a consumer provides an RSA public key during activation, the server returns a JWE token (RSA-OAEP + A256CBC-HS512). Only the consumer can decrypt and read the license claims.
At-Rest Encryption
Stored license tokens are encrypted using ASP.NET Core Data Protection. The [Protected] attribute triggers automatic encryption via a custom EF Core value converter.
Comprehensive REST API
12 controllers with 45 handlers covering every aspect of license management, from product catalogs to token validation.
# Products
GET /products
GET /products/catalog
GET /products/:id
POST /products
PUT /products/:id
DEL /products/:id
# Pricing Tiers
GET /pricing-tiers
GET /pricing-tiers/:id
POST /pricing-tiers
PUT /pricing-tiers/:id
DEL /pricing-tiers/:id
# Product Features
GET /product-features
GET /product-features/:id
POST /product-features
PUT /product-features/:id
DEL /product-features/:id
# Discovery
GET /.well-known/jwks.json
GET /.well-known/license-configuration
# License Keys
GET /license-keys
GET /license-keys/:id
GET /license-keys/by-customer/:id
POST /license-keys
POST /license-keys/validate
POST /license-keys/heartbeat
POST /license-keys/:id/revoke
POST /license-keys/:id/regenerate
GET /license-keys/:id/audit
DEL /license-keys/:id
# Activations
GET /license-activations
GET /license-activations/by-license/:id
POST /license-activations/activate
POST /license-activations/:id/deactivate
# Customers & Users
GET /customers
GET /customers/:id
POST /user/customer
GET /user/licenses
POST /user/licenses
PUT /user/profile
# Pending Claims
GET /pending-claims
POST /pending-claims/:id/resend-invite
DEL /pending-claims/:id
Dive Deeper
Explore the platform in detail.