StackHub Bulletin BoardAdvertise your announcements here!


Encrypts and obfuscates Axon source code

Registered StackHub users may elect to receive email notifications whenever a new package version is released or a comment is posted on the forum.

There is 1 watcher.


Axonator is an extension for SkySpark v3.0.13+ that encrypts Axon source code.

Axon functions can be distributed to clients and customers in Trio files. This is great until you realise Trio is a plain text format and what you're actually doing is distributing your Axon source code in plain sight!

This allows anyone to copy your hard work and potentially steal your intellectual property.

Even if you distribute your functions in .pod files, the Axon source code is still exposed through plain text Trio files in the pod.

Encrypt and protect your Axon code with Axonator!


Axonator is free to download and evaluate but a licence must be purchased for production use. See Licensing for details.


Axonator takes plain text Axon source code and a pass phrase, and generates encrypted Axon code and a secret key. The encrypted code can only be decrypted and run with the secret key.

For example, Axonator takes Axon source code in plain text like this:

(name) => do
  return "Hello " + name + "!"

and encrypts it into code like this:

(name) => do
  axonCode :
    "AxD:mvUjtIFWCMNZV1HuOAxMMg::jc84ZwXVBPzw3vfg2rLl1NIZx8eemoG_pYZEnnZfSvYZElURNjU4" +
    "c62cfYTMHGMf2HFsjYn0V8Kagb8hj8nBN9lkRUryYUxojI6zuWCnNef1LIqJ7fDdwcC43dpXsMunsHH_" +
    "6U7eKhTxJWzF0A32SLsdnotcjOwOyRKfUI91n-QHma9mEi2Ri4mRhGW805ISTU5Ut_LiwdImXL-qnqHQ" +
    "FUuWwiV-53ZSFnyUi_uAybEJBxNbiFiSRSptuTsrO5SQd6Np2V4iGM25b0Rc_WRP09LYbuo4Qo0w_Dqu" +
  keyFunc : (fnName) => ... fn that returns a secret key ...
  return afAxonatorCallFunc("hello", axonCode, [name], keyFunc)

Axonator can encrypt an individual function record, a Trio file of functions, or even an entire directory of Trio function files!

Axonator never reveals the decrypted / original Axon source so you can be confident your intellectual property remains safe.

The encrypted functions and Trio files are direct drop in replacements for the original. So if distributing Axon functions via .pod files, you would encrypt your Axon source files and distribute the axonated version in place of the original.

Quick Start

Here's how to encrypt an Axon function:

