osyra_ome.verify.composite
Private pre-release / network boundary: The currently usable customer surface is offline verification of an existing signed artifact against an out-of-band trust anchor. Memory/network RPC APIs and host snippets on this page describe protocol and interface shape; the public Edge bridge, package publication, and release acceptance remain pending. Do not treat
api.osyra.ai:443examples as a released customer route.
verify.composite — offline OCV-1.0 composite-receipt verification (v0.1).
Per the AP00016 OCV-1.0 composite design (`AP00016-OCV-COMPOSITE-RECEIPT-DESIGN.md`)
- ADR-161 + `cddl/eat-ocv-v1.cddl`. The composite receipt is a NEW EAT ``receipt_kind == "OCV"`` carried INSIDE the opaque ``receipt_body`` (claim key ``-65538``) of the standard ADR-146 EAT envelope. The outer COSE_Sign1 signs the whole ocv-body (composition-tree + leaf sub-envelopes + bindings + transport-witness) plus the outer ``cti``/``nonce``.
WIRE FORMAT (verified against the Go reference ``AP00016-verifier-svc/internal/codec/eat/{composite,binding,verify_composite}.go`` and the frozen KAT vector ``testdata/ocv-kat/OCV0-composite.cbor``):
* The envelope is an *untagged* COSE_Sign1 4-array over canonical CBOR
(RFC 8949 §4.2.1 / RFC 9052):
[ protected_bstr, unprotected_map(0xA0), payload_bstr, signature_bstr ]
protected is the byte-allowlisted header canonical_cbor({1:-8}) =
0xA1 0x01 0x27 (Ed25519, the only v1.0 suite); unprotected is the
empty map 0xA0. The signed Sig_structure is
canonical_cbor(["Signature1", protected_bstr, external_aad(empty bstr), payload_bstr]).
* ``payload`` is the Form-B preimage ``canonical_cbor([tstr("osyra-eat-v1"), claim-map])``.
The claim-map uses integer keys 1(iss) 6(iat) 7(cti) 10(eat_nonce)
-65537(receipt_kind) -65538(receipt_body) -65539(alg_suite) -65540(ws).
* For ``receipt_kind == "OCV"`` the ``receipt_body`` decodes to the ocv-body
map {0: composition-tree, 1: [leaf-envelope...], 2: bindings-map, 3: transport-witness}. Each leaf-envelope is a complete nested EAT
COSE_Sign1 (depth-1: a leaf's receipt_kind MUST NOT be "OCV").
* A binding-spec ``{0: adapter-id, 1: left-idx, 2: src-path, 3: right-idx,
4: dst-path}HOLDS iff SHA-256(canonical_§4.2.1(leaves[left-idx].body @ src-path)) == leaves[right-idx].body @ dst-path``.
HONEST SCOPE (the SDK boundary — verbatim into every downstream claim): ``verify_ocv_composite`` proves the composite is a **well-formed, single-(outer)-signed, tenant-uniform, depth-1, correctly-bound chain**:
- the OUTER EAT envelope's COSE_Sign1 signature (under the supplied, pinned issuer pubkey) over strict canonical CBOR;
- each LEAF envelope's COSE_Sign1 signature (under a leaf-key set) +
canonical claims + tenant-uniformity (leaf
ws== outerws) + depth-1 (no leafreceipt_kind"OCV"); - each interior committed-digest binding (anti-splice).
It does NOT perform per-kind LEAF RE-DECISION (e.g. re-deriving a VIR's inner content-hash, or re-running an OCVR's veracity gate). That is the L5 Verifier-of-Record's job (the registered ``ReDecider`` dispatch in ``verify_composite.go``), as is the stateful single-use nonce BurnSet. The SDK is an OFFLINE structural + cryptographic verifier; it carries each leaf body opaquely and never asserts the leaf's semantic verdict. A caller that needs the leaf re-decision must submit the composite to the AP00016 verifier-svc.
This module imports ONLY from ``osyra_ome.verify._kernel`` (BC-13 isolation; enforced by ``scripts/verify-no-kernel-imports.py`` + the runtime BC-14 finder). It reuses the existing ed25519 + canonical-CBOR mini-kernel — no new CBOR dependency.
Functions
verify_ocv_composite
def verify_ocv_composite(receipt_bytes: bytes, *, expected_signer_pub: bytes, leaf_signer_pubs: Sequence[bytes] | None = None) -> boolVerify an OCV-1.0 composite receipt locally (offline, structural + crypto).
Proves the composite is a **well-formed, single-(outer)-signed, tenant-uniform, depth-1, correctly-bound chain** (see the module docstring's HONEST SCOPE for the boundary). It does NOT re-decide the per-kind leaf semantics or burn nonces — those are the L5 Verifier-of-Record's job (AP00016 ``verify_composite.go``).
Args:
receipt_bytes: Canonical-CBOR bytes of the OUTER EAT COSE_Sign1
envelope (the composite receipt).
expected_signer_pub: The 32-byte Ed25519 public key the caller trusts
as the composite verifier-of-record (the OUTER envelope signer).
REQUIRED — the SDK fails CLOSED with no implicit trust.
leaf_signer_pubs: The rotation-tolerant candidate key set the leaves'
COSE_Sign1 signatures are verified against (the first that verifies
each leaf wins). V1 composites are tenant-uniform, so the leaves
typically share the outer workspace anchor. Defaults to
[expected_signer_pub] when omitted (the V1 single-anchor case).
Returns:
True on successful verification.
Raises: OmeWireFormatError: the bytes are not well-formed strict-canonical CBOR, the envelope/claim/ocv-body shape is wrong, or a tree / binding-spec is malformed. OmeVerifyError: the outer or a leaf COSE signature does not verify, a tenant/depth/alg invariant is violated, or a committed-digest binding does not hold (anti-splice).