Skip to main content
AuthForge provides the infrastructure for license verification, but how you integrate it affects how resistant your application is to cracking and abuse. Follow these practices to maximize protection.

Protect your App Secret

The App Secret is the most sensitive value in your integration. It’s used to authenticate /auth/validate requests. If an attacker obtains it, they can impersonate your app and consume licenses/credits. Response signatures are verified with your app’s public key, but protecting the App Secret still matters because it gates every new login.
1

Never hardcode in plain text

Don’t embed the secret as a string literal in your source code. Use environment variables, encrypted config files, or a secrets manager.
2

Don't ship it in air-gapped builds

Offline license files (loginFromFile) verify with the app id and public key only. Construct those clients with an empty / omitted App Secret so the secret is not sitting in a binary that never phones home.
3

Never log the secret

Ensure your logging framework doesn’t accidentally capture it. Redact secrets from error reports and crash dumps.
4

Rotate if compromised

If you suspect the secret has been leaked, rotate it immediately in the dashboard (App Settings → Rotate Secret). Running clients fail on their next server call (activation or online check-in), prompting a restart with the new secret.
5

Don't commit to source control

Add your config file or .env to .gitignore. Use CI/CD secrets for deployment.

Authenticate early

Call login() as early as possible in your application’s startup. Don’t let the app run meaningful code paths before authentication succeeds.

Minimize error details

Don’t expose internal error information to the user. Detailed error messages help attackers understand your verification logic.
Log the detailed error internally for debugging, but show only generic messages in the UI.

Enable online check-ins for high-value software

The default grace period relies on local re-verification of the signed session, which can be bypassed by:
  • Freezing or rolling back the system clock
  • Patching the SDK to skip the local signature check
Online check-ins require a valid signed response from the AuthForge API on every interval and catch revocations within minutes. For software where piracy has significant business impact, enable online check-ins (online_heartbeat / onlineHeartbeat / OnlineHeartbeat).

Don’t trust the client

Your binary can be decompiled, patched, and modified. Design with this assumption:
  • Don’t gate features with a simple boolean. Instead of if (licensed) { runProFeature() }, read license variables and check specific capabilities.
  • Don’t store the license status in a predictable location. Avoid a single isLicensed = true field that can be patched.
  • Spread auth checks. Don’t check the license in a single function; verify state at multiple points in your application.

Obfuscation (defense in depth)

While not a substitute for proper license verification, code obfuscation raises the difficulty of cracking:

Network security

  • Always use HTTPS. The SDK communicates with https://auth.authforge.cc by default. Never override the base URL to use HTTP.
  • Pin the certificate if your platform supports it, to prevent MITM with a trusted CA compromise.
  • Validate the nonce on /auth/validate. The SDK does this automatically; the nonce in the response must match the one you sent. Heartbeats don’t use nonce replay detection; they rely on the signed short-lived session token instead.

Self-ban safely

If your anti-tamper checks detect runtime manipulation, call /auth/selfban to lock out future auth attempts.
  • Prefer post-session self-ban for revoke. Revoke by key only when you have a valid sessionToken from a successful login.
  • Never revoke by key pre-session. Before activation, a licenseKey value can be attacker-controlled. Revoking at that stage can ban random or other customers’ keys.
  • Use pre-session for containment only. Pre-session self-ban should be limited to blacklistHwid and/or blacklistIp.
  • Keep nonce hygiene. Pre-session self-ban uses nonce replay protection; always send a fresh nonce.
  • Treat self-ban as high risk action. Add local anti-tamper confidence thresholds so noisy detections do not mass-ban legitimate users.
The API enforces this rule: pre-session self-ban requests with revokeLicense: true are rejected with revoke_requires_session.

Rate limiting

/auth/validate is rate-limited in addition to API Gateway throttling:
  • Per IP address: up to 30 /auth/validate requests per minute.
  • Per license key: up to 5 /auth/validate requests per minute (in addition to the per-IP limit). Unlimited-seat (shared) keys get this allowance per device instead, with a ceiling of 300 per minute across all devices on the key.
/auth/heartbeat is rate-limited per license (up to 6 requests per minute) but not per IP at the application layer; a flood of heartbeats beyond that only burns the victim app’s credits (which the server already handles via no_credits / app_burn_cap_reached). API Gateway burst/sustained throttling still applies. Unlimited-seat keys get the 6/min allowance per device here too, with a ceiling of 3,000 per minute across all devices on the key - higher than validate’s because the device comes from the signed session token rather than the request body. Official SDKs apply retry logic automatically when /auth/validate returns rate_limited. If you are building a custom integration, treat rate_limited as a transient error: implement exponential backoff (with jitter) and avoid tight retry loops so you stay within the limits above.

HWID and IP security

Use blacklists and whitelists to control access:
  • Blacklist known-bad HWIDs: If you discover a cracked copy, blacklist the HWID to prevent re-authentication.
  • Use IP whitelists for enterprise: Restrict authentication to known office IP ranges.
  • Monitor for anomalies: If a license key is being validated from many different HWIDs (more than the slot count allows, via resets), investigate abuse.

API key security

For your Developer API keys:
  • Don’t expose API keys in client-side code. API calls should only be made from your server.
  • Use separate keys for different environments (development, staging, production).
  • Audit key usage: If a key is compromised, delete it and create a new one. Keys are scoped to your account, so a compromised key gives access to all your apps’ license management.

Webhook security

  • Always verify the signature on incoming webhook requests using the X-AuthForge-Signature-V2 header, and reject requests whose t is more than 5 minutes old. The legacy X-AuthForge-Signature header doesn’t cover the timestamp, so it can’t stop replays.
  • Use HTTPS for your webhook endpoint.
  • Don’t expose your webhook secret in client code or logs.
  • Validate the event type: only process events you expect.
See Webhooks: Signature Verification for implementation examples.

Incident response

If you discover a cracked version of your software:
  1. Identify the HWID from your auth logs (if available via webhooks or the dashboard).
  2. Blacklist the HWID to block future authentication from that machine.
  3. Rotate your App Secret if you suspect it was extracted from the binary.
  4. Update your binary with stronger obfuscation and push an update.
  5. Review your integration against this checklist.