How We Keep the Paid Code Out of the Open Repo, and How You Can Check
"Open core" is easy to say and hard to verify. A company announces that the scanner is open source, keeps a paid layer on top, and asks you to believe the line between them sits where they say it does.
We'd rather you didn't have to believe it. So here is where the line is, what enforces it, and how to check it yourself.
Two repositories, one direction of travel
bomwerk/bomwerk is the Community edition under Apache-2.0: scan, observe, trim and binscan. The paid extension lives in a separate private repository and is composed on top of the public one at build time. It isn't copied in. If you point the build at a private source tree that sits inside the public checkout, CMake refuses.
Fixes only travel one way. A Community fix lands in the public repository first, and the private side picks it up later through a reviewed pin bump. Nothing flows back, and the private repository is never merged into the public one. A paid release names two commit ids, the Community one and its own, so you can always tell exactly what was composed.
A default Community build doesn't compile or link any of the paid code, and the binary has no monitor, registry, triage, license or report command. Setting an environment variable called BOMWERK_PRO, editing a config file or supplying a license token can't add a command that was never linked. That switch exists at configure time and nowhere else.
The history is the risky part
Most open-core leaks don't happen in the current tree. They happen in the history. You delete the private directory, push, and the old commits still contain it. A published object stays fetchable by its id long after nothing points at it.
So we didn't make the old repository public. The public history starts at one root commit, made from a reviewed source snapshot. None of the earlier development history was carried over, because it contained the paid source. It still exists privately, and nothing is ever cherry-picked from it into the public repo. Work from before the cut gets re-applied as a reviewed patch.
Two checks, both on every change
The first, scripts/audit_public_history.py, looks at the whole repository: every ref, every commit, every object in the database, including ones a deleted branch left behind. The second, a CTest called pro_boundary, looks at the current checkout, the build's compilation database, the CLI command tree, runtime flag behavior and the namespaces inside the final binary.
Both work from a positive allowlist. A path is fine because the public layout lists it, not because it failed to match a list of things we remembered to call secret. A new top-level folder or an unfamiliar src/ module is a finding by default. That choice matters, because a blocklist only catches what somebody thought of in advance.
You can run the history audit on your own clone:
$ git clone --depth 1 --branch v1.0.0-rc.1 https://github.com/bomwerk/bomwerk.git
$ cd bomwerk && python3 scripts/audit_public_history.py .
public history audit: OK (1 commits, 828 objects, 1 refs)
That output is from a shallow clone of the rc.1 tag. A full clone reports bigger numbers, and the line to look for is the one that starts with OK.
What this doesn't claim
Separation of code isn't obfuscation, and it doesn't make a binary on a customer's machine tamper-proof. The same goes for the paid side's license check: it's an offline authorization control, not DRM. There's no phone-home and no hardware lock, and we don't pretend that signing makes software unmodifiable. The paid extension also isn't generally available yet. It's in preview, with no tagged release.
What the checks do give you is narrower and easier to test. The free binary contains no paid code, the public history contains no paid source, and both statements can be re-run by anyone with a terminal.
If a vendor tells you their core is open, ask them for the command that proves it. We think that's a fair thing to ask us, too.
Free repo scan: bomwerk.com
Not sure what your current SBOM is missing? We'll assess one repository across its supported ecosystems, explain the evidence gaps, and go deeper on C/C++ where the build context allows.
Get a free scan of one repo