How Do You Revoke a License in a Bank That Can’t Even Ping Google?

Table of contents
- Business Landscape and Challenges
- Design Objectives
- Hardware-Bound Licensing
- Introducing the License Revocation List (LRL)
- Why Sign the LRL Instead of Encrypting It?
- Validity Periods and Duplicate Risk
- Why Not Check Only at Application Startup?
- Automation Through the Public Support Portal
- Security Considerations
- Operational Trade-Offs
- Lessons Learned
- Conclusion

Working on enterprise software products used by banks and other financial institutions, I’ve encountered many interesting challenges. One that stands out is managing software licensing in offline, highly regulated environments.
Financial institutions often need to migrate licenses between servers due to operational changes, infrastructure refreshes, or hardware failures. But these same institutions frequently operate air-gapped networks for security and compliance reasons. There’s no possibility of cloud-based license checks or remote revocations.
That constraint set the stage for designing a licensing system that could function entirely offline — a solution that turned out to be far more nuanced than simply generating a license file and sending it over.
Business Landscape and Challenges
Financial institutions run environments unlike those in most other sectors.
They operate air-gapped networks as a matter of security and regulatory compliance. These systems have no connection to the internet — not even for simple check-ins.
Yet the stakes for proper licensing remain substantial:
Revenue risk. Running duplicate licenses across multiple servers means potential lost revenue for software vendors.
Compliance risk. Regulators may demand proof that software is properly licensed and deployed only on authorized systems.
This creates an unavoidable tension:
We need to protect intellectual property and licensing revenue, but we have no remote channels to enforce license controls.
Design Objectives
Given this reality, I defined several clear objectives for any licensing system I’d design:
Prevent unauthorized duplication. A license should only run where it was intended to run.
Work fully offline. Air gaps aren’t a suggestion — they’re policy.
Remain practical for operations. Security solutions that can’t be operationalized are destined to fail.
Support auditability. In financial environments, audit readiness isn’t optional.
Minimize manual overhead. Neither customers nor vendors want to live inside a ticket queue for routine licensing changes.
Here’s the solution I designed — a framework that balances offline constraints with practical business and technical realities.
Hardware-Bound Licensing
First, every license is tied to a unique hardware fingerprint specific to the server it’s issued for.
If a license file is copied to a different machine, the application detects the mismatch and refuses to operate. It’s a straightforward first layer of defense against basic license duplication.
However, hardware binding only solves part of the problem. The more significant challenge is managing license transfers and revocations in a way that remains enforceable offline.
Introducing the License Revocation List (LRL)
Consider this scenario:
An enterprise customer has Server A running under a valid license. At some point, they decide to migrate operations to Server B and request a new license for that machine. Meanwhile, Server A continues running under its original license.
At that point, two servers could operate concurrently under what’s effectively a single license — a situation problematic for revenue protection and compliance.
This is why I introduced the concept of a License Revocation List (LRL).
The LRL functions as a signed record of licenses that should no longer be considered valid. It includes:
IDs of revoked licenses
Associated hardware fingerprints
Revocation timestamps
A valid_until timestamp indicating when the LRL itself expires
The LRL is digitally signed. This ensures its integrity and authenticity. Customers can read it — but they cannot modify it without detection.
{
"revoked_licenses": [
{
"license_id": "ABC123",
"hardware_fingerprint": "XYZ987",
"revoked_at": "2025-06-01T12:00:00Z"
}
],
"valid_until": "2025-07-01T00:00:00Z",
"signature": "<digital_signature>"
}
Why Sign the LRL Instead of Encrypting It?
One of the first questions I encountered was:
“Shouldn’t the LRL be encrypted so customers can’t see its contents?”
The answer is no, and here’s why:
Encryption protects secrecy.
Digital signatures protect integrity.
Since each enterprise’s LRL only contains data about their own licenses, there’s no cross-tenant data requiring secrecy. Customers seeing their own revoked license IDs isn’t an issue.
The critical goal is ensuring no one can modify the LRL undetected. Digital signatures achieve that without introducing unnecessary complexity or operational friction.
Validity Periods and Duplicate Risk
Here’s the practical challenge:
If I revoke Server A’s license, how can I ensure Server A actually stops running?
These servers never connect back to me.
I can’t push updates or remotely disable anything.
That’s why every LRL carries a valid_until timestamp. The application routinely checks whether the LRL is still valid. If the LRL has expired, the application refuses to start — or gracefully shuts down if it’s already running.
This forces the customer to replace the LRL file on a regular basis. It’s the only way to ensure revoked licenses eventually stop working, even in offline environments.
But this introduces a trade-off:
If the LRL is valid for 30 days, theoretically both Server A and Server B could run in parallel for up to a month. That’s the unavoidable reality of operating in air-gapped environments. The goal is to keep that potential window as short as practical without imposing unreasonable operational burdens on the customer.
License check flow in the app layer
Why Not Check Only at Application Startup?
It’s tempting to think:
“We’ll check the LRL when the application starts. That should be enough.”
However, enterprise servers often run continuously for months or even years without a restart. Relying solely on a startup check leaves a significant blind spot.
This is why the application also validates the LRL periodically at runtime — typically daily or hourly — to ensure licenses don’t continue running indefinitely under an expired revocation list.
Automation Through the Public Support Portal
Another critical dimension of this solution is avoiding manual bottlenecks.
Without automation, every license transfer or migration would require manual review, updates, and communication. That’s neither scalable nor practical for enterprise operations.
So I built this system into a public support portal.
Streamlined support request
The flow looks like this:
The customer logs in and requests a license change.
They provide the hardware fingerprint for the new server.
The portal:
This keeps the process efficient and removes unnecessary human friction, allowing both sides to operate smoothly.
System action flow
Security Considerations
A topic that often comes up in these discussions is reverse engineering.
Some ask:
“Couldn’t someone extract the public key from your application binary and forge an LRL file?
It’s a fair question.
The public key is embedded in the binary because the application needs it to verify digital signatures on the LRL. Anyone sufficiently motivated could extract that key.
But there’s a critical distinction:
The public key verifies signatures.
The private key creates them.
Extracting the public key lets someone check whether an LRL is legitimate. It does not enable them to forge a new, valid LRL. Without the private key, they cannot produce a valid signature.
This is why digital signatures remain a powerful tool for maintaining integrity, even in offline systems.
Operational Trade-Offs
This system isn’t perfect. No offline solution can be.
Enterprise customers still carry operational overhead:
They must download new LRL files periodically.
They need to deploy those files across potentially large infrastructures.
That introduces friction. However, there’s a balance to strike.
A 7-day validity period would minimize duplicate license risk but impose significant operational costs.
A 90-day validity period reduces customer effort but increases the risk window.
After evaluating the realities of enterprise change windows and maintenance cycles, I concluded that a 30-day cycle offers the best balance:
It fits within typical monthly maintenance processes.
It limits duplicate license exposure to a manageable window.
It keeps the burden reasonable for customers.
Lessons Learned
Here’s what designing this system reinforced for me:
Perfect security doesn’t exist — especially in offline environments. The goal is to raise the cost and complexity of misuse high enough that it becomes impractical.
Automation isn’t a luxury; it’s essential. Customers and vendors alike have limited capacity for manual licensing processes.
Architecture is as much about people as it is about technology. Security measures that are impossible or painful to deploy won’t succeed, no matter how technically sound they might be.
Conclusion
Designing a licensing system for offline enterprise environments, especially in the financial sector, has been one of the most fascinating — and humbling — challenges I’ve tackled as a product architect. It’s a space where cryptography, operational constraints, and business realities intersect in uniquely complex ways.
It’s not about achieving perfect protection. It’s about designing something secure enough to deter misuse, practical enough for customers to deploy, and efficient enough to avoid becoming a full-time operational burden.
I’d be interested to hear from others who have navigated similar challenges in regulated or offline environments. How have you balanced security, operational realities, and business needs in your architecture?
Subscribe to my newsletter
Read articles from Arda Eren directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
