Skip to main content

Offline evidence-bundle verification and sealing for GuardSpine (Python)

Project description

guardspine-kernel-py

Python implementation of the GuardSpine kernel -- evidence-bundle verification and sealing.

License

Produces byte-identical hashes to the TypeScript reference (@guardspine/kernel) and the Lean 4 formal verification backend. All three implementations use RFC 8785 canonical JSON serialization and are validated against shared golden vectors from guardspine-spec.

Language Implementations

Language Package Purpose
TypeScript @guardspine/kernel Reference implementation (canonical)
Python (this repo) guardspine-kernel Python integrations (FastAPI, CLI, ML pipelines)
Lean 4 guardspine-lean Formally verified backend

v0.2.1 adds optional sanitization metadata (PII/secret redaction attestation). The proof format is unchanged from v0.2.0.

Installation

pip install guardspine-kernel

From source:

pip install -e ".[dev]"

Requires Python 3.10+. Single runtime dependency: cryptography>=42.0.0.

Usage

Sealing a Bundle

from guardspine_kernel import seal_bundle

items = [
    {
        "item_id": "audit-001",
        "content_type": "guardspine/audit_event",
        "content": {"action": "user_login", "user_id": "u123"},
    },
    {
        "item_id": "audit-002",
        "content_type": "guardspine/audit_event",
        "content": {"action": "data_access", "resource": "customers"},
    },
]

result = seal_bundle(items)
print(result.immutability_proof.root_hash)
# sha256:...

Verifying a Bundle

from guardspine_kernel import verify_bundle

bundle = {
    "bundle_id": "bundle-001",
    "version": "0.2.0",
    "created_at": "2026-01-15T10:30:00.000Z",
    "items": [...],
    "immutability_proof": {...},
}

result = verify_bundle(bundle)
if result.valid:
    print("Bundle is valid!")
else:
    for error in result.errors:
        print(f"{error.code}: {error.message}")

Canonical JSON

from guardspine_kernel import canonical_json

# RFC 8785 compliant JSON serialization
obj = {"z": 1, "a": 2}
print(canonical_json(obj))  # {"a":2,"z":1}

Lean Shim (Formal Verification Backend)

The lean_shim module delegates cryptographic operations to a compiled Lean 4 binary via subprocess. This provides formally verified canonical JSON, content hashing, bundle sealing, and bundle verification -- the same operations the Python code performs, but with machine-checked correctness proofs.

What the Lean binary provides

  • RFC 8785 canonical JSON serialization
  • SHA-256 content hashing of canonicalized payloads
  • Evidence bundle sealing with hash chains and root hashes
  • Bundle verification (hash/chain/root integrity checks)

Signature verification is not yet implemented in Lean. When require_signatures=True, the shim falls back to the Python implementation.

Subprocess bridge protocol

The shim communicates with the Lean binary over stdin/stdout:

guardspine <entrypoint>
  • CLI argument = entrypoint name (canonical_json, compute_content_hash, seal_bundle, verify_bundle)
  • stdin = JSON payload (one line)
  • stdout = {"ok": true, "result": ...} on success, {"ok": false, "error": "..."} on failure
  • Exit code = 0 on success, non-zero on crash
  • Timeout = 30 seconds per call

Setup

  1. Build the Lean binary from the guardspine-lean repo:
cd guardspine-lean
lake build guardspine

This produces a native binary (e.g., .lake/build/bin/guardspine on Linux/macOS, .lake\build\bin\guardspine.exe on Windows).

  1. Set the environment variable to point at the built binary:
export GUARDSPINE_LEAN_BIN=/path/to/guardspine-lean/.lake/build/bin/guardspine

GUARDSPINE_LEAN_EXE is accepted as an alias.

  1. The shim auto-activates when imported. If the env var is unset or the binary is missing, lean_shim raises ImportError. Callers can catch this and fall back to the pure-Python implementation:
try:
    from guardspine_kernel.lean_shim import seal_bundle, verify_bundle
except ImportError:
    from guardspine_kernel import seal_bundle, verify_bundle

Parity testing

tests/test_lean_parity.py runs the same scenarios through both the Lean shim and the Python implementation, asserting byte-identical hashes. These tests skip automatically when the Lean binary is not available.

GUARDSPINE_LEAN_BIN=/path/to/guardspine pytest tests/test_lean_parity.py -v

