Repository navigation
Releases: litzki-systems/sovp-python
Release list
sovp 1.1.1
Fixes a defect found in an external review of the published surface: the documented live-validation path could not succeed against any real deployment, including this project's own.
validate_domain() rejected correctly signed, unexpired documents. It passed check_timestamp=True unconditionally, which enforced the issuance window of draft Section 9.4 (default W = 600 s) against freshness.created. A statically published .well-known document is re-signed on its validity cycle, not per request, so the window could never be satisfied — validate_domain("litzki-systems.com") returned psi_core = 0. The window is now opt-in:
validate_domain("litzki-systems.com") # psi_core 1, reason "ok"
validate_domain("litzki-systems.com", check_timestamp=True) # psi_core 0, reason "issuance_window"freshness.expiresAt and host binding are still always enforced.
New reason field. validate_domain() now names the first failed check — ok, host_mismatch, signature, freshness_missing, freshness_invalid, created_in_future, expired, issuance_window, no_key — so an expired document is distinguishable from a forged one. Backed by the new verify_identity_detail(), which returns (verified, reason). verify_identity() keeps its boolean contract unchanged.
generate_identity_document() default validity. It defaulted freshness.expiresAt to created + 1 hour, while its own docstring and draft Section 10 both claimed the field was omitted unless supplied. The default is now created + DEFAULT_VALIDITY_DAYS (90 days), matching what the production deployments publish.
Documentation. The README's "Live validation example" pointed at examples/validate_live.py, which the PyPI distribution does not contain, and printed an expected output that was wrong in two fields. It is now a three-line example over the installed API with its real output. Two dead draft cross-references corrected: the issuance window is Section 9.4 (not 7.2, which does not exist in revision 04), the 300-second DNS TTL recommendation is Section 9.3 (not 6.1). requires-python = ">=3.9" is now declared.
No change to the wire format, the schema, the signed scope or the canonicalization. 80 tests pass.
Full detail in CHANGELOG.md.
sovp 1.1.0
Added
sovp/core.py—generate_identity_document()now signs afreshnessobject (created,nonce,expiresAt) as part of the Ed25519-signed scope; defaultcontext_versionchanged from"v1.4"to"v2.0". Previously these fields lived inside the unsignedintegrity_proofand were forgeable without invalidating the signature — same weakness as the already-documentedexpiresAtforgeability insovp-engine's scanner. Closes the replay-protection gap described indraft-litzki-sovp-04.tests/test_vectors.py— Test Vector Set 2 (schema v2.0, real generated+verified signatures) covering the newfreshnessobject, including tamper rejection forfreshness.created/freshness.expiresAt. Test Vector Set 1 (v1.4, locked) is unchanged.sovp/document_safety.py—parse_unverified_sovp_document(), a minimal JSON parser enforcing draft-litzki-sovp-04's "Resource Limits for Unverified Documents": rejects a document larger than 64 KiB, nested deeper than 16 levels, or containing a duplicate member name in any object, before the document is trusted with any further processing.
Changed
pyproject.toml— thecryptographybound stays at>=38.0.0,!=40.0.0,!=40.0.1,<42. It matches theRequires-Distline of the OS-packaged pyOpenSSL 23.2.0 on Ubuntu 24.04, whichcertbotimports. A globalpip install sovpwith a higher bound shadows that version and breaks certificate renewal. The library itself runs on newercryptographyreleases; the bound protects the system install.CHANGELOG.md— the 1.0.1 entry referenced a parameter count. It now states that the parameter count references were aligned with the protocol specification.README.md— the introduction namespip install sovpas the normal installation route and keeps the editable clone for development.sovp/core.py—verify_identity()'scheck_timestamppath now readsfreshness.createdfirst and falls back to the unsignedintegrity_proof.createdonly for documents whose@contextpredates v2.0; this fallback affects timestamp freshness checking only, never signature verification.README.md— schema example and "Replay protection" table row updated to the v2.0/freshnessshape; added an explicit callout that the tamper-resistance guarantee is new as of v2.0 and did not hold under v1.4.README.md—contentAddressexample corrected from the stale prefixed"sha256:<hex>"single-field form to the shapegenerate_identity_document()actually ships:{"alg": "sha256", "digest": "<hex>"}.README.md— removed theparameters(entropy_threshold/determinism_score) field from the schema example; it does not exist in any reference implementation (sovp-python,sovp-engine, or the Cloudflare Worker) and was never anything other than an illustrative artifact. Found while reconcilingdraft-litzki-sovp-04against the running implementations — the draft's own schema example had the same field, removed there too.sovp/core.py— Draft 04 host binding is enforced throughexpected_host; v2.0 freshness remains signed and expiry is always validated. Generated DNS key references use the URL hostname, excluding ports and normalizing trailing dots and case.sovp/resolver.py— DNS TXT parsing now accepts only the exactv=SOVP1; k=<base64>record shape and requires a valid 32-byte Ed25519 public key. Legacy endpoint fallback remains restricted to HTTP 404.examples/— live validation, end-to-end verification, and the ARD trustManifest example now identify Draft 04 explicitly and demonstrate v2.0 host binding and the currentcontentAddressshape.workers/sovp-identity/— the reference worker now serves a publisher-supplied, pre-signed Draft 04 v2.0 document from a Cloudflare secret instead of embedding a stale v1.4 artifact.
Fixed
tests/test_vectors.py—contentAddress.digestin Test Vector Set 2 was wrong. The vector shipped33465a2b…3ae2b5; the correct value oversha256(JCS(signed scope))isd00c6db5…30b460. No test read the field, so the vector and the specification drifted apart unnoticed.sovp/core.py—verify_identity()no longer fails open whenintegrity_proof.createdis missing; withcheck_timestamp=Truea missingcreatedis now a rejection (Psi_core = 0), closing a replay bypass of draft Section 7.2sovp/core.py—verify_identity()no longer raisesAttributeErrorwhenintegrity_proofis a non-dict value (attacker-controlled since it's excluded from the signed payload); now returnsFalseper the documentedbool-only contractsovp/resolver.py—fetch_identity_document()usedresp.json()(==json.loads()) to parse a remote, not-yet-signature-checked document, with no size, depth, or duplicate-key limit. Now parses viaparse_unverified_sovp_document().
Tests
tests/test_vectors.py— two tests now recomputecontentAddress.digestfrom Test Vector Set 2 itself and assert that a change inside the signed scope changes the recomputed digest. This keeps the vector and the specification from drifting apart again.- Added Draft 04 conformance coverage for freshness clock-skew boundaries, the 600-second issuance window, signed unknown top-level members, unsigned
contentAddressandscanextensions, host normalization, URL ports, and exact DNS TXT syntax.
sovp 1.0.5
Diese Release-Notiz wurde nachträglich angelegt am 09.10.2026. Daher steht sie in der Liste nach v1.1.0, obwohl 1.0.5 die ältere Version ist.
This release note was created retroactively on 2026-10-09. It therefore appears after v1.1.0 in the list although 1.0.5 is the older version.
Fixed
pyproject.toml— capped the unpinnedcryptographydependency to>=38.0.0,!=40.0.0,!=40.0.1,<42. A globalpip install sovpon a server also runningcertbot/pyOpenSSL(OS-packaged) could pull acryptographyrelease newer than pyOpenSSL supports, shadow the OS-packaged version, and break certbot withAttributeError: module 'lib' has no attribute 'GEN_EMAIL'. The cap matches the range pyOpenSSL 23.x (Ubuntu 24.04's apt version) actually declares support for.
SOVP 1.0.4 — Packaging release
SOVP 1.0.4 — Packaging release
Fixed
sovp-Quellmodule werden jetzt ins gebaute Wheel aufgenommen (packages.find include = ["sovp*"]), sodass pip install sovp die importierbaren Module sovp.core, sovp.cli und sovp.resolver ausliefert.
Protocol specification: draft-litzki-sovp-03