Externalizing the Bytecode Array Encoding Key
Supply your own VM bytecode encryption key with vmBytecodeArrayEncodingKey and hand it back at runtime through a key getter - kept out of the bundle, read from client storage, or fetched from your backend.
What these options do
vmBytecodeArrayEncoding encrypts the VM bytecode array so it does not sit in the
output as plaintext. By default the encryption key is derived from the environment and reconstructed on the client, so
you never handle it. That is convenient, but the key material still lives in the bundle.
Two options let you take the key out of the bundle and control it yourself:
vmBytecodeArrayEncodingKey- the key you supply at compile time. When set, it is used instead of the default environment-derived key, and it is not embedded in the obfuscated output.vmBytecodeArrayEncodingKeyGetter- a JavaScript expression that returns that same key at runtime. It is embedded verbatim and evaluated in the browser when the obfuscated code loads.
The point is separation: because the key is not in the code, a purely static scan of the bundle cannot recover it. It still has to be present at runtime for the code to run, so it is not truly secret - but you decide where it comes from and who gets to see it.
These two options are a pair. vmBytecodeArrayEncodingKey without a getter leaves the obfuscated code with no way
to obtain the key at runtime, and a getter without a matching compile-time key has nothing to agree with. Set both,
together with vmBytecodeArrayEncoding: true.
How the two keys combine
Your key is never used on its own - on both sides it is mixed with an internal key the obfuscator controls:
- Compile time.
vmBytecodeArrayEncodingKeyis combined with an internal key that the obfuscator derives, and the bytecode array is encoded with the resulting mixed key. - Runtime. The value your
vmBytecodeArrayEncodingKeyGetterresolves to is combined with the same internal key, reconstructed on the client from various runtime factors, to decode the bytecode.
Because both sides mix your key with the internal key, the getter must resolve to the exact same string you passed
as vmBytecodeArrayEncodingKey. Neither piece is sufficient alone: your key without the internal key cannot decode the
bytecode, and the internal key is useless without yours - which is why controlling who receives your key is what
actually protects the code.
Supplying the key at runtime
By default the getter is synchronous: the expression must return the key immediately when the obfuscated code
loads. Read it from any source that is already present on the client - a cookie, localStorage, a global variable, or
a server-injected DOM element.
The key must exist before the obfuscated code runs:
Other synchronous sources work the same way - pick whichever your app already populates:
Keep the key out of the same file or script as the obfuscated code. Inlining it there defeats the whole point - a
static scan of the bundle would recover both the code and its key. Store it in a separate source, and inject the
compile-time vmBytecodeArrayEncodingKey from an environment variable or secret rather than committing it.
Fetching the key from your backend (async)
Requires vmAsyncExecutor · v7.3.0+A synchronous getter can only read what is already on the client. To fetch the key from your server - so you can
gate it behind authentication and revoke it - the getter has to be asynchronous, and that requires
vmAsyncExecutor. With the async executor enabled, the getter may return a
Promise, and the VM awaits it before running.
A Promise-returning getter requires vmAsyncExecutor. This cannot be checked at build time, so a Promise getter
with vmAsyncExecutor off fails at runtime - the decoder receives the Promise object instead of the key string.
Authorize key delivery with a validated session and any required license checks. Origin or Referer alone does not authenticate a caller, and same-origin GET requests may omit Origin. Disable response caching. Bind keys to the correct build version and deploy keys and bundles together. A client that receives the key can inspect it at runtime.
When the key doesn't match
The obfuscated code only works when the getter returns exactly the same key used during obfuscation. If the keys
differ - or the getter returns undefined, null, or an empty string - decryption produces a wrong keystream and the
code fails at runtime with garbage output or an ordinary runtime error.
There is deliberately no distinct, key-specific error message: a failed key is indistinguishable from any other runtime fault. So when a VM-protected bundle throws only once this option is in play, check the key path first - that the getter resolves on the page, returns a non-empty string, and returns the same value you built with.
