License keys are the backbone of software monetization. Get them wrong and you leak revenue, frustrate customers, or create security holes. Get them right and you have a self-service, scalable system that protects your business while keeping customers happy.
Key Format: Structure Matters
Your license key format sends a signal about your product's professionalism. A well-structured key is easy to copy, resistant to typos, and contains embedded metadata that speeds up validation.
Recommended Format
Use a segmented format with checksums:
TO-XXXX-XXXX-XXXX-XXXX
│ │ │ └─ Checksum segment
│ │ └─ Random entropy
│ └─ Encoded plan tier
└─ Prefix (your product)
- Prefix — Identifies your product instantly in support tickets
- Segments — 4-character groups are easy to read and type
- Checksum — Catch typos before hitting your API
- Entropy — At least 128 bits of randomness to prevent guessing
Generation: Cryptographic Randomness Only
Never use sequential numbers, UUIDs, or timestamps as license keys. Use a cryptographically secure random number generator (CSPRNG) to ensure keys cannot be predicted.
// Node.js — secure key generation
import { randomBytes } from 'crypto'
const generateKey = (prefix = 'TO') => {
const bytes = randomBytes(16)
const hex = bytes.toString('hex').toUpperCase()
const segments = hex.match(/.{4}/g)!.slice(0, 4)
return prefix + '-' + segments.join('-')
}
// Result: TO-A3F2-B7C1-D9E4-F6A8
Storage: Hash, Don't Store Plaintext
Treat license keys like passwords. Store a one-way hash (SHA-256) in your database, not the plaintext key. This way, a database breach doesn't expose every customer's key.
- Hash on creation — Store SHA-256(key) in the database
- Show once — Display the full key only at creation time
- Partial display — Show only the last 4 characters in dashboards (TO-****-****-****-F6A8)
- Lookup by prefix — Store the first segment unhashed for support lookups
Validation: Edge-First Architecture
License validation should be as fast as possible — sub-10ms is the target. Every millisecond of validation latency adds friction to your customer's application. Deploy validation at the edge, close to your customers.
The Validation Flow
- Customer's application sends license key + domain to your validation endpoint
- Edge function receives the request in the nearest PoP
- Check the edge cache first (95%+ hit rate for active licenses)
- On cache miss, query the database and cache the result
- Return a signed response the client can verify offline
// Validate a license key
const result = await fetch('https://api.trafficorchestrator.com/api/v1/validate', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
key: 'TO-A3F2-B7C1-D9E4-F6A8',
domain: 'app.customer.com'
})
})
const { valid, features, expiresAt } = await result.json()
Rotation: Plan for Compromise
License keys get leaked — in screenshots, support tickets, public repos, and Slack messages. Build rotation into your system from day one.
- One-click rotation — Customers should be able to rotate their own keys from the portal
- Grace period — Old keys work for 24-48 hours after rotation to avoid breaking production
- Audit trail — Log every rotation with timestamp, IP, and user agent
- Webhook notification — Alert the customer's systems when a key is rotated
Revocation: Clean and Immediate
When a customer churns, disputes a payment, or violates your terms, you need to revoke their key instantly. But don't break their production — communicate clearly.
- Soft revoke — Key returns "expired" with a message explaining why
- Grace period — Give 7 days for payment disputes before hard revocation
- Hard revoke — Key returns "invalid" after the grace period
- Notification — Email the account owner with remediation steps
Rate Limiting: Protect Your Validation Endpoint
Your validation endpoint will be called millions of times. Protect it from abuse with intelligent rate limiting:
- Per-key limits — 100 requests/minute per license key
- Per-IP limits — 1,000 requests/minute per IP address
- Burst allowance — Allow short bursts for application startups
- 429 responses — Return Retry-After headers with exponential backoff
Offline Validation: Essential for Desktop Apps
Not every application has constant internet access. Support offline validation with cryptographic signatures that can be verified without calling your API.
// Offline validation with Ed25519 signatures
import { TrafficOrchestrator } from '@traffic-orchestrator/client'
const to = new TrafficOrchestrator({ apiKey: 'YOUR_KEY' })
const result = await to.verifyOffline({
licenseKey: customerKey,
signature: cachedSignature,
publicKey: YOUR_PUBLIC_KEY
})
Checklist: License Key Implementation
- Use cryptographically random key generation (128+ bits of entropy)
- Hash keys in storage — never store plaintext
- Validate at the edge for sub-10ms latency
- Support key rotation with grace periods
- Implement soft and hard revocation workflows
- Rate limit your validation endpoint
- Support offline validation with signatures
- Log all key lifecycle events in an audit trail
- Show keys partially in dashboards (mask middle segments)
- Send webhook notifications for key events
Ship licensing in your next release
5 licenses, 500 validations/month, full API access. Set up in under 5 minutes — no credit card required.