RubyEncoder allows to protect Ruby and Ruby on Rails files by compiling and encrypting them. The encoded scripts are then run by RubyEncoder's loader. RubyEncoder is developed by Inovica Ltd, which also created a smiliar tool for PHP: SourceGuardian.

RubyEncoder can also be used to only partly protect a project, allowing plaintext Ruby and configuration files; or to limit an application to a certain host or only for a limited time period to create a trial version (more scenarios can be found in the RubyEncoder FAQ section).

InfoQ talked to Alexander Belonosov RubyEncoder's lead developer to learn more about the technical side of the project.

InfoQ: How does the encoding and the loading/running work?

The Ruby source code is compiled into an intermediate internal format which is followed by encryption. The original source code does not exist in protected scripts once they are encoded. RubyEncoder Loader needs to be installed to run protected scripts. The loader is a Ruby extension which decodes the protected script and runs it. Protected scripts are platform independent which is very important and you may use protected scripts on any supported platforms. Loaders differ for OS and platforms. We support the following platforms for running RubyEncoder protected scripts - OSX, Linux, FreeBSD and we are just started Solaris x86 support. We have plans to add support for Windows and other UNIX in the nearest future.

InfoQ: The source is translated to an intermediate format. Do you have your own interpreter that runs it or do you restore the original Ruby source code?

The original Ruby source code is never restored. We use internal intermediate format. [..] It is internal, binary, executable and never decodes back to original source code.

InfoQ: If you have your own interpreter, how does this interact with metaprogramming and other dynamic behavior of Ruby? Or are there no restrictions whatsoever?

Currently the loader passes the internal representation of the code back to Ruby for execution. This lets us to keep maximum compatibility and a dynamic nature of the Ruby code. But we also keep looking on other methods and possibly will change or implement a new schema in next versions of our product. Anyway using of RubyEncoder protected products will be transparent to end-users and Ruby developers will get an updated and more effective encoder.

InfoQ: With the ParseTree gem, one can access the parse tree of a class or method. Is this affected by RubyEncoder?

ParseTree is a great extension for investigating internals of Ruby, code optimisation etc. If you mean if we restrict to use ParseTree then the answer is no. But what is important to understand when you use tools like ParseTree is what you need to extract from Ruby internals and how to find it. I think it is also important to think of what is a reason for it, how much time will it take and what will be a final result :-)

InfoQ: Do you have plans to support other Ruby implementations, for example JRuby? Would it be possible to port the loader to Java to run JRuby code?

Currently we support only standard Ruby. JRuby is great project and it is growing. Although it has a bit different market.

InfoQ: Using JRuby and compiled Ruby sources, would ByteCode obfuscation lead to the same protection that RubyEncoder provides?

Using JRuby and compiled Ruby sources may produce a very good level of protection. But it is oriented for a Java environment. Our aim is to protect native Ruby and Ruby-on-Rails project initially and we may decide to look at enhancing or expanding the product later.

InfoQ: In what language is RubyEncoder written? Using Ruby and then self-encoded?

No, I have nothing bad to say about Ruby meta programming :-) But RubyEncoder and the loaders are written in C.

RubyEncoder is a commercial product, there's also a 30 days trial version available.

Have you ever used such a code protection tool? What were your experiences with it?