What to protect
When packaging an application to be deployed to a Modern On-prem environment, there are a number of concerns:
- Ensuring only paying customers are able to run the software.
- Enforcing expirations of licenses, including the enforcement of trial or Proof-of-Concept licenses.
- Controlling feature-based and usage-based entitlments for each end customer, facilitating and enforcing product assortment.
- Limiting the number of instances of an application that can be run by a single end user.
While running on-prem software in an internet-connected environment makes a lot of this much easier to enforce, Modern On-prem means embracing variety of deployment targets. This includes Airgapped environments with no outbound connection. Because of the variety of targets, this licensing conversation is focused on ways to do enforcement when an application does not have an outbound internet connection.
Two trust models
When thinking about licensing, it’s valuable to consider 2 different trust models. They are broken down here into High Trust and Low Trust. These trust levels encompass:
- Risk that an end customer will violate a software contract and use an application after they are not licensed to do so, or enable features they are not paying for.
- Risk that an end customer will accidentally or intentionally leak an application’s source code, configuration, or binary artifacts.
In all three cases, we’ll find that the effort applied by the vendor to secure the software usually matches the effort required by the end customer to circumvent any license enforcement measures. This is obviously a spectrum, and vendors should carefully weigh the risks and costs of different levels of protection.
In a high trust scenario, little licensing enforcement is necessary. End users that fall into the “high trust” category are not only those that fall in the “family and friends” category, but also large enterprises that would be wary of being in violation of a software contract. In a high trust scenario, a vendor might only limit access to the artifacts themselves. For example, a vendor might give out docker registry credentials to users whom they’d like to be able to run the software, controlling access to the artifacts, but not enforcing any restrictions at runtime.
The effort here for vendors is low. While the other trust levels might require some changes to application code and architecture so that licensing can be enforced at runtime, high trust environments don’t generally need these measures. Similarly, the effort for end users to circumvent is low – it should be fairly trivial for an end user who acquires the application artifacts and configuration to run them without acquiring a proper license.
When giving out software to general users, maybe via a public download page or public docker container, it’s worth considering a Low Trust licensing models. In this case, vendors should instrument application code with licensing logic to validate that the user running the application code is authorized to do so. Most implementations of the low-trust model involve some version of:
- Vendor embeds a public key in the application artifact, obfuscating the contents of this key if possible
- Vendor generages a license internally, signed with a private key they control. Provide this license to each customer.
- Application requires end users to supply this license as an environment variable or mounted file.
- Application code checks either at startup or during regular operation for a valid license containing an expiration date and other entitlements.
While this is a substantial effort for a vendor, the effort for an end user to circumvent license checks is also quite high. For a compiled, obfuscated artifact, a user would need to:
- Decompile and de-obfuscate the artifact
- Discover the public key
- Modify it to the public key of a keypair they control
- Recompile the artifact with the injected public key
- Create a license signed with their own key and provide it to the application
- Repeat stepds 1-4 for every new version of the application
While 100% airtight licensing for on-prem is impossible, with a combination of proper contract and some strong cryptographic license enforcement, its possible to have very high confidence that application use is being restricted to authorized users. When using low-trust methods, its important to sign not only the expiration date, but also any other entitlements, like which features are enabled and value-based limitations like number of users or amount of data throughput allowed.
Other things to consider
When shipping proprietary algorithms or machine-learning models that are core to the business, it might be valuable to further protect source code through obfuscation. There are many tools that can help make it harder to discern the intended functionality of an application. It’s also worth noting that as obfuscation tools evolve, so do de-obfuscation tools that are avaialable to malicious users looking to circumvent licensing.
Bridging this might mean, rather than mounting a license as a file or an environment variable, that vendors will want to embed a small webserver with an application that serves up the signed license contents. That way, in online scenarios, license information can be pulled from an always-up-to-date licensing server controlled by the vendor.
Because the license is signed, and a high amount of effort is required to change the public key embedded in the source code, its safe to allow the licensing server URL to be configured by an end user. In offline scenarios vendors can provide a microservice that serves a mounted license file, but they should still validate the served license as close as possible to the core application logic (i.e. not in a separate service).
Online installs also make it much easier for vendors to limit the number of instances running per license using methods like MAC fingerprinting, etc.
By and large the best way to enforce licensing is to lay out rules in the contract itself. As noted, most of the enterprise users who will be the core of a Modern On-Prem vendor’s business will be wary of violating a software contract. Different legal teams will have different needs, but in general, its valuable to prohibit end users from intentionally reverse-engineered the software for any purpose, including for circumvention of licensing and entitlement controls.
Since most of the customers who might try to circumvent licensing will probably be independent users or small companies, it can be valuable to consider some kind of “community licensing”. In this case, users are able to use a free version of the application with limited functionality. This can discourage people from reverse-engineering licensing just to gain access to an application.
Licensing is very much a cross-functional concern, spanning Sales, Legal, Support, and Engineering. This is covered in more depth in Cross-Functional On-prem Delivery.