// Axon funcs may be any created with the SkySpark Func app
// but here we're just going to create one in code
plainFuncRec : {
    "name" : "hello",
    "src"  : """(name) => "Hello " + name + "!" """

// encrypt the function
passPhrase : "Axonator Protects"
axonated   : afAxonateFunc(plainFuncRec, passPhrase)

// this is the encrypted func record
encryptedFuncRec : axonated["funcRec"]

// print the encrypted Axon source to the console
echo( encryptedFuncRec["src"] )

The encrypted source code may then be compiled and run, just like any other Axon function:

// compile the encrypted code...
helloFn : encryptedFuncRec["src"].eval()

// ...and run it!
helloFn("Mum")  // --> "Hello Mum!"

Key Functions

From the last example, note the secret key from the returned axonated Dict:

// keep this safe!
secretKey : axonated["secretKey"]  // --> "pPLFy7m5L5ym-WaVY9wiAQ"

The secret key is what Axonator needs to decrypt the axonated code.

To obtain the secret key, Axonator requires a keyFunc that returns the secret key when executed. You can see the keyFunc in the encrypted code from the last example:

(name) => do
  axonCode :
    "AxD:paWD-OWysOhmOg7h9VKf3Q::Zyp3EtWBS7hR3pEMXd7Odpr40jY_x6baLvvMSYi-iNVwj86xTpfF" +
    "h8H56DLHH1Jnte6SkiZZSxvch3mQxbGRDMizoR34xJV560q5fiTe8nWb9YZR2gLh5bKXhQHBuCqVD1Yp" +
    "nDnwOkWnT3rhvRt6B_5AQqV-4qisw_xtIhQ0HRIWtJLjFcp5O9U0PeTIW2TcJgb1u_um-cXb55PoI-iw" +
    "f4FVZrNy6NKkoQM126XRwX5ARXLpXnatlxQfsUftRSNz0jeBL9NABHc0-N2zWjJsbO6QvGpcBXduKjke" +

  keyFunc : () => "pPLFy7m5L5ym-WaVY9wiAQ"

  return afAxonatorCallFunc("hello", axonCode, [name], keyFunc)

The simplest keyFunc is one that just returns the secret key in plain text. And indeed, from the code above you can see that is what Axonator does by default. Whilst not 100% secure (see Notes on Security) it is extremely obfuscated and is usually good enough for most use cases.

Custom KeyFuncs

KeyFuncs take the function name as an optional argument, this lets you use another Axon function to perform a look up for the secret key.

This allows for highly customisable keyFuncs that are able to retrieve the secret key from a REST API, a StackHub licence file, or anywhere!

To use a custom keyFunc in axonated code, pass the keyFunc source code to one of the axonate functions:

funcRec    : ...
keyFunc    : "(fnName) => lookUpSecretKey(fnName)"
passPhrase : "Axonator Protects"
axonated   : afAxonateFunc(funcRec, passPhrase, keyFunc)

To customise keyFuncs even further, an Axon Fn may be passed to the axonate methods:

funcRec    : ...
keyFunc    : (fnName, secretKey) => "(fnName) => lookUpSecretKey(\"" + fnName + "\")"
passPhrase : "Axonator Protects"
axonated   : afAxonateFunc(funcRec, passPhrase, keyFunc)

The Axon Fn must return a string to be used as the keyFunc.

StackHub Licence Integration

Axonator has a built in method to retrieve secret keys from a StackHub licence file.

This makes your functions doubly secure as not only are your functions encrypted, but no-one can decrypt or run them unless they also have a valid licence file.

If your functions make use of this facility then (as a means of promoting StackHub licensing) the use of Axonator is FREE!.

Example - Product ID

Create a product on StackHub and note its ID. Use this product ID to create a keyFunc, then use the keyFunc to encrypt your Axon functions:

productId  : "01010101-01010101 My Awesome Product"
keyFunc    : afAxonatorStackHubKeyFunc("product", productId)
passPhrase : "Axonator Protects"
axonated   : afAxonateFile(`io/funcs.trio`, passPhrase, keyFunc)
secretKey  : axonated["secretKey"]
               // --> pPLFy7m5L5ym-WaVY9wiAQ

Note the secret key and edit your StackHub product to add the following extra property:

axonatorKey = <secretKey>

which, in our example, would be:

axonatorKey = pPLFy7m5L5ym-WaVY9wiAQ

When a licence file is generated for your product, it will contain the above property, meaning the only people with access to the secret key are those who have a valid licence file.

If you look at your encrypted Axon functions, the keyFunc will look similar to this:

keyFunc : () => afAxonatorGetKeyFromStackubLic("product", "01010101-01010101 My Awesome Product", "xxxxxxxx")

This generated keyFunc calls a hidden function that looks for a StackHub licence that matches the product ID 01010101-01010101 My Awesome Product. If such a licence is found, and if the licence is valid, the function returns the axonatorKey property, which is the secret key you setup earlier!

This means that only people with a valid StackHub generated licence have access to the secret key, and only people with a valid StackHub generated licence can run your Axon functions.

All functions encrypted with the afAxonatorStackHubKeyFunc key func are unrestricted, making Axonator FREE for creating StackHub products.

Example - Package Version

A more robust approach than finding licences with a Product ID, is to use your package name and version instead. Package names are unlikely to change whereas products are easily deleted and re-created on StackHub, thus increasing the risk of changing the associated ID.

For package details to exist in StackHub licences, you must first upload your package to StackHub and add it to your product.

From an Axonator point of view, you must tell it which package (and associated version) your functions are attached to, and it will find a valid matching licence file and extract the secret key from it.

// create a keyFunc with our pacakge details
packageVer : "acmeAwesome 2.3"
keyFunc    : afAxonatorStackHubKeyFunc("package", packageVer)

// these following lines are the same as usual
passPhrase : "Axonator Protects"
axonated   : afAxonateFile(`io/funcs.trio`, passPhrase, keyFunc)
secretKey  : axonated["secretKey"]
               // --> pPLFy7m5L5ym-WaVY9wiAQ

Also see the Axon func afAxonatorStackHubKeyFunc for details.

Note: Be careful when there's a different number of version segments in the StackHub licence and in the key func. Lobby the Fantom post sys::Depend.match() anomaly for a fix.

Command Line Encryption

Axonator may be invoked from the command line to encrypt .trio files. This is useful if you wish to encrypt many files in a batch, or in a non-SkySpark environment.

The examples below have new lines added for clarity.

Use Axonator with a valid Axonator licence and custom key func:

fan afAxonatorExt
    -axonIn      lib/myFuncs.trio
    -axonOut     lib/myEncyptedFuncs.trio
    -passPhrase  "Axonator Protects"
    -skysparkLic lic/lic-skyspark.props
    -axonatorLic lic/lic-axonator.props
    -keyFunc     "(fnName) => return \"gm8v8MePNgSRhVRZ-2zogw\""

To use Axonator in evaluation mode, just omit the licences:

fan afAxonatorExt
    -axonIn      lib/myFuncs.trio
    -axonOut     lib/myEncyptedFuncs.trio
    -passPhrase  "Axonator Protects"
    -keyFunc     "(fnName) => return \"gm8v8MePNgSRhVRZ-2zogw\""

To distribute the secret key via a StackHub licence:

fan afAxonatorExt
    -axonIn      lib/myFuncs.trio
    -axonOut     lib/myEncyptedFuncs.trio
    -passPhrase  "Axonator Protects"
    -stackhubKey "product"
    -stackhubVal "12345678-12345678 My Awesome Product"

To encrypt a directory of function files, just pass in the input / output directories:

fan afAxonatorExt
    -axonIn      lib-axonIn/
    -axonOut     lib-axonOut/
    -passPhrase  "Axonator Protects"
    -keyFunc     "(fnName) => return \"gm8v8MePNgSRhVRZ-2zogw\""

Note for Windows users: You should also use /forward slashes/ in directory names, as per the examples above.

Use the -help option for details:

fan afAxonatorExt -help

Notes on Security

Axonator encrypts using the Advanced Encryption Standard; which is pretty strong.

Note that export laws in the United States prohibit Oracle from selling very strong encryption. This limits the encryption strength of the standard Java installation, and hence Axonator, to 128 bits. Stronger encryption is possible in Java but requires the Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy to be installed.

Decrypting and running Axonated functions require the use of a secret key. While Axonator itself does not reveal the original Axon source code, anyone with the secret key (including the end user) and enough programming knowledge may be able to reveal the original Axon code.

For this reason, source code encrypted with Axonator should not be considered secure and Axonator itself should be considered an obfuscater. The only way to truly keep your functions secure, is to not distribute them in the first place.


Axonator is a Commercial product and requires a licence to be purchased (see below) to run unhindered.

Axonator is provided free of charge for use in products sold on StackHub.

Licences for Axonator are tied to an SkySpark organisation. This means it is valid for and will work on, any SkySpark installation within your organisation, but will not work on SkySpark installations for other organisations. You will need to enter your SkySpark organisation ID when purchasing, see Where is my SkyArc Organization ID? for details.

Purchased licences expire after 1 year. After this period all previously encrypted functions will continue to work as usual, but a valid licence will be required to encrypt further functions.

Purchased licences are available from the My Licences page and should be downloaded to the /var/lic/ directory of your SkySpark installation.

Minor updates to Axonator may be provided free of charge, but major updates will require a new licence to be purchased.

Although free to download, Axonator enters into an Evaluation Mode if it does not find a valid licence; whereby encrypted functions may only be invoked a maximum of 5 times and expire after 1 day.

For support, comments, and refunds, please email ----------------------.

SkyPosium Presentation

A presentation entitled Protect Your Code With Axonator was given to the SkyFoundry SkyPosium event in Dulles, Virginia, USA on Thursday, 15th November 2017.


How do I encrypt a Trio file?

A Trio file of Axon functions may be encrypted via afAxonateFile:

passPhrase : "Axonator Protects"
afAxonateFile(`io/funcs.trio`, passPhrase)

afAxonateFile backs up your .trio file and replaces it with a version where all the src tags have been encrypted. All other tags and non-func records remain intact hence the encrypted file may be used in place of the original.

Note you should always keep a copy of your original .trio files as they can not be restored.

How do I see the decrypted Axon source code?

You cannot. Axonator never reveals the decrypted Axon source. To do so represents a security risk.

Make sure you keep your source backed up!

Is there a performance hit when decrypting axonated code?

There may be a small hit the first time a function is decrypted, but once done, Axonator caches a reference to the compiled function.

All subsequent calls to the encrypted function are routed straight to the cached compiled version, so the hit is only ever taken once.

When distributing encrypted functions to clients, do they also need Axonator?

Yes. The Axonator extension is needed to decrypt your functions so your clients will also need it on their SkyArc installations.

If you are distributing your functions in a Fantom .pod file then your should express a dependency on afAxonatorExt. This will make sure Axonator is installed on any target system. It also enables Install Managers to download and install Axonator automatically along with your extension.

depends = [
    // ---- Fantom Core ----
    "sys           1.0.70 - 1.0",

    // ---- Axonator ----
    "afAxonatorExt 0.9.8  - 1.0",

    // ---- SkySpark ----
    "skyarcd       3.0.13 - 3.0",
    "haystack      3.0.13 - 3.0",
    "stackhub      3.0.13 - 3.0",

Your extension should also express a dependency on the afAxonator extension to make sure Axonator is enabled for your project.

using skyarcd::Ext
using skyarcd::ExtMeta

@ExtMeta {
    name    = "acmeAwesome";
    depends = Str["afAxonator"]
const class AwesomeExt : Ext {


The software is provided "AS IS" and the author disclaims all warranties with regard to this software including all implied warranties of merchantability and fitness. In no event shall the author be liable for any special, direct, indirect, or consequential damages or any damages whatsoever resulting from loss of use, data or profits, whether in an action of contract, negligence or other tortious action, arising out of or in connection with the use or performance of this software.

Published by Fantom Factory

Products & Services by Fantom Factory

Packages by Fantom Factory

Commercial packages

Free packages

Pricing options
Log in to purchase Download
Package details
Build date1 week ago
on Thu 9th May
Depends on
File nameafAxonatorExt.pod
File size69.58 kB
SHA1 01de1e089fccc185dcf1cc83d10145f9abe6a0f6
Published by
Fantom FactoryDownload now
Also available via SkyArc Install Manager
Fantom Pod
Axon Funcs
Sky Arc Ext