Licensing

Licensing with StackHub

License Features

StackHub provides the following default features and constraints for products and their associated license files.

Each product sold should clearly dictate which feature(s) it makes use of.

  • Package based

    The license enables one or more StackHub packages. The package may be optionally constrained to a set of version ranges.

  • Expiry Date

    The license is only valid up to a certain date, after which it becomes invalid.

  • SkyArc License ID

    The license is only valid when used on a SkyArc installation with a specific license number.

    These products are designed to be used on SkyArc installations such as SkySpark, FinStack, etc...

  • Capacity based

    The license provides a bundle of points. What a point represents and how it is spent is up to the product to decide.

Note that products may also impose their own custom constraints.

License Files

A typical (but fully loaded) StackHub license file looks like this:

authority  = stackhub
licVersion = 1.0
id         = xxxxxxxx-xxxxxxxx
rev        = 0
mod        = 1999-04-03T23:00:00Z UTC
generated  = 1999-04-03T23:00:00Z UTC
product    = xxxxxxxx-xxxxxxxx Bat Mobile
vendor     = xxxxxxxx-xxxxxxxx Wayne Enterprises
org        = xxxxxxxx-xxxxxxxx Batman
licensee   = <Bruce Wayne>
expires    = 1999-06-12
skyarcLic  = xxxxxxxx-xxxxxxxx
skyarcOrg  = xxxxxxxx-xxxxxxxx
packages   = batMobile 2.0; turboThruster 1.2-1.5; graplingHook 4+
capacity   = 1000 bullets; 20 missiles; 1 bomb
sig        = xxxxxxxx-xxxxxxxx-xxxxxxxx-xxxxxxxx

The signature (the sig property at the bottom) is a hash of all the other properties and is generated using industry standard public / private key encryption techniques. This means that only StackHub, using a secret private key, can generate the signature. But anyone else can use the public key to verify that the signature, and hence the contents of the license file, was indeed generated by StackHub.

StackHub Public Key:

RSA:X.509:MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAIJB5G86kTyzNKemUSPjT/H/JpzWzZ7BzFijzJAj9m+E8mYMkQsRCKPGB72pzCHq/d4wTzOXe+fedju1cRn/hL0CAwEAAQ==

License Validation

When a product is sold, StackHub generates a securely signed license file on your behalf. The customer should install the package and license on their system, but it is up to you to check that a valid licence exists for the package.

This necessitates a bit of custom code to perform the following:

  1. Find a license file for your packge
  2. Verify the signature property is valid
  3. Verify the constraint properties are valid
  4. Disable the package (or limit functionality) should the license be invalid

If your product runs on SkyArc (SkySpark, FinStack, etc, ...) then typically you would create a Fantom extension that overrides the onStart() method. There it should then use the StackHubLic class to find a license related to your product and check that it is valid. If it is not, then you should disable your extension.

Note that SkySpark will automatically mark a license as invalid if:

  1. The signature property is invalid
  2. It contains an out of date expires property.
  3. It contains a skyarcLic property that does not match the SkyArc License Number.
  4. It contains a skyarcOrg property that does not match the SkyArc Organization ID (or subOrg ID).

Validation of any other license property requires custom Fantom code.

Note that even though a license is invalid, it is still up to you to disable your extension.

See LicHelper for sample code on how to validate licenses. Contact StackHub should you require help with this process.

LicHelper

The LicHelper.fan Fantom class can help you find valid StackHub licences for your product on SkyArc systems such as SkySpark and FinStack. Note that the StackHubLic class and extension disabling feature is only available in SkySpark 3.0.13 or later.

Copy and paste the Fantom class from the GitHub Snippet below into your SkyArc project.

> LicHelper.fan

Repeated calls to the findXXX() methods whittle down the number of valid licences until one is left. The remaining licence may be retrieved with get().

A LicErr is thrown should no licence match the given criteria. This may be caught to disable the containing SkyArc extension.

Licence validation may be performed during the extension onStart() event. Typical usage would be:

using skyarcd::Ext
using skyarcd::ExtMeta
using haystack::Ref
using stackhub::StackHubLic

@ExtMeta { name = "acmeExt" }
const class AcmeExt : Ext {

    ** Validate the licence file.
    final override Void onStart() {
        try {
            lic := LicHelper(sys)
                .findVendor(Ref("87654321-87654321", "Acme"))
                .findPackage(Depend("acmeExt 1.0"))
                .findValid().get()

            cap := LicHelper.parseCapacity(lic)

            // ... validate licence capacity here ...

            log.info("${lic.product.dis} licensed to ${lic.licensee} --> okay")

        } catch (LicErr err) {
            // if a valid licence can not be found, disable this extension
            StackHubLic.extToFault(this, err.msg)
        }
    }
}

Note findVendor() should be called with your StackHub Vendor ID available from the My Products page.

findPackage() should probably be called with the details of the current pod:

findPackage(Depend("${typeof.pod.name} ${typeof.pod.version}"))