If one of your admin API tokens become compromised, you can quickly revoke it from
your admin dashboard.
In Client-facing Software
Do not embed your admin, environment or product API tokens within client- or end-user-facing code.
If you're using Keygen client-side, do not embed your admin, environment or product tokens
within your product's source code. Doing so exposes your tokens and opens your
account up to attackers, regardless of how obfuscated the token is.
Instead, you can perform license and machine creation requests client-side
while authenticated as one of your users, or by using a license token
which belongs to the license you're activating a machine for.
If you're using Keygen server-side, keep your secret API tokens safe.
In Version Control
We recommend that you do not store your API tokens in version control. It is recommended
that you store tokens in an environment file that is never checked into the repository,
or directly within the ENV on non-public devices.
Embedding account, product and policy IDs directly into your product i.e. client-side code
is perfectly safe. Inlining your public key is also perfect safe. In fact, you won't be able
to communicate with Keygen's API or verify signatures unless you include some of these values.
For example, your account ID is required so Keygen's API can route the request to the correct
account, and a product ID would be required for automatic upgrades.
With that in mind, it is recommended that you use your account ID over your account slug, as
unlike your account slug, your ID is unchangeable.
Resource IDs are standard v4 UUIDs, resembling the following format:
1fddcec8-8dd3-4d8d-9b16-215cac0f9b52
An account's RSA public key will resemble the following:
If you do not want your users to be able to create and manage their own licenses
and machines (which could necessitate listening for webhook events)
then you should set your account to protected, which require admin authentication
to create user and license resources.
Setting your account to protected can be done within your account settings.
Alternatively, you can set individual licenses policies to protected (which by default
is inherited from the account's current protected state), which will only disallow
users from creating and managing licenses which implement that particular policy and
their associated machines, rather than all resources. For example public user creation
would still be enabled, but license creation would be blocked.
You can also set a license to protected, which will disallow a user to activate/deactivate
their machines. Similarly to policies, the license's protected attribute is inherited
from its policy.
By default, your account is unprotected, which allows user registration as
well as the ability for users to manage their own resources.
If you only need to validate license keys, then you do not need to implement
user creation or authentication. The license validate-key
action does not require authentication. If you're doing anything else e.g. validating
multiple license resources per-user, tracking machines, etc., a form of API authentication
will be required in order to perform these API operations client-side.
You can add required validation "scopes" to your policies to, for example, require
a machine fingerprint parameter. This helps implement certain license models without
the need for any additional validation logic.
Although all applications are susceptible to cracking (given enough motivation), there are certain things
you can do to make cracking harder. Even applications written in a compiled language, such as C, are
susceptible to software cracking.
Efforts beyond the prevention measures below have diminishing returns for most software products and
time is better spent on legitimate users. Reach out to [email protected]
if you need additional anti-cracking measures, we'd be happy to chat with you.
Checksum verification
To help prevent against tampering of application code, you can utilize checksum assertions
during license verifications. By hashing an application during release, and hashing the same application
during runtime, you can assert that the two checksums match, proving that the end-user has not modified
application binaries or code. If there's a mismatch, the application has been modified.
To help prevent tampering and defend against other attack vectors such as a man-in-the-middle attack,
or proxy and replay attacks, you may choose to implement response signature verification.
Signature verification hardens your software by ensuring the given data originated from Keygen and
that the values have not been modified.
For caching purposes, or to allow time-limited offline use, we recommend using license files.
License files, like response signatures, are cryptographically signed and thus tamper-proof. In
addition to signatures, you can also encrypt license files. These can be used to store a secure
"snapshot" of a license as well as its entitlement and other relationship data.
User Agent Header
We recommend that you supply a custom User-Agent header with all API requests from
your software application. You should include your organization name, the application's
name, the running version number of the application, the operating system name, in
addition to any other information you may find valuable.
We will use this value to automatically detect certain crack attempts. We will notify
you of all findings and help you secure your application.
We are currently running a 'pilot' for an AI/ML crack detection product. If this is something
your organization is interested in, please reach out to us: [email protected].
We'd love to see if you're a good fit.
Protecting your application's licensing system from an end-user changing their local system time,
or "clock tampering", for an offline device can be a tough battle. As you could imagine, it's a
hard problem. Since the device is offline, there's not much one can do to prevent tampering or "spoofing"
the device itself to have its clock be in the past because whatever the device says is the time,
frankly, is the time.
There's no concept of a "correct" time for an offline device, since it can't sync to an NTP server
to get the real world time. What it has is correct, at least to the device itself, and as such,
it's correct for other uses as well, like licensing.
To properly defend against system clock tampering, you would need to periodically validate the license
using our API. We don't offer anti-clock-manipulation tools for offline use — that would need to be
handled outside of Keygen in your own application code.
In general, defending against system clock tampering is a tough problem — much like defending against
other types of cracking/tampering — because it's relying on an "untrusted" value of the system —
the clock.
We've seen companies occasionally write an inconspicuous config or log file to disk and then periodically
check the file's created (and modified) timestamps to loosely keep track of the clock, updating the
modified at value each time the file is checked. If a timestamp for the file is ever in the future
more than a couple hours (to account for daylight savings time), then it may be safe to assume that
the clock has been tampered with. You can also do the same by writing a timestamp to a secure
system registry, for example.
Alternatively, a simpler solution would be to always ensure that the system clock is at least greater
than the license's created timestamp. Or even more simply: require your software be periodically
connected to the internet to fully revalidate via the API.
No offline-only solution will be 100% effective. When it comes to a licensing implementation, the only
thing you can fully "trust" is our API, which is verifiable using cryptographic signatures. Everything
else should be considered untrusted.
As such, the only way to know if a license is truly valid is to validate the key using our API,
because our API is the only trusted source for this information.