Official C++ SDK for AuthForge — credit-based license key authentication with Ed25519-verified responses.
Single-source CMake library. Public headers plus one implementation file (authforge_sdk.cpp) packaged as authforge_sdk, linking libsodium (Ed25519), OpenSSL (SHA and helpers), and libcurl (HTTP). Targets C++17. Works on Windows (MSVC), Linux (GCC/Clang), and macOS (Clang).
There is no C++ package registry for this SDK. Ship source via GitHub Releases (tag v*, source archive) or by cloning the repository, then build with CMake as below.
Add authforge_sdk.h and authforge_sdk.cpp to your project, then:
#include "authforge_sdk.h"
#include <iostream>
#include <string>
int main() {
authforge::AuthForgeClient client(
"YOUR_APP_ID", // from your AuthForge dashboard
"YOUR_APP_SECRET", // from your AuthForge dashboard
"YOUR_PUBLIC_KEY", // base64 Ed25519 public key from dashboard
"SERVER" // "SERVER" or "LOCAL"
);
std::string key;
std::cout << "Enter license key: ";
std::getline(std::cin, key);
if (client.Login(key)) {
std::cout << "Authenticated!" << std::endl;
// Your app logic here — heartbeats run automatically in the background
} else {
std::cout << "Invalid license key." << std::endl;
return 1;
}
return 0;
}cmake -S . -B build
cmake --build build
cmake --install build --prefix /your/prefixCMake must be able to find libsodium, OpenSSL, and libcurl (headers and libraries). Examples:
- Linux (Debian/Ubuntu):
sudo apt install libsodium-dev libssl-dev libcurl4-openssl-dev - macOS (Homebrew):
brew install libsodium openssl curl— if CMake does not pick up Homebrew paths automatically, setCMAKE_PREFIX_PATHto your prefix (often/opt/homebrewon Apple Silicon,/usr/localon Intel). - Windows: Install dependencies with vcpkg, then configure with its toolchain file, for example:
vcpkg install libsodium:x64-windows openssl:x64-windows curl:x64-windows
cmake -S . -B build -DCMAKE_TOOLCHAIN_FILE=%VCPKG_ROOT%\scripts\buildsystems\vcpkg.cmake
(Adjust triplet andVCPKG_ROOTto match your setup.)
find_package(AuthForge CONFIG REQUIRED)
target_link_libraries(yourapp PRIVATE AuthForge::authforge_sdk)| Parameter | Type | Default | Description |
|---|---|---|---|
appId |
string | required | Your application ID from the AuthForge dashboard |
appSecret |
string | required | Your application secret from the AuthForge dashboard |
publicKey |
string | required | App Ed25519 public key (base64) from dashboard |
heartbeatMode |
string | required | "SERVER" or "LOCAL" (see below) |
heartbeatInterval |
int | 900 |
Seconds between heartbeat checks (any value ≥ 1; default 15 min) |
apiBaseUrl |
string | https://auth.authforge.cc |
API endpoint |
onFailure |
std::function | nullptr |
Callback (const string&, const exception*) on auth failure |
requestTimeout |
int | 15 |
HTTP request timeout in seconds |
ttlSeconds |
int | 0 (server default: 86400) |
Requested session token lifetime. 0 means "server default". Server clamps to [3600, 604800]; preserved across heartbeat refreshes. |
hwidOverride |
string | "" |
Optional custom hardware/subject identifier. When non-empty, the SDK uses this value instead of generated device fingerprint data. |
authforge::AuthForgeClient client(
"YOUR_APP_ID",
"YOUR_APP_SECRET",
"YOUR_PUBLIC_KEY",
"SERVER",
900,
authforge::AuthForgeClient::kDefaultApiBaseUrl,
onFailure,
15,
0,
"tg:" + std::to_string(telegramUserId) // or "discord:" + std::to_string(discordUserId)
);- One
Login()orValidateLicense()call = 1 credit (one/auth/validatedebit each). - 10 heartbeats on the same session = 1 credit (debited on every 10th successful heartbeat).
Any heartbeat interval is safe economically: a desktop app running 6h/day at a 15-minute interval burns ~3–4 credits/day; a server app running 24/7 at a 1-minute interval burns ~145 credits/day. Choose your interval based on how quickly you need revocations to propagate (they always land on the next heartbeat).
| Method | Returns | Description |
|---|---|---|
Login(const std::string&) |
bool |
Validates key and stores signed session (sessionToken, expiresIn, appVariables, licenseVariables) |
ValidateLicense(const std::string&) |
ValidateLicenseResult |
Same /auth/validate + signatures as Login; does not persist session or start heartbeats; never calls onFailure or std::exit — inspect valid / errorCode |
SelfBan(...) |
bool |
Requests /auth/selfban to blacklist HWID/IP and optionally revoke (session-authenticated only) |
Logout() |
void |
Stops heartbeat and clears all session/auth state |
IsAuthenticated() |
bool |
True when an active authenticated session exists |
GetSessionDataJson() |
std::optional<std::string> |
Full decoded payload JSON |
GetAppVariablesJson() |
std::optional<std::string> |
App variables JSON (if present) |
GetLicenseVariablesJson() |
std::optional<std::string> |
License variables JSON (if present) |
SERVER — The SDK calls /auth/heartbeat every heartbeatInterval seconds with a fresh nonce, verifies signature + nonce, and triggers failure on invalid session state.
LOCAL — No network calls. The SDK re-verifies stored signature state and checks expiry timestamp locally. If expired, it triggers failure with session_expired.
If authentication fails, the SDK calls your onFailure callback if one is provided. If no callback is set, the SDK calls std::exit(1) to terminate the process. This is intentional — it prevents your app from running without a valid license.
ValidateLicense() always returns a ValidateLicenseResult and does not invoke onFailure or exit the process.
Recognized server errors:
invalid_app, invalid_key, expired, revoked, hwid_mismatch, no_credits, app_burn_cap_reached, blocked, rate_limited, replay_detected, app_disabled, session_expired, revoke_requires_session, bad_request, system_error
Request retries are automatic inside the internal HTTP layer:
rate_limited: retry after 2s, then 5s (max 3 attempts total)- network failure: retry once after 2s
- every retry regenerates a fresh nonce
authforge::AuthForgeClient client(
"YOUR_APP_ID",
"YOUR_APP_SECRET",
"YOUR_PUBLIC_KEY",
"SERVER",
900,
authforge::AuthForgeClient::kDefaultApiBaseUrl,
[](const std::string& reason, const std::exception* exc) {
std::cerr << "Auth failed: " << reason << std::endl;
if (exc) std::cerr << "Details: " << exc->what() << std::endl;
std::exit(1);
}
);Use SelfBan(...) when anti-tamper checks trigger:
// Post-session (authenticated): defaults to revoke + HWID/IP blacklist.
client.SelfBan();
// Pre-session: pass license key, SDK automatically disables revokeLicense.
client.SelfBan("AF-XXXX-XXXX-XXXX");
// Custom flags:
client.SelfBan("", "", false, true, true);SelfBan(...) chooses request mode automatically:
- Uses post-session mode when a session token is available (
sessionTokenarg or current SDK session). - Falls back to pre-session mode with
licenseKey+ nonce + app secret. - In pre-session mode, revoke is always disabled client-side to avoid unsafe key revocations.
-
Login — Uses
hwidOverridewhen non-empty; otherwise collects a hardware fingerprint (MAC, CPU, disk serial). It then generates a random nonce and sends everything to the AuthForge API. The server validates the license key, binds the HWID, deducts a credit, and returns a signed payload. The SDK verifies the Ed25519 signature and nonce to prevent replay attacks. -
Heartbeat — A detached background thread checks in at the configured interval. In SERVER mode, it sends a fresh nonce and verifies the response. In LOCAL mode, it re-verifies the stored signature and checks expiry without network calls.
-
Crypto — Both
/validateand/heartbeatresponses are signed by AuthForge with your app's Ed25519 private key. The SDK verifies every signedpayloadusing your configuredpublicKeyand rejects tampered responses.
The shared test_vectors.json file validates cross-language Ed25519 verification behavior.
- C++17
- libsodium
- OpenSSL
- libcurl
MIT