DEV Community

Cover image for Building Offline Auth for Indie Devs
System Locker
System Locker

Posted on

Building Offline Auth for Indie Devs

I run SystemLocker.net. It started in 2020 as a pretty standard licensing and authentication service: a desktop tool pings my servers on launch, the server checks that the key is valid, and then (maybe) lets the user in. For a lot of simple tools, that's all you need. My target audience was developers selling desktop software that has to be online anyway, and I've seen outstanding growth in that segment. Picking a niche has its benefits, and it helped that I already knew this crowd well. But over time, that internet-only market has gotten saturated, and I decided it was finally time to take a risk and see if I could offer something more flexible.

The hope is that offline support brings in indie game developers and folks building heavy desktop software like DAW plugins or 3D rendering tools. Their users are opening laptops on planes, working in basement studios, or relying so heavily on local processing that requiring an internet connection just doesn't make sense. If your licensing API pings the server on every launch, or uses an ongoing authentication session, then your app breaks the second the connection drops. Steam's DRM is an option, but it's heavy-handed and locks you into Steam. And if you're selling on itch.io or direct from your website, offline licensing usually means rolling your own half-baked, easily cracked checks.

With that market in mind, I built the Nightflyer auth API for SystemLocker.

The core idea is pretty straightforward: as long as the machine is online once, the application is authorized for a configurable timeframe. Developers can set the maximum offline authorization length from anywhere between 20 minutes (great for quick rendering jobs or memory-only modes) up to 90 days.

The client SDK tries to renew the token in the background whenever it catches a connection. If it can’t, it just keeps running the clock down until the next time it gets internet.

Building this meant solving a few fun headaches. First, you can’t just hand a plaintext JSON file to a desktop user and trust it. If you do, they’ll just edit the expiry date. So, Nightflyer issues Ed25519-signed tokens. The server signs a payload containing the machine ID and the expiry date, and the client verifies it using a hardcoded public key.

The second headache was the oldest piracy trick in the book: rolling the system clock back to 1999 to get infinite offline access. To counter this, the SDK writes a securely hashed "last known good time" to disk. Every time the app launches, it checks if the current system time is before that last known timestamp. If it is, the offline token voids itself. It’s not 100% uncrackable—nothing on a local machine is—but it raises the barrier high enough to stop casual tinkering.

Third, what happens if a user tries to copy the authorization onto another computer? Well, I already have a couple layers of protection for that: there's my hardware identification module, which runs a local fuzzy match based on secret sharing encryption. If the identification factors are mostly similar, the hardware token is unlocked and the server will approve the lease. On top of that, I built a log analyzer into System Locker that checks for things like rapid IP geolocation switching. If suspicious behavior is detected, devs can automatically or manually suspend the license key's access.

This whole feature has been a cool pivot for the service, and it builds on top of so much work that I've already done. It’s expanded my focus to a whole new crowd at a time when the indie game dev market is bursting with creativity.

I just pushed Nightflyer live. If you’re building a desktop app or game and have been dreading the offline licensing problem, go ahead and take it for a spin. I’d love to hear what I got wrong and what you need next. Standard client implementations of Nightflyer are available for C++ and .NET, including via the Unreal plugin store and through NuGet.

Top comments (0)