FujiForty - Protect Your Bits

Protecting intellectual property has been a concern of partners, ISVs, and others for quite a while. Fuji offers up a great solution for those that want to distribute application logic without exposing the source scripts.

This is accomplished by setting the protection policy field on Application File extension records. Typically you would be concerned with protecting records such as script includes, business rules, ui pages, ui macros, and ui actions. All of these support protection. 

You can also view the protection policy from the list of your application's files.

 

So what's protected? 

First of all, you won't notice anything different in your dev instance. The protection doesn't kick in until you deploy your application to another instance. Once deployed, the fields that typically contain scripts or xml payloads are encrypted and not visible on the record form.

Here you can see the development record compared to the deployed record. In this case, I created a new application file table that contains a script field. Even though it's not a ServiceNow app file table, the script field was still protected, that's pretty cool.

 

So you say, "I'm an admin, there must be a way to see that data, right?".

Nope, once it's deployed you cannot access the encrypted data. The platform has access to decrypt and evaluate the scripts but they are not exposed. Next you're thinking "if it's a script include class I can just enumerate the class' properties and methods right?". Sorry again.

If you instantiate this class and try to enumerate it here's what you get. Actually, you would also get this in the development instance so I'm assuming they had to apply protection across the board for this case.

*** Script: [DEBUG] _youCantSeeMe: function () {
    [source code not available]
}
*** Script: [DEBUG] type: SuperSecretClass
*** Script: [DEBUG] _doSomeMagic: function () {
    [source code not available]
}
*** Script: [DEBUG] initialize: function () {
    [source code not available]
}

What about querying the GlideRecord from a script?

var gr = new GlideRecord("sys_script_include");
gr.get("8d09e5a24f87310050eb7d2ca310c7cb");
gs.debug(gr.script);
*** Script: [DEBUG] PROTECTEDSCRIPT:UX+9AwGkiyyXs3AgzQNwFLP5z8Mpaa0Z....

Ok fine, I can just export the record in XML which contains everything in the record.

No joy on that one too. You can see that we don't even have the script field in the file.

 

 

 

 

Well then, how could I move the record in an update set if I had to?

Actually, update set records in the dev instance are the one place that the records are in the clear. You can distribute updates as update sets like you always have but unfortunately you cannot migrate scoped applications in update sets since the scoping components only work when deployed through the app store. It's important to note that record protection does not apply when deploying your app through update sets. The target instance will have full access to the source records just as you did in development.

Backing up:

In the past you didn't really have to worry about keeping a backup of your app, as long as it was deployed somewhere. You could also get a copy of the update set from another instance. That method can't be relied on anymore since any deployed copy is going to be encrypted. So I'm making sure I occasionally publish my app to an update set and export it for an offline copy.