Skip to content

v1.5.6 — Python verifier + Node↔Python cross-language proof

Choose a tag to compare

@alex-jb alex-jb released this 05 Jul 04:42

Extends the verifier reach past Node. Banks whose SIEM pipelines are Python-based (Splunk SDK, pandas-based audit tooling, custom compliance harnesses) no longer need Node on the box.

What's new

  • `python/shadow_verify/` — pure-Python verifier. Same wire contract as the Node primitive (pipe-delimited signing payload, sorted-key JSON canonicalization, base64 signature for Ed25519, hex for HMAC). Response shape identical to the Node MCP tool + HTTP endpoint. Stdlib-only for HMAC mode; `cryptography>=41` required only for Ed25519 PEM parsing.
  • `python/pyproject.toml` — `pip install python/` works out of the box. Ready for PyPI publish as `shadow-verify` v0.1.0.
  • `test/python-verify-cross-lang.test.js` — 5 cross-language tests where Node signs and Python verifies. Includes a nested-array-in-nested-object edge case that catches ANY canonicalization drift between the two implementations. Skips gracefully if `python3` or `cryptography` aren't installed on the runner — CI without Python stays green, but Python-equipped environments actively prove compat.

Verifier surface (cross-language complete)

Language Surface Path Best for
Node CLI `bin/verify-attestation.mjs` dev machines, procurement demos
Node MCP tool `shadow_verify_attestation` Claude Desktop / Cursor / OpenCode chat
Node HTTP endpoint `POST /api/verify-attestation` SIEM pipelines, CI, curl from anywhere
Python library `from shadow_verify import verify_attestation` Splunk SDK, pandas audit tooling, Python compliance harnesses

Why this matters

Banks are typically Python shops for compliance work. A Node-only verifier told a bank: "your ops team has to learn Node just to check a signature." That's friction that scuttles procurement conversations. `pip install shadow-verify` removes it.

Use

```python
from shadow_verify import verify_attestation

result = verify_attestation(
attestation=persisted["response"]["attestation"],
original_request=persisted["request"],
original_response={k: v for k, v in persisted["response"].items()
if k != "attestation"},
public_key_pem=open("shadow-public.pem").read(),
)
if result["ok"]:
print(f"verified — model_id: {result['model_id']}, key_id: {result['key_id']}")
```

Response shape identical to the Node MCP tool + HTTP endpoint, so audit-trail comparability holds regardless of language.

Tests

  • Node test suite: 543 → 548 (+5 cross-language). All green.
  • Python test suite: 16/16 passed via `python3 python/tests/test_verify.py`.

Not yet shipped

  • PyPI publish (needs Alex's Trusted Publisher setup at pypi.org)

Full details: CHANGELOG.md