Skip to main content
Frost Auth protects your licensing and authentication. Protecting your program itself is on you. Software running on a machine somebody else owns can always be modified by that person. Our job is to make cracking more expensive than buying, not to pretend it’s impossible. We are a licensing service, not an obfuscator.

What’s already enforced for you

These are decided server-side, on every request so your integration is not just a local if check that someone can patch out:
  • The server decides. Every activation and every heartbeat re-applies the same gates — kill switch, license state, blacklist, platform, version, and build hash from one shared module. Activation and heartbeat can never disagree about whether a license is valid.
  • Atomic device limits. Concurrent activations cannot overshoot a license’s device cap. Fifty simultaneous requests against a one-seat license grant exactly one.
  • Revocation on the next beat. A license is re-read from the database on every heartbeat rather than trusted from a token, so a revoked key stops working within one beat.
  • Vague refusals. An unknown key, a key belonging to another product, and a wrong password are all indistinguishable from the outside. Attackers cannot enumerate valid keys from the error responses.
In other words: your app only proceeds if the server says so and the server re-checks every time.

What you should do as a developer

  1. Do not remove the checks. Keep the refusal handling in place: if /activate or /validate returns anything other than success, stop. Don’t turn a failed validation into a warning.
  2. Use HTTPS safely. All traffic is HTTPS already; if you modify the request layer yourself, add certificate pinning so a man-in-the-middle can’t substitute a fake “valid” reply.
  3. Spread out your checks. Don’t only validate at startup. Use the heartbeat call POST /api/v1/validate on a timer every heartbeatSeconds and add your own integrity checks at multiple points in your code, not just one.
  4. Do not hardcode sensitive data. Never embed license keys or your webhook signing secret in source or shipped configs. Keep secrets in environment variables.
  5. Obfuscate your code, and turn on Build Hash checks. Even basic obfuscation or packing slows an attacker down; anti-debug / anti-inject is recommended where possible. Then register your binary’s SHA-256 under Settings → Build Hashes and enable Check Hash. A patched build then fails with INVALID_HASH even if it holds a valid key.
  6. Update your program often. The longer a build sits unchanged, the more time an attacker has to study it. Ship updates, re-register the new build hash, and bump your version so old cracked builds fall below your minVersion gate and stop activating.
These don’t make your program uncrackable nothing is. They make cracking it cost more than buying it.
If you’re verifying licenses from your own server (not from an application running on the user’s machine), you don’t need client-side hardening. Servers can’t be patched by end users, so network traffic between your server and Frost Auth doesn’t require anti-tamper protection.

Webhook signature verification — worked example

Frost Auth signs every webhook delivery so your server can prove it came from us. The X-Frost-Signature header arrives as t=<unix>,v1=<hmac>. You compute an HMAC-SHA256 of ${t}.${rawBody} using your webhook signing secret and compare. Your signing secret is generated automatically the first time you save a webhook URL under Settings → General → Webhook Deliveries. It looks like this:
Say Frost Auth delivers this payload to your endpoint:
And the request headers include:
The signed material is the timestamp concatenated with the raw body, separated by a dot:
HMAC-SHA256 that string with your secret whsec_4a59f8cab30447e28d56870004a6, and you get:
That matches the v1 value in the header. In your application, compare these using a constant-time function and reject the delivery if they don’t match:
Hash the raw request body before your framework parses it. Most frameworks parse JSON before your handler runs, and re-stringifying can reorder keys or change spacing, either one changes the hash and every delivery will look forged. Answer 401 when verification fails.
De-duplicate on X-Frost-Delivery. Delivery is at least once, never exactly once. If your server accepts a payload and crashes before responding, you will receive it again. Store each delivery ID you’ve processed and skip duplicates.