Engage Licensing - rallytac/pub GitHub Wiki

Licensing Your Engage Software

Licensing your Engage software is a necessary part of the process of using our code. While we're pretty trusting people over here at Rally, we're just not in a position to give our code away for free or hope that some folks will just give us money out of the kindness of their hearts (but that'd be very nice if you feel so inclined). So ... we have to license this stuff.

Now, software licensing is not a unique concept and there's many ways to skin this cat. (PS. What ever did the poor cat do to so often be considered for skinning !?)

At the very least, you can run Engage software without a license and still have some semblance of operation. In fact, an Engage Engine without a license will run for an unlimited amount of time, support multiple groups, a variety of features, and pretty much all CODECs. However, you'll only be able to transmit for a maximum of 3 seconds at a time.

NOTE: We reserve the right to change this mode of unlicensed operation at any time so, please, don't rely on this great capability. Rather, just buy the licenses you need.

Alright, let's get into how licensing works.

An Engage license key is simply a string of 24 characters that is constructed and encoded using a combination of anonymized identification of the customer, some information about the type of license we're talking about and some other goodies. Something like this: 37060A61010DBED2980A6DF2.

When we say anonymized identification of the customer, we mean that you can't actually tell from the license key who the customer is, where they are, or anything like that. So, you can be sure that your license key will never identify you, your users, your organization, or for what purpose the key is being used.

This encoded license key contains a wealth of information for Engage, including:

License Expiration

Most important is the expiration date of the license. The expiration date is simply a date after which the license is no longer valid. This means that we can accomodate short-term licenses such as those that are issued for use at an event like a football match or a trade show. The expiration date also makes it simple for partners to license their Engage-powered applications on a subscription basis where the end-customer signs up to use the software for a certain period of time - maybe 1 year at a time, etc.

For licenses that do not fall into such an obviously expiring category, the license will still expire - but in a few million years or so. (So you probably won't care about that too much unless you have plans that the rest of humanity isn't privy to.)

Activation vs Non-Activation

Also included in the license key is a flag (its just an encoded value) that indicates whether the license needs to be activated. If this value is not set, then the license does not need to be activated - obviously. If the flag is set, then the license needs to be activated.

A key difference between a license that requires activation (we call that a "Perpetual License") and one that doesn't (cleverly named a "Non-Perpeptual License") is that a license that requires activation causes that license to be valid only for the particular device on which Engage is running - such as an Android phone or a Windows desktop machine. This means that if you try to use that license (together with its activation code discussed in more detail below) on a device other than for which you have that activation code, your Engage software will not work on the new device. Put more simply, activating a license ties that license to a specific device. You might then surmize that a license that does not require activation is not locked to a particular device - and you'd be right!

So, why would you want a license that requires activation and limit yourself to just the device(s) for which the license is activated? Well, a license not tied to a device can be used on any number of devices - whether they're yours or someone else's. That's obviously a major concern if the license were to be exposed (or "grow legs"). So, its best to use licenses that require activation and can therefore be tracked and managed properly.

Activation Codes

You might wonder what exactly an activation code is. Well, it's also just a string of characters just like a license key. But instead of the activation code being largely based on information about the customer, its based on a combination of the license key and the device identifier (see below). Also contained in the activation code is an expiration date - just like that found in the license key. This means that, while you may have a license key that is perpetual for all intents and purposes - such as expiring around the time of the end of the Universe; if that license requires activation, then the activation code can set a limit on the operational lifetime of the license on the device for which it has been activated. Bottom-line, an activation code can (and often does) override the expiration date of the license.

That sounds terribly complicated and you're probably wondering why we'd go to such lengths. Simply, we want to give our partners and their customers the most flexibility and choice on how they utilize (i.e. license) our software. The ability for an activation code to change a license's expiration date means you can come up with some pretty fancy licensing schemes - particularly in the realm of SaaS, subscription-based business models, and so on.

Device Identifiers

We spoke earlier about device identifiers. Let's expand on that a little.

A device identifier is an anonymized representation of an-already unique ID for the device in question and varies based on operating system platform. On most platforms, Engage obtains the ID by querying the operating system for the information. On platforms where the OS does not provide this information, Engage either obtains the information by generating a pseudo identifier from hardware present on the device or by calling manufacturer-specific APIs to retrieve the data. No matter the process involved in obtaining this data from the OS, hardware, or manufacturer; Engage further anonymizes the machine-provided information by generating a one-way hash of that data together with some other data (called salts) which, finally, result in a machine identifier that has no identifying information about the machine itselt. (Yeah, this probably sounds confusing and overly complicated ... but just go with it.)

Getting Activiated

A license that requires activation needs an extra step before it'll work. That step is to send the license key along with the device identifier to our licensing system which, in turn, will issue the activation code. Usually that's pretty straightforward and users don't need to get involved. That's because the software will take care of contacting our Internet-based licensing system to get the activation code.

"Aha!", you say, "But what about if my device is NOT connected to the Internet? Now what???"

That's an excellent question. Here goes:

In the event your device cannot reach the Internet (maybe you're on a secret network of some sort (wink, wink!)), you can use another device to act as your proxy; assuming that device* has Internet connectivity.

Here what we do is to generate a QR code which the app displays on the screen. Then, you scan that QR code with a scondary device (like your personal cell phone), and open the link in your phone's browser. That link will, in turn, display a QR code, which is the activation code. Back on the device you're trying to activate you need only scan this QR code (or type in the text of the QR code), and you're ready to go!

If all that fails, contact your vendor (email/phone/other) with your license key and device identifier and they'll get you the activation code. Pretty simple, huh!?

So, real quick, licensing can be roughly divided into two use-case categories

Do not require activation Require activation
Typically have an expiration date set within 1 year of issue A lot more flexibility is available for the expiration date - anywhere from 24 hours from date of issue to no effective expiration at all
Dangerous because, if leaked, can be used on an unlimited number of devices Locked to a particular device
Cannot be tracked Has the option of being tracked
No need for deactivation if the device is lost or factory reset Need to be returned to the central activation pool
Can be used on any number of devices without need for explicit transferral Need explicit transferral from the "old" device to the "new" device

Going Deeper

Alright, we've covered the basics of our licensing.... Actually, no, we haven't. There's a bit more.

Remember we mentioned earlier that the license key is comprised of anonymized customer information, the license type, and some other goodies. Let's delve into two of those, shall we?

Manufacturer ID

RTS licenses Engage to a large number of software and hardware vendors in the market. Each of these fine folks is a manufacturer in our eyes and, therefore, licenses issued for that manufacturer's product need to be unique to that particular manufacturer. That way there's no chance that Customer X using Vendor A's product could inadvertently (or maliciously) use that license for Vendor B's product. So, to protect against this, every license contains not just the anonymized customer info, type, and expiration date; but also contains the manufacturer's ID - something like {44ACD820-4534-4896-83D4-12398C55F0FD} (not a real manufacturer ID by the way if you're wondering).

Entitlement Key

Now, each of these manufacturers have at least one product that uses Engage and, often, more than one. For example: Vendor A may have Engage-powered apps for Windows, Android, iOS, and a super-sexy piece of custom hardware they've built just for Engage. This vendor could choose to have licenses issued for any of these platforms to work on all the other platforms. Or, they could choose to have licenses for Android work only on Android, those for Windows only on Windows, and so on.

In that case (actually, in all cases), the Vendor is issued an entitlement key for each product. For example: {62D1A2DF-D757-4375-A8D5-830EBE0A293B} for Android, {550F3A8B-A626-4C96-B9C8-0F280CFCB1BB} for Windows, {225CD80C-76C3-4E0B-BC34-DF6C3C534E56} for iOS, and {4F616C81-4D0F-42EB-BA1E-90E749ECC508} for that groovy hardware kit. (These are example entitlement keys by the way. And they're always different for every product from every manufacturer using Engage.)

Now let's assume Customer X buys licenses for each of these platforms, they'd all have different licenses - even though they're for the same customer by the same vendor. To wit, something like A53FB92ACE4909391EA7EF92 for Android, 1FF02787171BFCA1AF455E33 for Windows, FB8D789053C212C0F9531EF7 for iOS, and 3E162A241C407AD42EA893C4 for the specialized hardware kit.

Now our partner (Vendor A) has maximum control over their licensing. The customer gains, too, by being able to pay just for what they want on the platform(s) they want without paying a premium for a license that works across all platforms. Pretty sweet!

Featuresets

For all the work we put into our licensing model to make it flexible, its still not flexible enough. (Hard to believe isn't it?) What's at issue is that there are situations where the Engage software needs to have licensing of specific capabilities and/or counts of capabilities. For example: in general, an Engage Engine allows for an unlimited number of groups (channels) to be created. But there are situations where we at RTS or our OEM partner needs to limit the number of groups - say to 4 - due to pricing constraints, government and/or corporate agreements, and so on. In other instances we need to pay third parties for the use of their software within Engage - meaning we can't just issue a license and let everyone have at it.

The solution to this is the notion of a featureset. A featureset is configuration data (in JSON format), provided to the Engage Engine which it uses in conjunction with the license (perpetual or otherwise) to enable one or more, you guessed it, features! It looks something like this:

{
    "featureset": 
    {              
        "signature": "DAE12D151AE10B41AEEB67197C94CCA72450D9FF2E08345C467454010DAF211D",
        
        "features": [
            {
                "id": "{0F4F5C22-7F35-4AE9-99AA-23F821EC9ECF}",
                "count": 16,
                "comments": "Audio Groups"
            },
            {
                "id": "{A22D2528-0B3F-4B36-A075-AB19E127EA1B}",
                "count": 1,
                "comments": "Presence Groups"
            },
            {
                "id": "{4FBD3FA5-81A1-4DF4-981F-A1894DAB70A9}",
                "count": -1,
                "comments": "Recording Instances"
            },
            {
                "id": "{2BE94F5E-5630-4487-AAB6-77D820BB505A}",
                "count": -1,
                "comments": "MELPe CODEC"
            }
        ]
    }
}

In this example, the featureset provides for 16 audio groups, 1 presence group, unlimited recordings, and unlimited use of the 3rd-party MELPe audio CODEC.

Pay attention to the signature field in this JSON - DAE12D151AE10B41AEEB67197C94CCA72450D9FF2E08345C467454010DAF211D. That is a special bit of data that ties the featureset to the license provided to the Engage. This means that this featureset can only be used in conjunction with a specific license. But it is NOT tied to the activation code. So it means that the featureset applies to all devices where the license is used - regardless of whether the license requires activation or not. However, this only works if the entire license is valid - i.e. the license must not have expired, and it must be activated if deemed necessary.

Not only does the signature tie the featureset to the license, it also locks down the contents of the featureset - invalidating it if changed. For example: let's say you take the above featureset and change the audio group count from 16 to 32. If don't recalculate the signature, the featureset is invalidated and Engage will bark at you. (Oh, by the way, the method by which the signature is calculated is a secret we're not sharing!)

License Distribution

We already discussed how activation codes make their way into Engage. But we haven't talked about how to get licenses and featuresets in the hands of end-users.

Typically, those decisions are left to our OEM partners to decide what works best for them and their customers. This can range from users typing in license keys, to scanning QR codes, to obtaining licenses from centralized servers, and so on. No single approach will work for everyone in every scenario; and we're certainly not going to dictate how our partners should do this stuff.

However, we can make recommendations. Specifically in the area of distribution of more complex data such as featuresets where server-based license distribution is not possible such as in tactical military environments.

Here, we recommend a simple JSON file format comprising all or a subset of the licensing and featureset objects found in the Engage Engine policy JSON (developers using the Engage Engine will know what this means).

For example:

PLEASE NOTE: This example does not represent real values for the various JSON fields. These values are merely provided as an example.

ALSO: Our recommendation is that the way in which the application should process the JSON is in an atomic fashion - meaning that whatever is provided FULLY REPLACES whatever current licensing has been provided to the Engage Engine, Rallypoint, or whatever application is using the Engine - such as the Engage Activity Recorder, EngageBridge, our your own application.

{
    "licensing":{
        "entitlement": "{550F3A8B-A626-4C96-B9C8-0F280CFCB1BB}",
        "key": "37060A61010DBED2980A6DF2",
        "manufacturerId": "{44ACD820-4534-4896-83D4-12398C55F0FD}",
        "activationCode": "CE369D67550F4106"
    },

    "featureset": {              
        "signature": "DAE12D151AE10B41AEEB67197C94CCA72450D9FF2E08345C467454010DAF211D",
        
        "features": [
            {
                "id": "{0F4F5C22-7F35-4AE9-99AA-23F821EC9ECF}",
                "count": 16,
                "comments": "Audio Groups"
            },
            {
                "id": "{A22D2528-0B3F-4B36-A075-AB19E127EA1B}",
                "count": 1,
                "comments": "Presence Groups"
            },
            {
                "id": "{4FBD3FA5-81A1-4DF4-981F-A1894DAB70A9}",
                "count": -1,
                "comments": "Recording Instances"
            },
            {
                "id": "{2BE94F5E-5630-4487-AAB6-77D820BB505A}",
                "count": -1,
                "comments": "MELPe CODEC"
            }
        ]
    }
}

This JSON could be shared as a simple clear-text file, encrypted text file, or copy-pasted email text. In addition, this content may be encoded into a QR code. On the receiving end it would be scanned to text either by camera or by processing an image file. For example:

Feature IDs

Name Value
ENGAGE_FEATURE_ID_AUDIO_GROUP {0F4F5C22-7F35-4AE9-99AA-23F821EC9ECF}
ENGAGE_FEATURE_ID_PRESENCE_GROUP {A22D2528-0B3F-4B36-A075-AB19E127EA1B}
ENGAGE_FEATURE_ID_RAW_GROUP {F32931F3-8259-4161-A12A-DC98E6126A5F}
ENGAGE_FEATURE_ID_BRIDGE {D66C0A3C-6209-4736-830B-1526416C59D8}
ENGAGE_FEATURE_ID_RECORDING {4FBD3FA5-81A1-4DF4-981F-A1894DAB70A9}
ENGAGE_FEATURE_ID_RP_STATIC_REFLECTOR {CC181130-0AC6-4775-8192-71B0320082D0}
ENGAGE_FEATURE_ID_RP_DYNAMIC_REFLECTOR {54724595-BFB1-470D-8340-D604E6C4042E}
ENGAGE_FEATURE_ID_RP_CLIENT_CONNECTION {BE4D5A27-BBF5-4C70-A382-654874E7C030}
ENGAGE_FEATURE_ID_RP_PEER_CONNECTION {F741EE1B-CCD3-40B3-9403-857D6A5CC680}
ENGAGE_FEATURE_ID_MELPE_CODEC {2BE94F5E-5630-4487-AAB6-77D820BB505A}