Compliance Ledger verifier

Drop in a Compliance Ledger export and check it: every evidence artifact against the address the chain committed to, every entry against its Ed25519 signature, every link back to genesis. Runs entirely in your browser; nothing is uploaded.

Every LiMon Professional deployment with the Compliance Ledger enabled can export its evidence chain as a single JSON file. This page checks one.

It recomputes the content address of every evidence artifact, verifies every entry’s Ed25519 signature over the exact bytes that were signed, and walks the chain link by link back to the genesis constant. It never rebuilds the canonical form of anything — that is what makes the same check reproducible in a shell, in Python, or in any language you like.

If you have no bundle to hand, load the sample and then press one of the buttons that edits it.

Choose a ledger export

Drop a bundle here or pick one. It is read on this device and never sent anywhere.

A bundle carries its own public keys, so on its own it can only be checked for internal consistency. Paste the fingerprint you recorded elsewhere and the check becomes meaningful.

This page is triage, not the audit check. It proves committed evidence has not been altered. It does not prove the producer canonicalized correctly when sealing, because it never rebuilds the canonical form. Establishing that requires an independent implementation, which is what the ledger_verify.py shipped with LiMon does.

This page implements bundle version . A bundle from a newer LiMon release is refused rather than guessed at — use the verifier shipped with that release.

Who is this for?

Anyone holding a Compliance Ledger export.

If you run LiMon, it is the quickest way to check a bundle you have just exported, or to see what your auditor will see before you send it.

If you are evaluating LiMon, it shows the Compliance Ledger is what we say it is, rather than a database table we could quietly UPDATE.

If you are an auditor holding a customer’s export, it runs on a laptop where installing Python is a three-week ticket.

It verifies one specific file format and does nothing else.

Is this the authoritative check?

No.

This page proves that committed evidence has not been altered: the bytes hash to the addresses the chain commits to, the signatures verify over those bytes, and the entries link back to genesis. That is the property that matters for tamper-evidence, and it is what a bundle’s own conformance.minimum_checks block asks a consumer to do.

What it cannot prove is that LiMon canonicalized correctly when it sealed the evidence in the first place, because it never rebuilds the canonical form — it checks the bytes it was given. If the producer had been wrong at seal time, the hash and the signature would agree with each other perfectly and nothing here would notice.

Establishing that needs an independent implementation of the canonicalization rules, which is exactly what tools/ledger_verify.py shipped with your LiMon release is: one self-contained file, standard library plus cryptography, that you can read end to end before you run it. Treat this page as triage and that file as the audit check.

Why should I trust JavaScript served by the vendor being audited?

For a formal audit, you should not. We serve this page, and we could serve different code to different visitors.

So the page shows its work. Every hash it computes is displayed next to the one the chain committed to, and each row carries the shell command that reproduces it on your machine with nothing but jq and sha256sum. If our numbers and your numbers disagree, believe yours.

The code is served unminified. It makes exactly one network request — fetching the sample bundle when you press that button — and the page is served with a Content Security Policy that blocks every other kind of outbound connection, so a request added by mistake would fail rather than succeed quietly.

What does the file I drop in actually contain?

A ledger export is not a log file. It carries your server names, your feature names, licence quantities and expiry dates, and per-feature usage totals — a fair picture of your estate, and commercially sensitive even though it is not personal data.

It carries no usernames. Usage is sealed per server and feature, never per user, so a GDPR retention run that scrambles usernames cannot change what was sealed. Usernames are simply never part of the evidence.

Either way it stays on your machine. The file is read by a Web Worker on this page and never leaves the browser tab.

Can I check a bundle without this page at all?

Yes, and you should if you can. Your LiMon release ships tools/ledger_verify.py — one self-contained file, standard library plus cryptography, that you can read end to end before you trust it:

python ledger_verify.py bundle.json --expected-fingerprint <hex>

That is the authoritative check, and it is the one to use for an audit.

Without even that, a shell reproduces the artifact half on its own. Every evidence artifact is carried as the exact bytes that were hashed, keyed by its own SHA-256:

jq -r '(.data // .).evidence["<address>"]' bundle.json | tr -d '\n' | sha256sum

That is the same one-liner the bundle carries in its own conformance.shell_example field. A file that has to survive a seven-year retention period should explain itself without depending on a web page still existing, so it does.

Why does it refuse some bundles instead of trying?

Every bundle states its format version and the algorithms it was built with. If this page meets a version it does not know — a bundle from a newer LiMon release, for example — it refuses to process it and tells you which version it found.

Use the ledger_verify.py shipped with that release, or come back once this page has been updated to handle the newer format.

It says GAPS but no findings. Is that bad?

No. The report separates three things on purpose.

Integrity findings mean committed material was altered. That is the serious one.

Gaps mean something is absent or incomplete but nothing was altered — evidence released under a retention policy, a chain slice that starts mid-history, a key installed without an attestation from the one it replaced, or a bundle that was never anchored outside the host that produced it. A day sealed as PARTIAL coverage is honest evidence that covers less than a whole day, not a failure.

Notes are context you need to read the result correctly, including the ledger’s own list of what it does not attest to. That list is written by the producer, not by us, and the page renders it verbatim.

What this tool does not claim

This tool is provided free and without warranty. It verifies the internal consistency of a file you supply; it makes no statement about your licence position, your contractual entitlement, or your compliance with any vendor agreement. Alia Software S.L. accepts no liability for decisions taken on the basis of its output. For an audit you should use the ledger_verify.py distributed with your LiMon release, and read it before running it.

All tools

Built by the people behind LiMon — on-premises license monitoring for FlexLM, RLM, LM-X and DSLS.