Protecting containerized applications (e.g. in docker) is similar in many ways to non-containarized applications. The major difference is that, in most cases, there is no reliable way to uniquely identify an instance. And even if it would be possible to identify them, it might not be desirable since oftentimes containers spin up and down very frequently.
More specifically, the challenge from a software licensing perspective is to prevent end users from exceeding the maximum number of concurrent instances.
Solution
The general solution to restrict the number of concurrent users is to use a floating license model (allows to restrict how many instances can run concurrently) and generate a random identifier upon application start (i.e. not relying on any OS information).
If your clients will have an internet connection, your application can call the Cryptolens API directly as described here. In this case, Cryptolens will be responsible for keeping track of all active instances.
If your clients will be offline, they can install a local license server that will keep track of all instances. A tutorial on how it can be setup can be found here.
If you would have any questions or need advice on how to protect containerized applications, please reach out to us at [email protected].
Not a customer yet? Sign Up for a free trial and implement our software licensing system within minutes.
Being able to find anomalies in software license logs can help you as a software vendor to detect whenever your customers experience problems (for example, with license verifications) or to detect other types of abnormal behaviour (for example, fraudulent usage).
As the amount of data increases, detecting anomalies becomes time-consuming and, in some cases, unfeasible.
To help you to find anomalies, we have released a new dashboard that will automatically let you know of any behaviour that does not conform to the norm.
How it works
The anomaly detection module works by learning the distribution of your historical data. Any group of samples that does not conform to the norm will be classified as an anomaly.
Under the hood, an autoencoder-based neural network is used (displayed below), where the goal is to train an identity function. Since there is a bottleneck layer in the middle, it forces the network to find a compressed representation of your data. As a result, it will succeed to find such representation for most of the samples. Those samples where the network struggles to find a compressed representation are classed as anomalies.
A sample can be classified as an anomaly either by its reconstruction loss (anomalies will have a higher reconstruction loss than normal samples) or by using the low-dimensional representation (the bottleneck layer) in a different method (for example, in a clustering method). In the first case, the challenge is to pick the right method to decide the decision boundary and in the latter to pick a clustering method that will be able to differentiate between normal samples and anomalies. You can read more about how it works in the following article.
Getting started
The anomaly detection module is can be accessed on the following page. It is continuously being updated, so if you notice anything or have any feedback, please reach out to us at [email protected].
Not a customer yet? Sign Up for a free trial and implement our software licensing system within minutes.
We are continuing our work on making the .NET SDK cross platform. In the latest release of our .NET library, we have added support for machine code computation on Raspberry Pi and improved the existing support for Linux.
Image of Raspberry Pi 4 Model B. Credits Michael Henzler. License CC BY-SA 4.0.
From a licensing perspective, being able to identify a device is important in order to make it possible to limit the number of end users that may use the same license. Treating a device id as an end user is very common, even though an end user can also be defined in other ways too (for example, to include the process id or username).
In that version of the library, both Helpers.GetMachineCode and Helpers.GetMachineCodePI work the same way. If you prefer to use the pre-compiled binaries, these can be obtained here. It’s important to use the ones in the “Without System.Management” folder.
How it works
Every Raspberry Pi board comes with a unique serial number. The updated methods first determine whether it is a Raspberry Pi board, and if it is, hash the serial number. The machine code is of the structure “RPI_{SHA256(serial number)}”. More technical information is available in the release notes.
This post is a continuation of Licensing software to customers with thousands of employees (B2B) where we talked about common issues that might arise when licensing software to larger clients. In this post, we will focus on the case when your clients do not have internet access (e.g. hospitals) or where you would like to have more control over who can use your software within the client company.
Use cases
Specifically, we will explore the following cases:
Controlling who can activate: Typically, new devices are activated automatically, until the maximum number of machines is reached. However, you might not want that to happen, especially if you sell to a specific department in the company and don’t want users from other departments to use the software.
Companies with no internet access: When your clients don’t have internet access, the solution is to send them a license file where all devices are already activated. However, this quickly becomes problematic if there are thousands of employees whose device needs to be activated.
Solution
Both of the cases above share a common problem: gathering machine codes from a large number users and then activating them from your end.
Gathering machine codes from all employees
To gather machine codes (aka. hardware ids) from all employees, Customer IT needs to run a special batch script. We have prepare one that can be downloaded here. Typically, your client will use a system similar to Microsoft SCCM, which allows the customer IT to run a script on all computers and collect the result.
Activating multiple devices at once
Once the customer IT has collected all the machines, they can send the file with all the results to you. Our script will compute both the machine code and a device name (to make it easier for customers to differentiate between different activations). The can then be activated on the following page.
In this post, we would like to share several new tools and practical tips that are tailored to those of you that sell to larger companies. We will cover the common issues such as management of large number of activations, offline access and reporting.
Recommended approach
When selling to larger companies, we recommend to issue one license key per client and keep track of the employees using activations. For those familiar with Flexera terminology, an activation is the same as a seat. There are two ways to restrict the number of active employees that you can your software:
Node-locked: in the node-locked model, once a device is activated, it needs to be manually deactivated if the customer wants to use that seat on a different machine.
Floating license: in this model, unused devices will automatically be deactivated when not in use, allowing your customers to install your application on any number of machines and use it concurrently on a limited number machines.
If you want to have different number of seats per feature, our recommendation is to issue a separate license per feature.
Managing activations
Typically, it’s more convenient to issue one license key per company and then restrict the number of end users (aka. machine codes/seats) to the number of workstations that will run the application. However, it can quickly become hard to manage all the end users, especially when employees leave and your customers want to free up unused seats.
To solve this problem, we have introduced the concept of “friendly name” and improved the license portal to allow your customers to query on it.
A friendly name is a way to add a human-readable name to each activated device, so that it is possible to tell which user it belongs to. Normally, machine codes are an unreadable string, and look similar to “9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08“. To make it easier to distinguish between these, you can add an optional paramater FriendlyName when activating/verifying a device. For example, if you have integrated our key verification script, you can add the friendly name as shown below:
var result = Key.Activate(token: auth, parameters: new ActivateModel()
{
Key = licenseKey,
ProductId = 3349,
Sign = true,
MachineCode = Helpers.GetMachineCode(),
FriendlyName = Environment.MachineName
});
Our recommendation is to use Environment.MachineName as the friendly name, since if your customers use Active Directory, they will be able to see it in the admin dashboard:
To make it easier for your customers to find unused devices and deactivate them, we have added new tools in the customer portal and a new permission to deactivate devices in the customer object. There’s also a new sign up link that you can use to allow your customers to sign up with deactivation permission.
Once they are logged in, they can click on the “manage licenses” tab, and they will see a pag similar to the one below:
Here they can either manage all the activations/used seats and remove unused ones. For example, to find all my activations, the admin could click on “manage activations globally” and search for “artem(at)cryptolens.io”:
Offline access
Oftentimes, larger companies have strict constraints on internet connectivity. They may want to have their devices completely offline or without direct internet access. When your customer puts forward this constraint, our recommendation is to offer them to use our license server as a first step, which tends to be accepted in most cases. The idea behind the license server is to act as a reverse proxy, in other words, it allows devices on your customers’ network to communicate with Cryptolens through the license server, without the need of having a direct internet access by themselves. As a result, only the license server needs to be able to access the internet. Furthermore, your customers can restrict the internet access of the license server to only be able to access Cryptolens. Instead of having to do that for all their devices, they can focus on protecting one workstation running the license server. The license server is freely available on GitHub.
If your customers want to have their devices completely offline, you can use the idea of offline activation, by delivering the license file using eg. a USB stick. In simple terms: normally, when you call Key.Activate to verify a license key, you receive a signed JSON response that our client libraries convert into a language-specific object. For example, in .NET, it’s the LicenseKey object. Once you have this object you can check the status of the license, eg. features and expiration date. For devices that do not have the ability to call Key.Activate, you can instead send them the result from this method as a license file. The easiest way to enable your customers to receive these files on their own is by using our Activation Forms. Once they have provided the license key and machine code, a license file will be downloaded, which they can put on a USB stick, which is then used to activate the offline device. Under the hood, an activation form will call Key.Activate; in other words, if you want to control the user experience, you can create your own page that performs this call. Alternatively, you can manually create this file in the dashboard, by clicking on the yellow button next to the license key.
Reporting tools
Another important feature that your customers can request is to have access to audit logs. For example, if the use the floating license model, they might want to know how many seats are used at any one time so that they can scale it up or down. We are actively working on improving the customer portal to allow your customers to analyse their usage. At the time of writing, we have created standalone scripts on GitHub that you can use to generate several common reports. If you need to generate a specific report, please let us know and we will add example code.
Not a customer yet? Sign Up for a free trial and implement our software licensing system within minutes.
It is now possible to integrate your FastSpring store with Cryptolens. This integration allows you to automatically issue licenses to your customers upon a successful payment in your FastSpring store. You can read more on how to get started in the following tutorial.
Not a customer yet? Sign Up for a free trial and implement our software licensing system within minutes.
Since the end of last year, we have made the reseller portal generally available for all users. We would like to thank all our beta customers for their feedback during the development process.
Idea
The goal behind the reseller portal is to allow you to delegate license issuance rights to other users. This can be your resellers/distributors, IT-admins of your customers or your employees. In other words, “reseller” can be any user that should only be able to create specific amount of new licenses based on a pre-defined template.
The reseller portal also introduces new logging capabilities. All events related to new licenses, customers, etc, are stored in the object log. Thanks to this log, you can, for instance, bill your resellers or customers only when they have successfully created a new license.
Getting started
Once you have created a new account, the reseller portal will be available in the top menu. If you are an existing customer, you can enable it on the billing page. As the next step, we recommend to check out the wiki page for more information.
Please let us know if you have any questions š
Not a customer yet? Sign Up for a free trial and implement our software licensing system within minutes.
Today we have released a library that you can use to implement license key verification for applications written in Rust. The library is freely available on GitHub.
To verify a license, you can use the code similar to the one below. More information about the parameters can be found here.
AutodeskĀ® Revit is a powerful building information software, which allows developers to extend its functionality through plug-ins that can be written in either Python or .NET. In order to monetize your plugin, we need to implement a license verification mechanism and a way to accept payments from prospective customers.
License verification
Python plugins
If your plugin is written in Python, you can use the Python2 version of our Python client. A simple license verification can be performed with the code below (your specific parameters can be found here):
from cryptolens_python2 import *
HelperMethods.ironpython2730_legacy = True
pubKey = "<RSAKeyValue><Modulus>sGbvxwdlDbqFXOMlVUnAF5ew0t0WpPW7rFpI5jHQOFkht/326dvh7t74RYeMpjy357NljouhpTLA3a6idnn4j6c3jmPWBkjZndGsPL4Bqm+fwE48nKpGPjkj4q/yzT4tHXBTyvaBjA8bVoCTnu+LiC4XEaLZRThGzIn5KQXKCigg6tQRy0GXE13XYFVz/x1mjFbT9/7dS8p85n8BuwlY5JvuBIQkKhuCNFfrUxBWyu87CFnXWjIupCD2VO/GbxaCvzrRjLZjAngLCMtZbYBALksqGPgTUN7ZM24XbPWyLtKPaXF2i4XRR9u6eTj5BfnLbKAU5PIVfjIS+vNYYogteQ==</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>"
res = Key.activate(token="WyIyNTU1IiwiRjdZZTB4RmtuTVcrQlNqcSszbmFMMHB3aWFJTlBsWW1Mbm9raVFyRyJd",\
rsa_pub_key=pubKey,\
product_id=3349, key="ICVLD-VVSZR-ZTICT-YKGXL", \
machine_code=Helpers.GetMachineCode())
if res[0] == None or not Helpers.IsOnRightMachine(res[0]):
print("An error occurred: {0}".format(res[1]))
else:
print("Success")
license_key = res[0]
print("Feature 1: " + str(license_key.f1))
print("License expires: " + str(license_key.expires))
C# or VB.NET
If your plugin is either written in C# or VB.NET, you can use our .NET library instead. To add it to your project in Visual Studio:
Right click on your project in theĀ SolutionĀ ExplorerĀ and click onĀ ManageĀ NuGetĀ Packages.
Add the code-snippet formĀ this pageĀ in the code where the plugin loads for the first time.
Accepting payments
One way to sell an Autodesk Revit plug-ins is by publishing them in the Autodesk App Store, where a basic licensing mechanism is already provided. The problem with this approach is that the licensing models available are quite limited (eg. you can only charge your customers once for the plug-in and they will be able to use it in perpetuity). For instance, selling your plug-in as a service (subscription model) is not supported.
A better approach is to still publish your plug-in in the Autodesk App Store and set it to be a free app. You can then ask your customers to get a separate license key to be able to unlock all features.
You can read more about various ways of selling your software in our help pages. I would also recommend to check out the available licensing models.
If you have any questions, please feel free to reach out!
Python can be used to develop a variety of applications, either as plugins (eg. for Discord, AutoCAD, Autodesk Maya, etc) or standalone applications. In this post we will focus on how to monetize a standalone Python application.
Let’s say you have developed a Python application that classifies images (eg. using tensorflow or pytorch). To start selling it, there are just three things we need in place:
Code obfuscation – to ensure that no one can reverse engineer the application.
License verification – to ensure that customers need a license key before they can use the application (eg. so that you can restrict which features they can use and how long the license is valid).
Webshop – so that customers can obtain a license key to unlock functionality.
Code obfuscation
To obfuscate your application, multiple tools can be used. You can either use packages such as pyarmor that are made to obfuscate Python code or open source tools such as pyinstaller in combination with cpython (for most sensitive code).
License verification
A license key can be easily verified using the code below. You can find more information about the parameters here.
from licensing.helpers import Helpers
from licensing.models import Response, RSAPublicKey
from licensing.methods import Key
pubKey = "<RSAKeyValue><Modulus>sGbvxwdlDbqFXOMlVUnAF5ew0t0WpPW7rFpI5jHQOFkht/326dvh7t74RYeMpjy357NljouhpTLA3a6idnn4j6c3jmPWBkjZndGsPL4Bqm+fwE48nKpGPjkj4q/yzT4tHXBTyvaBjA8bVoCTnu+LiC4XEaLZRThGzIn5KQXKCigg6tQRy0GXE13XYFVz/x1mjFbT9/7dS8p85n8BuwlY5JvuBIQkKhuCNFfrUxBWyu87CFnXWjIupCD2VO/GbxaCvzrRjLZjAngLCMtZbYBALksqGPgTUN7ZM24XbPWyLtKPaXF2i4XRR9u6eTj5BfnLbKAU5PIVfjIS+vNYYogteQ==</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>"
res = Key.activate(token="WyIyNTU1IiwiRjdZZTB4RmtuTVcrQlNqcSszbmFMMHB3aWFJTlBsWW1Mbm9raVFyRyJd",\
rsa_pub_key=pubKey,\
product_id=3349, key="ICVLD-VVSZR-ZTICT-YKGXL", machine_code="test")
if res[0] == None:
print("An error occured: {0}".format(res[1]))
else:
print("Success")
Webshop
When you have obfuscation and license verification in place, we need a way for customers to be able to order a license key. If you already have Stripe, you can use the recurring billing module, which acts like an interface for plans defined in your Stripe account. In other cases, you can either use payment forms or a different platform (please read more here).