C# SDK
Works on .NET Framework 4.7 / 4.8 / 4.8.1 and .NET 5 / 6 / 8+. No NuGet packages.
Download AtlasAuth.cs from the sidebar and add it to your project. Create a client with your app id and public key from the dashboard:
var client = new AtlasAuth.AtlasClient(
"YOUR-APP-ID",
"YOUR-PUBLIC-KEY");Init
Call first. Opens the session. Returns false if the app is in maintenance or disabled, or your version is blocked.
if (!await client.Init())
{
Console.WriteLine(client.StatusMessage);
return;
}Login
Username and password.
if (!await client.Login(username, password))
{
Console.WriteLine(client.LastError);
return;
}Register
Create an account that redeems a key. The user logs in with username and password after that.
if (!await client.Register(username, password, licenseKey))
{
Console.WriteLine(client.LastError);
return;
}License
Sign in with just a key, no account.
if (!await client.License(licenseKey))
{
Console.WriteLine(client.LastError);
return;
}Heartbeat
Start it right after Init, before login. You do not need to be logged in. It pings the server on an interval and kicks the user when their key expires, their session is killed, the app goes down, or they are banned.
It is also an anti-tamper check. If the heartbeat thread is paused or suspended, the session goes stale and the user is kicked. Both the server and the SDK measure the gap, so freezing the client clock does not hide it. Running it from Init catches a paused thread before the user ever logs in, which is when crackers try to jump past auth.
client.StartHeartbeat(reason =>
{
Console.WriteLine(reason);
Environment.Exit(0);
});Gate anything sensitive on SessionAlive. It is false the moment the heartbeat stalls, so a frozen heartbeat thread stops your app from working.
if (!client.SessionAlive) return; // heartbeat stalled or session dead
// run protected codeVariables
Fetch an app variable. Returns null if it does not exist, or if it is login-gated and you are not logged in.
string value = await client.Var("download_url");Protect content
Stops a cracked copy from working. Put the values your app needs (a download link, an unlock code, a config string) in the dashboard as secret variables, then read them at runtime. A real logged-in user gets the real value. A cracked or faked copy gets a wrong one, so the app can't run.
Read a value and use it:
long offset = await client.SecretLong("aim_offset");
Write(gameBase + offset, value);For a real user offset is correct. For a cracked copy it is wrong, and the app breaks on its own. SecretString returns text, SecretBytes returns raw bytes. Don't check if it worked, just use it.
Protect a few small values you actually use, not one big value at startup, and change them when you ship an update.
To ship a whole encrypted file or blob inside your app: enter the variable name and click Generate to make a key, encrypt your value in the Encrypt a value box, paste the result into your app, then unlock it at runtime with the same variable name.
string url = await client.DecryptSecret("content_key", cipher);A wrong or missing key makes DecryptSecret fail (throw) instead of returning anything, so a cracked copy gets an error, not the real value. The difference from SecretLong: that one hands back a wrong value, DecryptSecret refuses. Either way the cracked copy never gets the real thing. The value is also locked to this app and variable name.
Log
Send a line to the app log.
await client.Log("info", "started");Status and news
Public. No login needed.
var status = await client.Status(); // status.Status, status.Online
var news = await client.News(); // List<NewsItem>HWID seed
Optional. A fixed seed gives the same HWID on any machine, so you can move your own key. Others cannot use it.
var client = new AtlasAuth.AtlasClient("YOUR-APP-ID", "YOUR-PUBLIC-KEY", "your-secret-seed");Logout
await client.Logout();Reading the user
After a successful login:
client.Username; // string
client.Expiry; // DateTimeOffset? (null = lifetime)
client.LoggedIn; // bool
client.LastError; // last failure messageHarden further
The SDK verifies every response and delivers your keys only to a live session, but the binary still runs on the attacker's machine. To raise the cost:
- Consume decrypted values, never gate on a bool. If flipping one branch unlocks your app, nothing else here helps.
- Encrypt more, smaller pieces through the secret channel, and re-key them each update.
- Run a protector on your shipped build (ConfuserEx, or a commercial packer). Virtualize the few methods that verify and decrypt.
- Code-sign your build so users can spot tampered copies.
- Rotate your app key if you suspect a leak, and watch HWID churn and sessions in the dashboard.
No client-side check is unbreakable by someone who owns the machine. These raise the time and effort, they do not make it impossible.
