v0.1.0-alpha.3
Pre-release
Pre-release
·
113 commits
to main
since this release
Closes the last HIGH conformance-audit finding (witness audit-query
response missing signature, proofs and protocol envelope).
Added
signAuditQueryResponse(payload, privateKey)andverifyAuditQueryResponseSignature(payload, signature, publicKey)primitives. Canonical signed bytes areink/audit-query-response/v1\n+ JCS(payload without serviceSignature). The payload bindsserviceDid,messageId,requester,events,proofs,treeSize,rootHash,timestamp, so a valid signature cannot be rebound to a different witness, message, requester, or root.verifyAuditQueryResponse({response, witnessPublicKey, expectedRequester, expectedMessageId, verifyEventSignature, expectedServiceDid?, laterCheckpoint?})is the recommended high-level verifier.verifyEventSignatureis a REQUIRED callback that resolves the submitting agent's keys and validates each event'sagentSignature. Without it, the verifier refuses to return valid, because Merkle inclusion alone does not prove agent provenance (§7.5). The function enforces envelope shape, requester binding, events/proofs strict one-to-one alignment, the §7.4 per-event scope rule, walks every Merkle proof viacomputeAuditMerkleLeafHashup to the response'srootHash, runsverifyEventSignatureon every event and supports optional later-checkpoint cross-check.verifyAuditQueryResponseSignaturealone is signature-only and is documented as a low-level primitive.computeAuditMerkleLeafHash(event)primitive: the RFC 6962 leaf-hash rule for inclusion proofs,SHA-256(0x00 || JCS(event-without-agentSignature)). Distinct fromcomputeEventHash(unprefixed, used only forpreviousEventHashchain linkage). Verifiers walking an inclusion proof MUST use this function, notcomputeEventHash.- Nix flake now exposes
apps.default, sonix run github:Ad-Astra-Computing/ink -- verify-inclusion --file r.json --witness URLworks withoutnpm install.
Security
- The §7.3 envelope now binds
requester. Without this binding, a signed witness response generated for Alice could be replayed to Bob as Bob's authoritative view of the samemessageId. Verifiers MUST check the response'srequesterequals their locally authenticated requester before accepting events as a complete view. - Witnesses MUST fail closed when the requester's visible event set for a
messageIdexceeds the response cap, returning an unsigned HTTP 413 rather than silently signing a partial response. The reference and OSS witnesses queryLIMIT MAX_QUERY_EVENTS + 1, detect overflow and refuse to sign. - Witnesses MUST emit a deterministic, stable result-set order so signed bytes are reproducible. The reference and OSS witnesses use
ORDER BY event_id ASC. - Storage-integrity failures during proof construction (missing event_hash, hash mismatch, missing Merkle node, unprovable leaf, malformed event_json) now return HTTP 500 instead of silently omitting events from a signed response.
- All canonicalize-and-sign / canonicalize-and-verify paths now cap by UTF-8 byte length, not JS string length. With non-ASCII event data the prior cap could be undercounted and let oversized payloads through. Affects
buildSignatureBase,computeMessageHash,signAuditEvent/verifyAuditEventSignature,computeEventHash,signAuditResponse/verifyAuditResponseSignature,signAuditQueryResponse/verifyAuditQueryResponseSignatureand the witnesshandleQueryresponse-size guard. verifyAuditEventSignature,verifyAuditResponseSignature,verifyAuditQueryResponseSignaturenow wrap canonicalization inside the try/catch, so payloads that pass the complexity precheck but throw insidejcsCanonicalize(e.g. objects withundefinedvalues) returnfalseinstead of propagating.
Spec
specs/ink-auditability.md§7.3 (audit-query response) now defines the full signed-envelope shape:{protocol, type: "network.tulpa.audit_query_response", serviceDid, messageId, requester, events, proofs[{eventId, leafIndex, inclusionProof}], treeSize, rootHash, timestamp, serviceSignature}. Previous text described a bare{events}shape with no signature, no protocol envelope and no per-event proofs.- §7.3 leaf-hash text now references
computeAuditMerkleLeafHashdirectly and warns implementers thatcomputeEventHash(chain linkage) is NOT the leaf input. - §7.3 now explicitly forbids witnesses from signing partial results: truncation MUST be an unsigned error. A signed response is a complete enumeration of the requester's visible events at
(treeSize, rootHash). - §7.3 requires witnesses to emit
eventsandproofsin a stable, deterministic order.