Lumra signs each event the moment it arrives, chains it so tampering is detectable, and exports a ProofPack that anyone can check offline with a standalone tool. Here is exactly how it works, and exactly what it does not claim.
Every event is signed the moment it arrives. Where the edge device can sign at the source with its own key, Lumra preserves that device signature and re-verifies it independently. The production signing key lives in a hardware security module and never leaves it.
Signed record digests are linked into a tamper-evident hash chain, ordered by the time the server received them. A backdated payload cannot quietly reorder history.
Any record exports as a ProofPack and can be checked later, offline, by anyone, with a standalone verifier that contacts no PriviNet system.
The precise promise: integrity you do not have to trust us for. A ProofPack proves a record was not altered after signing and was signed by PriviNet's published key. It does not claim to prove when the underlying event occurred, and we make no promises about court admissibility.
Records and ProofPack manifests are signed with ECDSA P-256 (SHA-256), key id kms-1944107aa98ec035, held in a Google Cloud KMS hardware security module, FIPS 140-2 Level 3, non-extractable. Our servers can request a signature. They can never read or copy the private key. A full compromise of the application server yields no signing key.
If the HSM is briefly unreachable, production does not silently downgrade. A record signed by the software fallback key is labeled software_key in the record itself, and is never passed off as HSM-signed. The verifier surfaces that distinction to the reader.
The prior software key, Ed25519, key id sw-77396abcd4102123, is not compromised. It still verifies every record it signed before the 2026-07-06 cutover, and remains listed as an availability fallback. Old ProofPacks keep verifying.
Every PriviNet signing key is published out-of-band at privinet.net/keys.txt, machine-readable at /keys.json. A ProofPack counts as signed by PriviNet only if its signing key matches that list, a published directory pinned inside the verifier itself, so a swapped directory fails the check.
The sharp question a claims examiner or opposing expert asks is not "is it signed" but "who signed it, and when." A record a device signed at capture is stronger evidence than one Lumra sealed when it arrived. Both are useful; they are not equal, and pretending they are is how evidence stories fall apart under scrutiny. So every Lumra record carries one of five signing states, the verifier confirms which applies, and the ProofPack prints it in plain language. Intake-sealed data is never presented as if a device had signed it.
Implementation status: source-signed, cloud-signed, and unverified states are exercised in the product and test paths. Gateway-signed and vendor-preserved states require the relevant integration. The exact deployed revision is identified during controlled onboarding; a taxonomy in code is not represented as a completed customer integration.
Lumra proves less than a magic box would, and says so. Here is the boundary, stated before opposing counsel finds it for you.
Digests are computed over canonical JSON: sorted keys, fixed separators, ensure_ascii false, UTF-8. A reformatted but identical file still verifies. Any change to a meaningful value fails. We describe it that way rather than claiming every raw byte is bound, because canonical whitespace is deliberately normalized.
Each event hash binds the payload, the analysis, and the evidence window under a domain-separation context string. Digests from one context cannot be replayed into another.
The hash chain and incident timelines order by the server-assigned receipt time, not the client-supplied timestamp. A backdated payload cannot reorder the ledger.
When a timestamp token is present, the package retains its status and imprint so the standalone verifier can check what digest it covers. Missing, delayed, failed, or unconfirmed time evidence is reported rather than hidden. A token time does not prove the sensor reading, the claimed observation time, or complete capture.
Court exhibits are archived to write-once, read-many Cloud Storage with object versioning and a multi-year retention policy. Once written, an exhibit cannot be silently overwritten or deleted within the retention window.
A ProofPack is the portable, self-contained evidence bundle. It includes:
The analysis inside a ProofPack is framed as decision-support and documentation, not a determination of fact, liability, or medical diagnosis.
Every ProofPack carries an Evidence Trust Assessment: a fixed, versioned set of deterministic checks that either fired or did not. It is not a score, not a machine opinion, and not a judgment about what happened. It is a record of which signals were present, so a reader can weigh the evidence rather than take a label on faith.
Read it plainly: when nothing is flagged, the assessment says so by name, listing the checks that ran and did not fire, so silence is explicit rather than assumed. Each check names the ruleset version that produced it. The assessment rides inside each ProofPack's sealed bundle, so the manifest signature binds it and the standalone verifier's manifest check rejects any later edit to it. It is context for a human decision, never a determination of fact or liability.
The verifier is a single Python file, verify_proofpack.py, that contacts no PriviNet system. It needs Python 3.9+, one common crypto library, cryptography or pynacl, and OpenSSL to verify RFC-3161 timestamp signatures. Without OpenSSL, timestamp status is INDETERMINATE, never a pass. The digest checks run on the standard library alone. It checks:
Current verifier: 1.3.2. SHA-256: fe9c7bb5085e7b6e6bff71388cc71a6f54cc93e264002ea381c0eb8e3c6cdf2c.
Try it yourself, no account: download the verifier and a sample ProofPack, confirm the key in the key directory, install cryptography, ensure openssl is on your PATH for timestamp verification, and run it. Change any sealed value and watch it fail.
What "verified" means, plainly: it proves the record was not altered after signing and was signed by PriviNet's published key. It does not prove when the underlying event occurred.
| ECDSA P-256 (SHA-256) | Production record and manifest signatures, HSM-held key. |
| FIPS 140-2 Level 3 HSM | Custody of the non-extractable production signing key (Google Cloud KMS). |
| Ed25519 | Source-device signatures and the retired-but-honored software fallback key. |
| SHA-256 over canonical JSON | Component digests and the domain-separated composite event hash. |
| RFC-3161 | Independent third-party timestamp anchoring, bound into the manifest. |
| WORM object storage | Write-once evidence archive with multi-year retention. |
| FRE 902(13)/(14) | Pre-filled self-authentication certification template in each ProofPack. |
Established primitives, applied end to end. The value is where they are applied, from the source to independent verification, not in inventing new cryptography.
Production and staging are intentionally separated. The production service continues to expose the older per-event ProofPack path. The Gate 3 case-package and receipt-batch workflow passed an isolated staging rehearsal, but has not been represented as production. A pilot release must name and verify the exact deployed revision.
The standalone verifier is the public trust boundary. Version 1.3.2 rejects altered protected content and requires non-production trust to be supplied separately. OpenSSL is required for RFC 3161 token verification. This is independent machine verification, not a human cryptographic or legal audit.
The TTN path is a release candidate. Complete original uplink JSON can be sealed through the raw adapter, and ordinary TTN retries receive a deterministic tenant-scoped identity when the sender supplies none. Disposable-PostgreSQL concurrency remains part of deployment acceptance and is not silently described as passed.
The EU profile is in development. It binds a closed batch root to an RFC 3161 request and retains the response and service identity for later validation. No real token from the prospective qualified service has been independently validated, and authenticated historical trusted-list and revocation validation remains incomplete. The only honest qualification result today is INDETERMINATE.
Pull a sandbox ProofPack from the public demo lane, no account needed, and run the standalone verifier against it. No call required.