Browse documentation
Documentation / Protection passes / Build-time watermarking

Build-time watermarking

ImplementedAn optional per-build identifier, obfuscated the same way the native library is, recoverable without running the jar.

What it does

An optional per-build identifier, typically per-licensee, is embedded using the same manifest-plus-obfuscated-blob scheme as native library bundling. An in-app accessor can read it back at runtime (it returns nothing, and does not throw, when no watermark was embedded). The intended workflow is a separate, standalone extraction tool that recovers a jar's watermark by reading its entries directly and never loads or runs the jar's bytecode, which would be a risk when investigating a jar you don't otherwise trust.

How to use it

Pass a watermark string at protect time; see Configuration for the flag. If you don't pass one, no watermark is embedded and the extraction tool reports none, not a stale or default value.

Threat model

Defeats a plain file-content scan for the watermark text. It does not resist an attacker who identifies this exact scheme and strips or overwrites both the manifest and the blob together. It catches a leak redistributed without modification, or by someone who didn't scrub the watermark.

Verified. For a protected jar built with a watermark, the extraction tool recovers the exact original text directly from the output jar file, with no classloading involved. A companion run with no watermark reports none, not a wrong or leftover value.