Activation Code Licensing System Design (Part 2): Constraints & Code Generation
2 min read
Learn how to design activation code constraints that define license plans, and how to generate, manage, and enforce codes in a backend and portal system.Contents
- Introduction
- Activation Code Constraints
- Activation Code Generation
- Abuse and Guardrails
- Design Justification
Introduction
Activation code constraints are the foundation of the licensing system.
They define the rules under which activation codes can be created and used.
From there, users generate codes that eventually bind to devices.
Activation Code Constraints
Definition
A constraint represents a license plan. It determines:
- Who owns it (
user_id
) - When it expires (
expire_at
) - How many codes can be created (
max_codes
)
Examples:
- Free trial: expires in 14 days, allows 1 code.
- Paid plan: expires in 1 year, allows 3 codes.
Backend Enforcement
The backend enforces constraints by:
- Ignoring expired constraints.
- Rejecting code generation when
max_codes
is reached. - Ensuring integrity even if a malicious client bypasses frontend checks.
Portal UX
- Shows only active constraints.
- Each constraint displays its expiration date, allowed codes, and the number already generated.
- If the maximum is reached, the constraint becomes non-selectable.
- A “Generate” button appears only when the user selects a valid constraint.
This ensures users clearly see what they can and cannot do.
Activation Code Generation
Process
- User selects a constraint in the portal.
- Frontend requests a new code from the backend.
- Backend checks validity:
- Constraint is still active.
- Code limit not reached.
- Backend creates a new row in
activation_codes
linked to the constraint.
Code Lifetime
- Each code inherits its
expire_at
from the associated constraint. - When the constraint expires, all codes under it automatically expire as well.
- Expired codes are ignored by backend queries and do not appear in the portal.
Code Management
- One-time use: when a device activates, the code is marked as
is_used = 1
. - Deletion: users may delete unused or used codes.
- Regeneration: deleting frees up a slot so a new code can be created, staying within the
max_codes
limit.
For example, a user with a 3-code plan may generate 2 codes. If they delete one, they can generate another, keeping total generated codes ≤ 3.
Abuse and Guardrails
Allowing deletion and regeneration makes the system flexible, but could be abused (e.g., cycling codes infinitely).
Simple guardrails include:
- Enforcing the
max_codes
limit at all times. - Adding a cooldown before regenerating a new code.
- Applying a daily cap per constraint.
These measures increase fairness without complicating the user experience.
Design Justification
- Constraints anchor license rules to specific users.
- Codes provide flexibility for device activation while respecting plan limits.
- Expiration ensures old data naturally falls out without manual cleanup.
- Guardrails prevent misuse while keeping the system practical for real users.