Verify Paridity yourself - a proof-of-value guide¶
The claim¶
You don't have to take our word for any of it. Paridity's core claims - accuracy (every byte-level difference detected, no false passes on Verified engine pairs, scoped to the threat model the accuracy proof states explicitly: replication faults and corruption, not a privileged insider deliberately tampering with both compared datasets), audit integrity (a complete, tamper-evident trail you can check without trusting our dashboards), speed (per-phase timings recorded for every run), and provenance (the images you run are exactly the ones we built and signed) - are each independently reproducible by you, in your own environment. This guide consolidates the concrete verification steps from the companion proof documents into one proof-of-value walkthrough.
This is Paridity's own thesis - prove it, don't assure it - applied to the evaluation process itself. The detailed claims, evidence citations, and limitations live in the companion documents; this guide tells you how to test them:
- Accuracy proof - the
hash_total/row_hash/field_diffcorrectness claim, per-engine verification status. - Audit & compliance proof - the append-only, hash-chained, offline-verifiable audit trail claim.
How it works (deterministic)¶
Everything you will verify below is deterministic computation, not inference - which is precisely why it is independently reproducible:
- Proof phase -
hash_total. Paridity computes an aggregate dataset fingerprint (hash_total) independently on source and target within a deterministically aligned time window, and compares the two values. Identical data produces identical fingerprints; a single changed byte does not. - Diff phase -
row_hash, thenfield_diff. If thehash_totalvalues differ, Paridity computes a per-row SHA-256row_hashon both sides to isolate exactly which rows differ, then compares those rows column-by-column to produce thefield_diffevidence - the exact row, column, and source/target values (subject to masking policy). - Audit trail - deterministic writes at defined points. The
config_checksum(SHA-256 of the canonicalized resolved config) is written before any comparison begins; every phase writes timestamps and aworker_idto the run's per-phase attempt records; evidence is append-only; and the trail can be exported as a hash-chained, signed evidence bundle verifiable offline.
Because every one of these is a defined algorithm over defined inputs - never a judgment call - you can recompute the same values yourself and check that they match what Paridity recorded.
Note: AI never determines correctness in Paridity. Correctness is always established deterministically - by aligned time windows,
hash_totalaggregate fingerprints,row_hashper-row fingerprints, andfield_diffcolumn comparisons. AI assists triage and explanation of already-computed results only; it never decides whether data matches and never auto-confirms an operator action.
What you can verify¶
| Claim | How you verify it | What proves it |
|---|---|---|
| Accuracy - a single changed byte is always detected, never silently passed | Force a known one-cell mismatch on the target and re-run the Mapping (Track A, steps 1-4); independently recompute the shipped hash test vectors offline (Track A, step 5) | The run reaches fail_field and the field_diff evidence identifies the exact row and column you changed; your own SHA-256 computation over the documented canonical string matches the shipped expected_row_hash |
| Audit integrity - the trail is complete and tamper-evident, verifiable without trusting the platform | Recompute a config_checksum from the resolved config snapshot; verify an evidence bundle offline with tools/verify_bundle.py; walk the bundle hash chain; verify the audit-log hash chain; trace the per-phase attempt records (Track B) |
Your independently computed SHA-256 matches the stored config_checksum; the bundle's content_hash and signature verify offline; each bundle's previous_bundle_hash equals the prior bundle's content_hash; the chain-verification endpoint reports the audit log intact; every phase has timestamps and a worker_id; and with asymmetric (KMS/ECDSA) signing the signature verifies against a public key you obtained from the data owner's KMS out of band - no shared secret, and nothing of ours to trust |
| Speed - run performance is measured and recorded per phase, not asserted | Run a Mapping over a dataset of ≥50,000 rows you control and read the proof and key-extraction phase durations from the per-phase attempt records (Track C) | Recorded started_at/completed_at per phase are the platform's own source of truth for run latency - you compute the throughput yourself from your own row counts and the recorded timings |
| Provenance - the images you run are exactly the ones Paridity built and signed | cosign verify each released image and the Helm chart by digest against its keyless Sigstore identity; pull and scan the per-image SPDX SBOM; read the three committed cloud install transcripts (Track D) |
The signature validates against the public Rekor transparency log for the exact build-workflow identity - no shared key to trust; the SBOM enumerates the shipped artifact, not a description of it; each install transcript reproduces a from-empty, signature-verified install with a live pass and a live fail |
Verify it yourself¶
The four tracks below are independent - run any or all of them. Tracks A (steps 1-4) and C require a live source and target you're willing to write a test value into; most evaluators do this with an SE in a sandboxed environment rather than a production system. Track A step 5, Track B step 3's offline verification, and Track D's signature and SBOM checks require no running Paridity application at all - only the released artifacts and a read-only registry pull token.
Track A - Accuracy¶
Reproduces the accuracy claim: a forced mismatch is always detected and pinpointed. (Source: accuracy proof, "Verify it yourself".)
- Create a Mapping between two engines from the accuracy proof's Verified list (e.g. PostgreSQL → Snowflake), pointed at a dataset you control.
- Run it once cleanly. Confirm the run reaches
pass_cleanand that the Run detail view shows a native-pushdown proof (not a DuckDB fallback, unless one of the two engines requires it - see the accuracy proof's Limitations table). - Force a known, single-cell mismatch on the target - change one value in one row directly in the target system.
- Run the Mapping again. Confirm:
- The proof phase's
hash_totalvalues now differ between source and target (visible on the Run detail page). - The run's status reaches
Issue detected- terminal statefail_field, because you changed a value (row counts still match, so the proofhash_totalfails, then the diff phase isolates the field). Had you instead added or removed a row, it would reachfail_count. Either way - never a silent pass. - The Evidence tab's
field_diffrecord identifies the exact row and column you changed, with the source and target values shown side by side (subject to your masking configuration). - Run the shipped test vectors independently of the running application.
tests/hashing/test_vectors.jsoncontains the canonical row-hash vectors (tv001-tv051) andhash_totalvectors (ht001-ht010) that gate every engine implementation before it can be declared production-ready. These are plain input/expected-output pairs - you do not need to trust Paridity's own test runner to check them; you can independently compute SHA-256 over the documented canonical string for any vector and confirm it matchesexpected_row_hash. This step can be done offline against the JSON file alone.
Track B - Audit integrity¶
Reproduces the audit-trail claim: complete, append-only, tamper-evident, and verifiable without the platform. (Source: audit & compliance proof, "Verify it yourself".)
- Recompute a
config_checksum. Pull a run's resolved config snapshot (linked from the run's config-version reference), apply the documented canonicalization rules (stripspec_version/generated_at/generated_by, sort all object keys and the documented arrays, serialize with no whitespace, UTF-8 encode), take SHA-256, and confirm it matches theconfig_checksumstored on the run's config-audit evidence record. This proves the policy in force was recorded before the run touched any data - and that you can check it without trusting Paridity's serialization. - Confirm append-only evidence. As an
auditororplatform_admin, attempt anUPDATEorDELETEagainst any evidence table other than the two documented lifecycle exceptions, from an ordinary application code path (not a database console) - there is no API surface that permits it. Ask your Paridity contact to walk through the retention-purge routine if you want to see the one sanctioned deletion path in code. - Verify an evidence bundle offline. Generate a bundle for a run
(
POST /runs/{execution_request_id}/evidence-bundle- the run is addressed by its execution request id), download it, and run the shipped verifier. With a KMS or ECDSA signing key configured, anyone can verify with the public key alone - obtain it out of band from the data owner's KMS (aws kms get-public-key,az keyvault key download,gcloud kms keys versions get-public-key) and runpython tools/verify_bundle.py --bundle <file> --public-key <pem>, or pin the copy embedded in the bundle with--public-key-fingerprint <sha256>; the verifier never trusts an embedded key unpinned. Public-key mode is stdlib-only - no packages to install. With an HMAC key, run--key-from-env HMAC_KEYwith the tenant's key from its own secrets backend. The platform'sPOST /evidence-bundles/{bundle_id}/verifyendpoint is the server-side complement; the offline tool is the one that does not require trusting the platform, and the out-of-band public key is the one that does not require trusting the bundle. - Walk the bundle hash chain. Generate two sequential bundles for the
same Mapping and confirm the second bundle's
previous_bundle_hashequals the first bundle'scontent_hash. - Verify the audit-log hash chain. Call
GET /audit/verify(or the equivalent chain-verification endpoint) and confirm it reports the chain intact; if automatic sealing is enabled, confirm the signature on the latest checkpoint validates against the configured signing key/public key. - Trace a run's phase timings. Pull the per-phase attempt records for a
run_idand confirm there is a row for each phase the run went through (readiness,proof_countandproof_hash, and - on a failed proof -key_extraction,field_diff,lag_retry), each withstarted_at,completed_at, andworker_idpopulated. - Trace a terminal status to its audit entry. Pick a run that reached a
terminal status and confirm the audit log has a matching entry with
actor, action, entity, and timestamp - and, for an admin-triggered
cancellation or a
bypass_readinessrun, that areasonis present.
Track C - Speed and scale¶
Paridity records how long every phase of every run took - so the speed evidence is your own environment's timings, not a vendor benchmark slide.
- Run a Mapping over a dataset of at least 50,000 rows you control, on
engines from the accuracy proof's Verified list, and let it complete
(
pass_clean, or afail_*state if you combine this with Track A). - Read the phase durations from the per-phase attempt records for that
run_id(the same query as Track B, step 6): theproof_countandproof_hashrows show how long the count andhash_totalproof took, and - on a failed proof - thekey_extractionandfield_diffrows show the diff-phase timings.started_atandcompleted_atare written by the platform for every phase of every run; these recorded timings, not ad-hoc stopwatch numbers, are the source of truth. - Compute throughput yourself from your own row count and the recorded phase durations. On Verified engine pairs the proof phase is pushed down into the engines as SQL aggregation - the rows are fingerprinted where they live rather than pulled across the network - so proof-phase duration is dominated by your engines' aggregation speed, not by data egress.
- Interpret the numbers honestly. Paridity engineering holds internal per-worker throughput floors as design targets, and this document deliberately does not quote a guaranteed rows/sec figure: observed throughput depends on your engines, warehouse sizing, network, and whether the run used native pushdown or the DuckDB reference fallback (visible on the Run detail page, and slower by design - see the accuracy proof's Limitations). What you can verify self-serve is that every phase's timing is recorded and attributable in your environment - and you can re-run the same Mapping on the same dataset to check the timings for yourself rather than relying on a one-off number. For sizing a production deployment against your row volumes, ask your Paridity contact for an SE-led benchmark against a dataset shaped like yours.
Track D - Provenance and supply chain¶
Reproduces the supply-chain claim: the images you run are exactly the ones
Paridity built and signed, and you can prove it without trusting Paridity's
build system. (Source: the digests-vX.Y.Z.{md,json} assets on each GitHub
Release; further supporting material available to reviewers on request through
your Paridity account contact.)
- Verify the release signatures yourself - keyless, against a public
transparency log. Paridity signs every released container image and the
Helm chart with cosign keyless signing (Sigstore): each signature is
bound to the GitHub Actions workflow identity that built the artifact and
recorded in the public Rekor transparency log - there is no shared signing
key to trust or to leak. After Paridity issues you a read-only registry
pull token (the images are in a private registry - see the note below),
verify each digest.
The identity string, the image names and the exact digests are printed in
the release's own
digests-vX.Y.Z.md- copy them from there rather than from this page. Every release published before the repository rename on 2026-10-27 - v1.3.1 and earlier, including this v1.2.0 example - was built under the product's former name: the identity namesEGMW2/DataAlignand the artifacts areghcr.io/egmw2/dataalign-{api,ui,docs}and the chartghcr.io/egmw2/charts/dataalign. Those signatures are permanent and verify exactly as published. The release workflow now builds under the new name, so a release published after the rename namesEGMW2/Paridityin its identity andparidity-{api,ui,docs}/charts/paridityfor its artifacts (at the time of this verification no such release had been published yet).The digest for each artifact is published in that release's owncosign verify \ --certificate-identity 'https://github.com/EGMW2/DataAlign/.github/workflows/release-images.yml@refs/tags/v1.2.0' \ --certificate-oidc-issuer 'https://token.actions.githubusercontent.com' \ ghcr.io/egmw2/dataalign-api@sha256:<digest> # repeat for ui / docs / chartdigests-v1.2.0.{md,json}asset. A verify that passes proves the image was built by that exact workflow at that exact tag; change a byte and it fails. - Pull and read the SBOM. Each release ships a machine-generated
SPDX-JSON SBOM per image (
sbom-dataalign-{api,ui,docs}-v1.2.0.spdx.jsonfor releases through v1.3.1;sbom-paridity-{api,ui,docs}-vX.Y.Z.spdx.jsonfrom the first post-rename release), generated by syft from the published digests - not a local rebuild - so it lists exactly what is inside the artifact you pull. Take it as a GitHub Release asset, or verify it as a cosign in-toto attestation bound to the same identity:Feed the SBOM into your own vulnerability scanner and license policy - you are auditing the shipped artifact, not a description of it.cosign verify-attestation --type spdxjson \ --certificate-identity 'https://github.com/EGMW2/DataAlign/.github/workflows/release-images.yml@refs/tags/v1.2.0' \ --certificate-oidc-issuer 'https://token.actions.githubusercontent.com' \ ghcr.io/egmw2/dataalign-api@sha256:<digest> - Read the reproducible install proofs. Paridity publishes a committed,
fail-first install transcript for each of the three managed Kubernetes
clouds - EKS, AKS, and GKE. Each records the same sequence you
would run: cosign-verify the signatures with the tamper and wrong-identity
legs proven to fail first, mirror the images digest-preserved into your own
cloud registry,
terraform applyfrom empty,helm installthe signed chart by digest, and a live reconciliation reaching bothpass_cleanandfail_counton native pushdown. Ask your Paridity contact for the transcripts and walk them against your own cluster. - Inspect the verification record behind these documents. Every proof
document in this pack carries a
last_verifieddate and cites the exact artifact behind each claim - the committed live-gate results (docs/live_gates/, including the 55/55 direct pairing-matrix run) and the dated benchmark artifacts. Paridity maintains a living verification ledger on a documented edition cadence with an explicit fail-first bar: a claim is not recorded as passing until it has been seen to go red against a planted defect. Its verified results are what these customer-facing documents render from. The provenance you can hold in your hand is the citation trail in these documents plus the committed artifacts they point to.
Important - the registry is private by design. Paridity's release images and chart are published to a private registry, so an anonymous
cosign verifyreturns a 401. This is deliberate: customers mirror the signed images into their own registry and run from there. You verify with a read-only pull token Paridity issues you - and once you have read access the signature check is fully independent of Paridity, because it validates against Sigstore's public transparency log, not against anything Paridity operates. Note also thatcrane copy-style mirroring copies the image only; signatures and attestations do not travel with it, so verify against the source registry before you mirror.Tip: An SE-led session can walk through all four tracks live against a sandbox Mapping - including a deliberately tampered evidence bundle so you can see offline verification fail as expected, which is the most convincing five minutes of the exercise.
Limitations¶
Be clear-eyed about what each track does and doesn't establish, and what you can run entirely on your own versus with an SE.
| Scope | Status | Notes |
|---|---|---|
| Offline hash test-vector verification (Track A, step 5) | Verified | Fully self-serve, no Paridity environment needed - plain input/expected-output pairs in tests/hashing/test_vectors.json, checkable with any SHA-256 implementation. |
| Offline evidence-bundle verification (Track B, step 3) | Verified | tools/verify_bundle.py runs independently of the platform. Requires a bundle generated by a live deployment first. |
| Third-party bundle verification with the public key alone (Track B, step 3) | Verified | With KMS/ECDSA signing, verification needs only the public key - no Paridity credential, no shared secret, and no packages to install. Live-verified against a real AWS KMS key in a throwaway container holding no cloud credentials, with six can-fail legs each exiting non-zero for a named reason. |
| Write-once anchor read-back (Track B) | Verified | Where the tenant's bundle object store is a write-once store, the verify endpoint reads the anchored object back in full and compares its hash with the platform record. A disagreement, an absence, and an unreachable store are each reported as exactly that - never as a pass. Live-verified on S3 Object Lock, and on Azure Blob immutability and GCS retention lock. |
| Forced-mismatch accuracy test (Track A, steps 1-4) | Verified | Requires a live source and target you can write a test value into - typically an SE-led sandbox, not production. Applies to engine pairs marked Verified in the accuracy proof; see that document's Limitations table for per-engine verification depth (including SUM-only engines and DuckDB-fallback paths). What this track demonstrates is the accuracy proof's stated threat model - an accidental or fault-induced change is detected; it is not a claim about a construction-aware insider crafting compensating changes (accuracy proof, Threat model section). If the Mapping under test declares an SCD scope, this track proves that declared current-rows scope rather than the whole table - the run carries a "Scoped: SCD current rows" badge to say so. |
config_checksum recomputation (Track B, step 1) |
Verified | Requires read access to the platform database (or an SE pulling the snapshot for you) plus the published canonicalization rules. |
| Audit-log hash-chain verification (Track B, step 5) | Supported | The chain and verification endpoint are shipped; automatic sealing is on by default (#2729) - a deployment that opts out has a verifiable-on-demand chain, not a continuously advancing one. See the audit proof's Limitations for signing-key options (HMAC default, ECDSA-P256, and KMS-backed signing on AWS KMS, Azure Key Vault and GCP KMS - each live-verified against a real key in that cloud) and their status. |
| Phase-timing trace and speed measurement (Track C) | Supported | Per-phase attempt-record timings are recorded for every run. This guide quotes no guaranteed throughput figure - your observed numbers depend on your engines and infrastructure; internal throughput floors are engineering design targets, not contractual SLAs. SE-led benchmarking is available for production sizing. |
| Release signature verification (Track D, step 1) | Verified | cosign keyless signatures on every released image and the Helm chart, live-attested since v1.1.1 and re-exercised by the release workflow's own fail-first verify job (correct identity passes, a tampered image and a wrong workflow identity are required to fail) on every release through v1.3.1, the latest at this verification. Independent of Paridity once you hold a read-only pull token - validated against Sigstore's public Rekor transparency log. The registry is private by design, so anonymous verification is not the model; you verify the images you mirror. |
| SBOM inspection (Track D, step 2) | Verified | SPDX-JSON per image, generated by syft from the published digests and shipped as both a GitHub Release asset and a cosign in-toto attestation. No CycloneDX output today. |
| Cloud install transcripts (Track D, step 3) | Verified | EKS / AKS / GKE from-empty installs with fail-first signature verification, live-attested against the published v1.1.1 artifacts; the v1.2.0 release was additionally install-verified on AKS. These are committed evaluation materials, not a live sidecar page - request them from your Paridity contact. |
| SLSA build-provenance predicate | Roadmap | Provenance today is cosign keyless signing plus an SPDX SBOM in-toto attestation; a formal SLSA provenance predicate is not yet generated. Do not read a SLSA level into these steps. |
| Roadmap replication adapters and engines | Roadmap | Tracks A and C apply to the engine pairs listed as Verified/Supported in the accuracy proof. Design-partner-pending replication adapters (e.g. SAP SLT, Qlik Replicate, Informatica CDC) and any engine not in that table are Roadmap - do not extend these verification results to them. Debezium, Airbyte, Fivetran, Oracle GoldenGate and Qlik Talend Cloud are the Tier-1 (production) replication adapters today. Note that Fivetran HVR is a separate product with no adapter - Evaluating, not Roadmap. |
| Deployment model | Verified | Everything in this guide runs inside your VPC - evidence, audit log, and signing keys never leave your environment. |
This guide consolidates the verification steps from the two companion proof
documents as of last_verified above. Where this guide and a companion
document differ, the companion document - which carries the underlying
evidence citations - wins.