Product tour
Two licensing models, one library.
RockyGuard handles node-locked and floating licensing through a single C++17 library and a small set of CLI tools. No daemon to install, no SDK to register, no online activation step.
How it fits together
Two parties: you (the vendor) and your customer (the end user). The signing private key lives only on your build machine. The verification public key is embedded into the application you ship.
YOU YOUR CUSTOMER
---- -------------
private.pem ──┐
│
▼
license_create ──signs──▶ license.json ──ship──▶ end-user app
│
▼
LicenseVerifier
│
public.pem ──embedded into your app ──verifies──┘
The library never phones home. The only outbound network call from the customer side is anonymous TLS time-anchor verification to a rotating pool of public hosts — see /security for the full transport story.
Capabilities
Node-locked licensing
Each license is bound to one machine via a 4-component hardware fingerprint (MAC, CPU id, disk serial, motherboard id). Configurable match threshold (default: 2 of 4) tolerates ordinary hardware swaps without breaking customer access. Available on both tiers.
Floating licensing (Premium)
Run the floating license server on your customer's LAN; client applications check out a seat at startup, send heartbeats while in use, and release on exit. Configurable max-users cap, automatic seat reclamation on heartbeat timeout, optional TLS + payload signing for transport security.
Hardware fingerprinting
Cross-platform: WMI on Windows, /sys + /proc on Linux, IOKit on macOS (v1.3). Virtual-network adapter filtering excludes VMware, VirtualBox, Docker, and VPN interfaces from the MAC component so a customer hopping VPNs does not accidentally invalidate their license.
Anti-tampering
Multi-location time anchors (file + Windows registry where applicable) cross-check against the system clock to detect rollback attacks. Optional online time verification via TLS to a rotating pool of public hosts. Binary integrity self-check on shared-library builds.
Per-feature gating
License files carry a list of feature flags. Your application calls verifier.check_feature("export_pdf") to gate functionality. Feature names are arbitrary strings; you decide the taxonomy.
Grace period handling
Configurable per-license grace period. The verifier returns InGracePeriod (not Expired) for licenses that are past expires_at but within the grace window, so your application can warn the user without locking them out abruptly.
Two ways to protect a feature
Verification gives you a verdict. What you do with it is your call — and you can mix both patterns in one build, feature by feature.
Simple branch
Verify, then branch: if (result.status != LicenseStatus::Valid) return 1;. A few
lines, and enough for most products. Its honest limit: it is one boolean gating a branch, so a
one-instruction binary patch — a conditional jump turned unconditional — can flip
it in your own executable, where the library cannot reach.
Load-bearing
The licence physically carries an encrypted data key. You seal a real feature asset under it
at build time with rg_bind_asset, then open it at runtime through
LicenseAsset / unwrap_data_key(). There is no verdict to patch
— a forged or patched licence yields the wrong key and the feature just produces garbage.
It ships as a toolchain (the binder, a CMake helper, and rg_bind_lint) and is
incremental: protect one high-value feature, leave the rest on the simple branch.
No offline check can prevent tampering on hardware the attacker controls — it raises the cost. And RockyGuard cannot fix a branch in your own code; that is exactly what load-bearing binding removes.
Integration in four steps
The full Quick Start is in the docs. The shape of it:
Generate a keypair (one time)
Run license_keygen --private private.pem --public public.pem on a secure machine. Keep private.pem on that machine; it never leaves.
Embed your public key in your application
Paste the contents of public.pem into a static C++ string constant. Pass it to LicenseVerifier at construction time.
Issue a license to each end user
Run license_create with the end user's hardware fingerprint, expiry date, and feature list. Signed JSON file out. Email it to your customer alongside your application.
Verify on the customer's machine
One function of C++. Load the license, check the hardware match, optionally check feature flags. Every uncertain state returns a documented LicenseStatus.
#include <rockyguard/rockyguard.h>
int main() {
try {
rockyguard::LicenseVerifier verifier(PUBLIC_KEY);
auto result = verifier.load("license.json");
if (!result) { std::cerr << result.message << "\n"; return 1; }
if (!verifier.check_node_locked()) { return 1; }
} catch (const std::runtime_error& e) {
// Only fires if PUBLIC_KEY above is not parseable PEM -- a
// truncated or mis-pasted key. Never for a bad license file.
std::cerr << "Invalid public key: " << e.what() << "\n";
return 1;
}
// licensed and running
} This is the simple-branch pattern — a verdict gating an exit. Enough for most products, but it is one boolean an attacker can patch. For a high-value feature, bind an asset to the licence instead so there is no verdict to flip (see Two ways to protect a feature above). Read the full quick start →
Supported platforms
v1.3.2 ships Windows and Linux x64 (glibc 2.34+). macOS is built on request rather than shipped in the standard package, and a glibc-2.28 build for older distributions remains on the roadmap; both are tracked publicly in the future roadmap.
- Windows 10 / 11 x64 ✓ Supported
- Windows Server 2019 / 2022 ✓ Supported
- Linux x64 (glibc 2.34+) ✓ Supported
- macOS arm64 + x86_64 v1.3 (planned)
- Linux x64 (glibc < 2.34) v1.3 (manylinux_2_28)
Try it for 30 days
Download the demo bundle and verify the API in sixty seconds, or start a trial for a vendor license bound to your build machine.