Skip to main content

Standalone verifier for Marturia (Plumb v2) cryptographic audit receipts.

Project description

marturia-verify

Standalone verifier for Marturia cryptographic audit receipts.

Anyone holding a Marturia receipt and the issuing tenant's public key can verify the receipt without trusting the Marturia infrastructure that issued it. That's the point: cryptographic testimony you can audit independently.

Install

pip install marturia-verify

The only runtime dependency is cryptography.

CLI

# Verify a single receipt
marturia-verify --receipt receipt.json --pubkey tenant.pub
# → VALID: signature valid; receipt_hash matches; sequence 42 of tenant 12

# Verify a contiguous chain
marturia-verify --chain receipts.json --pubkey tenant.pub
# → VALID: chain valid: 27 receipt(s), seq 1..27

# Public key inline as hex
marturia-verify --receipt receipt.json --pubkey-hex 4f3a...64hex...

# Quiet mode (one-line output)
marturia-verify --chain receipts.json --pubkey tenant.pub --quiet

Exit code: 0 on success, 1 on any verification failure.

Library API

from marturia_verify import verify_receipt, verify_chain

# Single receipt
result = verify_receipt(receipt_dict, public_key_bytes)
if not result.valid:
    raise RuntimeError(result.reason)

# Chain — public_key must match the signing key for every receipt in the
# chain. If your chain crosses a key rotation, split it at the boundary
# and verify each segment with its own public key.
chain_result = verify_chain(receipts, public_key_bytes)
print(chain_result)  # VerifyResult(valid=True, reason=..., receipt_seq=27)

Both functions return a VerifyResult — a frozen dataclass with .valid, .reason, .receipt_seq, .tenant_id. It's also truthy/falsy, so if not result: works.

Receipt format

A Marturia receipt is a JSON object with these fields:

Field Type Notes
payload_canonical_bytes hex or base64 string The exact bytes that were signed. NOT the deserialised payload — the canonical-JSON-encoded version with sorted keys, no whitespace, embedded schema/meta.
tenant_id int The Marturia tenant the receipt belongs to. Bound into the hash.
receipt_seq int Per-tenant monotonic sequence (1, 2, 3, ...). Bound into the hash.
prev_hash hex string or null SHA-256 of the previous receipt in this tenant's chain. null when receipt_seq == 1.
receipt_hash hex string `sha256(prev_hash
signature hex string Ed25519 signature of receipt_hash, raw 64 bytes hex-encoded.
kid string (optional) Signing key ID at signature time. Informational.

What this verifier checks

For each receipt:

  1. All required fields are present
  2. The public key, signature, and stored receipt_hash are well-formed
  3. The recomputed receipt_hash matches the stored one (catches body modification)
  4. The Ed25519 signature verifies against the public key (catches forgery)

For a chain (verify_chain):

  1. receipt_seq is contiguous ascending with no gaps
  2. Each receipt's prev_hash matches the previous receipt's receipt_hash (catches insertion / reordering / removal)

What it does NOT check:

  • Witness cosignatures on Merkle roots — those are a separate transparency layer (see Marturia design doc 05). This package verifies the per-tenant chain; cosignature verification will land in a future release.
  • Plan / billing / authorisation — that's enforced at issuance time, not in the receipt itself.

Why this exists

Every other observability vendor stores audit logs in a database they alone control. They could rewrite history and you'd never know. Marturia signs each event into a hash-chained ledger using a per-tenant Ed25519 key. The chain itself is rolled into Merkle roots that can be cosigned by independent witness peers — including your own customers, your own auditors, or third-party witnesses you trust. A compromised Marturia operator cannot forge history if any single witness cosigner is honest.

This package is the public verifier — anyone can check any receipt without our cooperation. That's the whole moat: cryptographic testimony you don't have to take our word for.

Versioning

The receipt format is _schema_v: 1 (visible in the payload_canonical_bytes payload). When Marturia eventually bumps to schema v2, this package will keep reading v1 receipts forever (they're permanent evidence) and add v2 support in a new minor release.

License

MIT.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

marturia_verify-0.1.0.tar.gz (13.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

marturia_verify-0.1.0-py3-none-any.whl (10.3 kB view details)

Uploaded Python 3

File details

Details for the file marturia_verify-0.1.0.tar.gz.

File metadata

  • Download URL: marturia_verify-0.1.0.tar.gz
  • Upload date:
  • Size: 13.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for marturia_verify-0.1.0.tar.gz
Algorithm Hash digest
SHA256 3e600e0bc5c41bc363f01f07853823307104492c35c34c094352a0db79599818
MD5 4115051a55c311da8b59b9a830de23cf
BLAKE2b-256 dd37d429a440ea81c39d8a402a6891030089023d825d2646b501f3a8ebbe669b

See more details on using hashes here.

File details

Details for the file marturia_verify-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for marturia_verify-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 493f12eb7879d6df361f0376b52a1fc723ed945a276024eee7f6a8edf3492bfd
MD5 c6af487a9563d47ed4d7b46565b0612c
BLAKE2b-256 77ca54037b3a2fc173fdcc36d46755ee2ddf520f9817e6869038c55f754f6459

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page