Hardening

Security measures matching the TypeScript kernel:

  • Seal validation guards: seal_bundle validates item_id and content_type presence before processing, raises ValueError with the offending index
  • Max chain items: build_hash_chain rejects inputs exceeding 10,000 items
  • Proof version support: both v0.2.0 (current) and legacy (deprecated 3-field chain hash)
  • Non-empty items: seal_bundle raises on empty items list
  • Version enforcement: verify_bundle rejects versions other than "0.2.0" or "0.2.1"

Signature Verification

verify_signatures supports the same algorithms as the TypeScript kernel:

Algorithm Implementation
ed25519 cryptography library Ed25519 verification
rsa-sha256 RSA PKCS1v15 with SHA-256
ecdsa-p256 ECDSA with SECP256R1 and SHA-256
hmac-sha256 hmac.compare_digest with shared secret

Public keys are passed via public_keys dict (key_id -> PEM string). HMAC secrets via hmac_secret parameter.

API Reference

Sealing

  • seal_bundle(items, options, bundle_id, version, created_at) -- Seal items into a bundle dict
  • build_hash_chain(items, options) -- Build hash chain from ChainInput list
  • compute_content_hash(content) -- SHA-256 of canonical JSON ("sha256:<hex>")
  • compute_root_hash(chain) -- Root hash over concatenated chain hashes

Verification

  • verify_bundle(bundle, ...) -- Full bundle verification (fields, content, chain, root, cross-check, signatures)
  • verify_hash_chain(chain, ...) -- Verify chain linkage and recompute chain hashes
  • verify_root_hash(proof) -- Verify root hash matches chain
  • verify_content_hashes(items) -- Verify item content hashes via canonical JSON
  • verify_signatures(bundle, ...) -- Verify Ed25519/RSA/ECDSA/HMAC signatures

Error Codes

All error codes match @guardspine/kernel/errors.ts:

Code Meaning
MISSING_REQUIRED_FIELD Bundle missing required field
UNSUPPORTED_VERSION Bundle version not "0.2.0" or "0.2.1"
INPUT_VALIDATION_FAILED Invalid input format
CONTENT_HASH_MISMATCH Content hash does not match
HASH_CHAIN_BROKEN Chain linkage broken
ROOT_HASH_MISMATCH Root hash does not match
SEQUENCE_GAP Sequence numbers have gaps
LENGTH_MISMATCH Items count != chain length
SIGNATURE_INVALID Signature verification failed
SIGNATURE_REQUIRED Bundle must have signatures

Cross-Language Parity

pytest tests/test_parity.py -v

Golden vectors are stored in ../guardspine-spec/fixtures/golden-vectors/.

License

Business Source License 1.1 (source-available) -- see LICENSE. Free for non-commercial, evaluation, and small-organization use (annual revenue under USD 1,000,000); other production use requires a commercial license from GuardSpine, Inc. Each version converts to Apache-2.0 four years after its release.

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

guardspine_kernel-2.0.0.tar.gz (23.3 kB view details)

Uploaded Source

Built Distribution

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

guardspine_kernel-2.0.0-py3-none-any.whl (20.1 kB view details)

Uploaded Python 3

File details

Details for the file guardspine_kernel-2.0.0.tar.gz.

File metadata

  • Download URL: guardspine_kernel-2.0.0.tar.gz
  • Upload date:
  • Size: 23.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.5

File hashes

Hashes for guardspine_kernel-2.0.0.tar.gz
Algorithm Hash digest
SHA256 e5498279ccdb9f71651e6fb5964545225cb97e8a999ee2d2dc89153407006626
MD5 8f621fbdb07d0d3804c1a27e0586d218
BLAKE2b-256 893fdd665ce82e9fe18eb2391257a43ca432b4ef3bedad7abb7d42b490cd2dc7

See more details on using hashes here.

File details

Details for the file guardspine_kernel-2.0.0-py3-none-any.whl.

File metadata

File hashes

Hashes for guardspine_kernel-2.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 6e2cb6f61b84228783b5c550ea8b7c8acd0af84a8cc0d98beeb1be64120edac7
MD5 500f036b1ccf5d39656676018097cf3f
BLAKE2b-256 342c2d5c71db12680d49b9f19621694137b28957ab6dd4363f0315f80a460dd3

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