You've built software. Now you need to sell it. Which means you need licensing.
What seems like a simple problem—"generate a key, check if it's valid"—turns into months of engineering once you consider activation limits, hardware binding, subscription management, trial periods, offline validation, and dealing with users who inevitably lose their keys.
This guide covers everything you need to know.
The Core Components
A complete licensing system has these parts:
- License Key Generation — Creating unique, verifiable keys
- Activation Server — Validating keys and tracking activations
- Client Integration — Checking licenses in your software
- Admin Dashboard — Managing customers, licenses, and analytics
- Customer Portal — Self-service for users
License Key Generation
There are two approaches to license keys:
Option 1: Algorithmically Verifiable Keys
Keys that can be validated offline using mathematical properties.
import hashlib
import secrets
def generate_license_key(product_id, tier):
"""Generate a verifiable license key"""
random_part = secrets.token_hex(8).upper()
data = f"{product_id}-{tier}-{random_part}"
checksum = hashlib.sha256(data.encode()).hexdigest()[:8].upper()
# Format: PROD-TIER-XXXXXXXX-CHECKSUM
key = f"{product_id[:3]}-{tier[0]}-{random_part[:4]}-{random_part[4:]}-{checksum}"
return key.upper()
# Example: BRV-P-A3F2-9C1E-8B4D7F2APros: Works offline, fast validation
Cons: Can't revoke keys, limited metadata
Option 2: Server-Validated Keys
Keys that must be checked against a database.
def generate_server_key():
"""Generate a key that requires server validation"""
return f"KEY-{secrets.token_hex(16).upper()}"
def validate_key(key, hardware_id):
"""Check key against server"""
response = requests.post(
"https://api.yourserver.com/validate",
json={"key": key, "hardware_id": hardware_id}
)
return response.json()Pros: Full control, can revoke, rich metadata
Cons: Requires internet connection
Recommendation
Use server validation as primary, with a grace period for offline use. Check once on activation, then periodically (every 7-30 days) to maintain validity.
Hardware Fingerprinting
To prevent one license from running on unlimited machines, you need hardware identification.
import hashlib
import platform
import uuid
def get_hardware_fingerprint():
"""Generate a unique machine identifier"""
components = [
platform.node(), # Hostname
platform.machine(), # Architecture
str(uuid.getnode()), # MAC address
platform.processor(), # CPU info
]
raw = "-".join(components)
return hashlib.sha256(raw.encode()).hexdigest()[:32]Warning: Hardware Changes
Users upgrade computers, replace hard drives, and reinstall operating systems. Your fingerprint must be stable enough to survive minor changes but specific enough to prevent abuse. Allow 2-3 activations per license as a baseline.
Activation Flow
Here's the typical activation flow:
- User enters license key in your software
- Software generates hardware fingerprint
- Software sends key + fingerprint to your server
- Server validates key exists and isn't revoked
- Server checks activation count (e.g., max 3 machines)
- Server stores fingerprint and returns activation token
- Software stores token locally for future validation
Subscription vs Perpetual
Perpetual Licenses
- One-time payment
- User owns forever (usually with version limits)
- Easier to implement
- No recurring revenue
Subscription Licenses
- Monthly/annual payments
- Requires expiration checking
- Need integration with payment provider (Stripe)
- Recurring revenue, but more complexity
The Admin Dashboard Problem
Generating licenses is easy. Managing them is hard.
You need:
- Customer management
- License creation and revocation
- Activation history
- Usage analytics
- Support tools (reset activations, extend trials)
- Webhook integrations (Stripe, email)
Building this from scratch takes 3-6 months of development time. That's 3-6 months not building your actual product.
Build vs Buy
Build Your Own
Cost: 500+ engineering hours
Time: 3-6 months
Pros: Complete control, no external dependencies
Cons: Maintenance burden, security responsibility
Use a Service (Keygen.sh, etc.)
Cost: $49-299/month
Pros: Quick to implement, maintained by others
Cons: Monthly fees forever, vendor lock-in, data on their servers
Self-Hosted Solution (Bravura Admin Pro)
Cost: $49.99/month or $1,999.99 one-time
Pros: Your servers, your data, no monthly fees with perpetual
Cons: Need to host it yourself
Security Considerations
Your licensing system will be attacked. Assume it.
- Never trust the client — All validation logic must be server-side
- Rate limit everything — Prevent brute force key guessing
- Use HTTPS — Encrypt all communication
- Log activation attempts — Detect patterns of abuse
- Consider code obfuscation — Make it harder to patch out checks
Reality Check
Determined pirates will crack any protection. The goal isn't perfect security—it's making piracy inconvenient enough that honest people pay. Don't waste months building DRM that annoys paying customers.
Conclusion
A complete licensing system involves more than license keys. You need activation management, customer dashboards, subscription handling, and security considerations.
You can build it yourself (6+ months), use a SaaS service (ongoing fees), or deploy a self-hosted solution (own your data).
Whatever you choose, start simple. You can always add complexity later.