@adastracomputing/ink 0.1.0-alpha.2 → 0.1.0-alpha.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +56 -5
- package/CODE_OF_CONDUCT.md +1 -1
- package/README.md +7 -5
- package/SECURITY.md +1 -1
- package/bin/verify-inclusion-impl.mjs +4 -1
- package/dist/audit/inclusion-receipt.d.ts +142 -0
- package/dist/audit/inclusion-receipt.js +496 -0
- package/dist/crypto/ink.d.ts +178 -0
- package/dist/crypto/ink.js +915 -0
- package/dist/crypto/keys.d.ts +42 -0
- package/dist/crypto/keys.js +179 -0
- package/dist/crypto/multi-key-verify.d.ts +29 -0
- package/dist/crypto/multi-key-verify.js +153 -0
- package/dist/crypto/sign.d.ts +17 -0
- package/dist/crypto/sign.js +152 -0
- package/dist/crypto/verify.js +1 -0
- package/dist/discovery/agent-card.d.ts +83 -0
- package/dist/discovery/agent-card.js +545 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +15 -0
- package/dist/ink/checkpoint.d.ts +19 -0
- package/dist/ink/checkpoint.js +69 -0
- package/dist/ink/discovery-gating.d.ts +237 -0
- package/dist/ink/discovery-gating.js +91 -0
- package/dist/ink/handshake-budget.d.ts +90 -0
- package/dist/ink/handshake-budget.js +397 -0
- package/dist/ink/receipts.d.ts +31 -0
- package/dist/ink/receipts.js +89 -0
- package/dist/ink/transport-auth.d.ts +47 -0
- package/dist/ink/transport-auth.js +77 -0
- package/dist/middleware/ink-auth.d.ts +68 -0
- package/dist/middleware/ink-auth.js +214 -0
- package/dist/models/agent-card.d.ts +154 -0
- package/dist/models/agent-card.js +59 -0
- package/dist/models/ink-audit.d.ts +344 -0
- package/dist/models/ink-audit.js +167 -0
- package/dist/models/ink-handshake.d.ts +129 -0
- package/dist/models/ink-handshake.js +89 -0
- package/dist/models/intent.d.ts +437 -0
- package/dist/models/intent.js +172 -0
- package/dist/models/key-entry.d.ts +60 -0
- package/dist/models/key-entry.js +13 -0
- package/dist/models/profile.d.ts +61 -0
- package/dist/models/profile.js +24 -0
- package/docs/maturity.md +3 -3
- package/docs/threat-model.md +1 -1
- package/package.json +17 -13
- package/specs/ink-auditability.md +37 -12
- package/specs/ink-compliance-checklist.md +9 -1
- package/src/audit/inclusion-receipt.ts +0 -268
- package/src/crypto/ink.ts +0 -902
- package/src/crypto/keys.ts +0 -210
- package/src/crypto/multi-key-verify.ts +0 -170
- package/src/crypto/sign.ts +0 -155
- package/src/discovery/agent-card.ts +0 -508
- package/src/index.ts +0 -67
- package/src/ink/checkpoint.ts +0 -75
- package/src/ink/discovery-gating.ts +0 -147
- package/src/ink/handshake-budget.ts +0 -413
- package/src/ink/receipts.ts +0 -114
- package/src/ink/transport-auth.ts +0 -96
- package/src/middleware/ink-auth.ts +0 -263
- package/src/models/agent-card.ts +0 -63
- package/src/models/ink-audit.ts +0 -205
- package/src/models/ink-handshake.ts +0 -123
- package/src/models/intent.ts +0 -201
- package/src/models/key-entry.ts +0 -52
- package/src/models/profile.ts +0 -31
- /package/{src/crypto/verify.ts → dist/crypto/verify.d.ts} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
All notable changes to INK
|
|
3
|
+
All notable changes to INK are recorded
|
|
4
4
|
here. Pre-1.0 releases follow `0.Y.Z` semantics, see
|
|
5
5
|
[`docs/maturity.md`](docs/maturity.md) for the versioning policy.
|
|
6
6
|
|
|
@@ -8,6 +8,58 @@ here. Pre-1.0 releases follow `0.Y.Z` semantics, see
|
|
|
8
8
|
|
|
9
9
|
No unreleased changes.
|
|
10
10
|
|
|
11
|
+
## 0.1.0-alpha.5, ship compiled JS
|
|
12
|
+
|
|
13
|
+
Fixes a publish-time regression in `0.1.0-alpha.3` (and the unreleased
|
|
14
|
+
`alpha.4`) where the package shipped raw TypeScript under `main` and
|
|
15
|
+
`exports`. Node 24 refuses to strip types from anything under
|
|
16
|
+
`node_modules`, so any consumer following the quickstart hit
|
|
17
|
+
`ERR_UNSUPPORTED_NODE_MODULES_TYPE_STRIPPING` on the first `import`
|
|
18
|
+
and could not use the library at all.
|
|
19
|
+
|
|
20
|
+
### Changed
|
|
21
|
+
|
|
22
|
+
- `npm run build` compiles `src/` to `dist/` via `tsconfig.build.json`;
|
|
23
|
+
`prepublishOnly` runs it automatically so the npm tarball always
|
|
24
|
+
contains compiled JS plus declaration maps.
|
|
25
|
+
- `main`, `types` and `exports."."` now point at `./dist/index.js` and
|
|
26
|
+
`./dist/index.d.ts`. The `files` array ships `dist/` instead of
|
|
27
|
+
`src/`, so consumers no longer see raw TS in `node_modules`.
|
|
28
|
+
- Dev shell and `engines.node` move from Node 22 to Node 24 (the
|
|
29
|
+
current Active LTS) to match CI.
|
|
30
|
+
|
|
31
|
+
End-to-end verified against `witness-demo.tulpa.network`: the
|
|
32
|
+
quickstart `submit.mjs` now returns a signed inclusion receipt on
|
|
33
|
+
Node 24 without modification.
|
|
34
|
+
|
|
35
|
+
## 0.1.0-alpha.3, signed audit-query response
|
|
36
|
+
|
|
37
|
+
Closes the last HIGH conformance-audit finding (witness audit-query
|
|
38
|
+
response missing signature, proofs and protocol envelope).
|
|
39
|
+
|
|
40
|
+
### Added
|
|
41
|
+
|
|
42
|
+
- `signAuditQueryResponse(payload, privateKey)` and `verifyAuditQueryResponseSignature(payload, signature, publicKey)` primitives. Canonical signed bytes are `ink/audit-query-response/v1\n` + JCS(payload without serviceSignature). The payload binds `serviceDid`, `messageId`, `requester`, `events`, `proofs`, `treeSize`, `rootHash`, `timestamp`, so a valid signature cannot be rebound to a different witness, message, requester, or root.
|
|
43
|
+
- `verifyAuditQueryResponse({response, witnessPublicKey, expectedRequester, expectedMessageId, verifyEventSignature, expectedServiceDid?, laterCheckpoint?})` is the recommended high-level verifier. `verifyEventSignature` is a REQUIRED callback that resolves the submitting agent's keys and validates each event's `agentSignature`. 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 via `computeAuditMerkleLeafHash` up to the response's `rootHash`, runs `verifyEventSignature` on every event and supports optional later-checkpoint cross-check. `verifyAuditQueryResponseSignature` alone is signature-only and is documented as a low-level primitive.
|
|
44
|
+
- `computeAuditMerkleLeafHash(event)` primitive: the RFC 6962 leaf-hash rule for inclusion proofs, `SHA-256(0x00 || JCS(event-without-agentSignature))`. Distinct from `computeEventHash` (unprefixed, used only for `previousEventHash` chain linkage). Verifiers walking an inclusion proof MUST use this function, not `computeEventHash`.
|
|
45
|
+
- Nix flake now exposes `apps.default`, so `nix run github:Ad-Astra-Computing/ink -- verify-inclusion --file r.json --witness URL` works without `npm install`.
|
|
46
|
+
|
|
47
|
+
### Security
|
|
48
|
+
|
|
49
|
+
- 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 same `messageId`. Verifiers MUST check the response's `requester` equals their locally authenticated requester before accepting events as a complete view.
|
|
50
|
+
- Witnesses MUST fail closed when the requester's visible event set for a `messageId` exceeds the response cap, returning an unsigned HTTP 413 rather than silently signing a partial response. The reference and OSS witnesses query `LIMIT MAX_QUERY_EVENTS + 1`, detect overflow and refuse to sign.
|
|
51
|
+
- 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`.
|
|
52
|
+
- 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.
|
|
53
|
+
- 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` / `verifyAuditQueryResponseSignature` and the witness `handleQuery` response-size guard.
|
|
54
|
+
- `verifyAuditEventSignature`, `verifyAuditResponseSignature`, `verifyAuditQueryResponseSignature` now wrap canonicalization inside the try/catch, so payloads that pass the complexity precheck but throw inside `jcsCanonicalize` (e.g. objects with `undefined` values) return `false` instead of propagating.
|
|
55
|
+
|
|
56
|
+
### Spec
|
|
57
|
+
|
|
58
|
+
- `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.
|
|
59
|
+
- §7.3 leaf-hash text now references `computeAuditMerkleLeafHash` directly and warns implementers that `computeEventHash` (chain linkage) is NOT the leaf input.
|
|
60
|
+
- §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)`.
|
|
61
|
+
- §7.3 requires witnesses to emit `events` and `proofs` in a stable, deterministic order.
|
|
62
|
+
|
|
11
63
|
## 0.1.0-alpha.2, inclusion-receipt verifier
|
|
12
64
|
|
|
13
65
|
Adds a public verification path for INK Auditability Section 7
|
|
@@ -21,7 +73,7 @@ trusting any specific operator's UI.
|
|
|
21
73
|
|
|
22
74
|
## 0.1.0-alpha.1, spec clarification
|
|
23
75
|
|
|
24
|
-
Spec-only release.
|
|
76
|
+
Spec-only release. Library code in `src/` is
|
|
25
77
|
unchanged from `0.1.0-alpha.0`; the bundled spec text is updated.
|
|
26
78
|
|
|
27
79
|
### Spec changes
|
|
@@ -37,8 +89,7 @@ unchanged from `0.1.0-alpha.0`; the bundled spec text is updated.
|
|
|
37
89
|
|
|
38
90
|
## 0.1.0-alpha.0, first public alpha
|
|
39
91
|
|
|
40
|
-
Initial open-source release of the INK protocol
|
|
41
|
-
and accompanying specification.
|
|
92
|
+
Initial open-source release of the INK protocol library and specification.
|
|
42
93
|
|
|
43
94
|
### Protocol surface
|
|
44
95
|
|
|
@@ -53,7 +104,7 @@ and accompanying specification.
|
|
|
53
104
|
- Optional containment extension: capability-gated visibility, handshake
|
|
54
105
|
budgets, sender silent-drop after first rate-limit violation.
|
|
55
106
|
|
|
56
|
-
###
|
|
107
|
+
### Library
|
|
57
108
|
|
|
58
109
|
- Public API exported from the package root, see README for the export
|
|
59
110
|
surface.
|
package/CODE_OF_CONDUCT.md
CHANGED
|
@@ -11,7 +11,7 @@ Participate in this project as a professional. That means:
|
|
|
11
11
|
- Assume good faith from contributors and maintainers. If you believe
|
|
12
12
|
someone has acted in bad faith, raise it privately first.
|
|
13
13
|
- Keep public discussions focused on the protocol, the spec, the
|
|
14
|
-
|
|
14
|
+
library, or related interoperability work.
|
|
15
15
|
|
|
16
16
|
## Scope
|
|
17
17
|
|
package/README.md
CHANGED
|
@@ -65,7 +65,9 @@ const ok = await verifyInkSignature(input, signature, keypair.publicKey);
|
|
|
65
65
|
|
|
66
66
|
For inbound request verification, `verifyInkAuth` parses the `Authorization: INK-Ed25519 <sig>` header, checks freshness, and applies the key-rotation authority rule. It requires a `nonceStore` option so the 5-minute freshness window does not silently accept replays; pass a `NonceStore` to have the middleware enforce single-use, or `"deferred"` to acknowledge that the caller will run `checkReplay` (or equivalent) elsewhere in the request pipeline.
|
|
67
67
|
|
|
68
|
-
For consumers of audit-exchange responses, call both `verifyAuditResponseSignature` (signed response wrapper) and `verifyAuditEventChain` (sequence-by-one and `previousEventHash` continuity, fork detection). The signature gate alone does not prevent a
|
|
68
|
+
For consumers of bilateral audit-exchange responses (`network.tulpa.audit_response`), call both `verifyAuditResponseSignature` (signed response wrapper) and `verifyAuditEventChain` (sequence-by-one and `previousEventHash` continuity, fork detection). The signature gate alone does not prevent a peer from returning a gapped or forked slice.
|
|
69
|
+
|
|
70
|
+
For consumers of witness audit-query responses (`network.tulpa.audit_query_response`, Auditability §7.3, added in `0.1.0-alpha.3`), call `verifyAuditQueryResponse({response, witnessPublicKey, expectedRequester, expectedMessageId, verifyEventSignature, expectedServiceDid?, laterCheckpoint?})`. The `verifyEventSignature` callback is REQUIRED: it resolves the submitting agent's Ed25519 keys (typically via Agent Card §2) and validates each event's `agentSignature`. Without it, the verifier refuses to return valid, because Merkle inclusion alone does not prove a real agent produced the event (§7.5). The verifier enforces envelope shape, the `requester` binding (prevents cross-requester replay), events/proofs strict one-to-one alignment, the §7.4 per-event scope rule, walks every Merkle proof via `computeAuditMerkleLeafHash` up to the response's `rootHash`, runs `verifyEventSignature` on every event and supports an optional later-checkpoint cross-check. The lower-level `verifyAuditQueryResponseSignature` is signature-only and is not sufficient to accept a witness response on its own.
|
|
69
71
|
|
|
70
72
|
## Tests
|
|
71
73
|
|
|
@@ -76,12 +78,12 @@ npm run lint # eslint
|
|
|
76
78
|
npm run check:surface # public-surface drift check
|
|
77
79
|
```
|
|
78
80
|
|
|
79
|
-
For Nix users: `nix develop` gives a pinned Node 22 + git + gitleaks shell. `nix build` produces the publishable npm tarball under `result/`.
|
|
81
|
+
For Nix users: `nix develop` gives a pinned Node 22 + git + gitleaks shell. `nix build` produces the publishable npm tarball under `result/`. `nix run github:Ad-Astra-Computing/ink -- verify-inclusion --file receipt.json --witness https://witness.example.com` runs the CLI without installing anything globally.
|
|
80
82
|
|
|
81
83
|
## Layout
|
|
82
84
|
|
|
83
85
|
```
|
|
84
|
-
src/
|
|
86
|
+
src/ library implementation
|
|
85
87
|
crypto/ signing, multi-key verification, key encoding
|
|
86
88
|
models/ Zod schemas for Agent Card, handshake, key entries
|
|
87
89
|
middleware/ transport-level INK auth (verifyInkAuth)
|
|
@@ -93,7 +95,7 @@ test-vectors/ JSON interop vectors
|
|
|
93
95
|
test/ vitest unit + integration tests
|
|
94
96
|
```
|
|
95
97
|
|
|
96
|
-
The
|
|
98
|
+
The library runs on any runtime providing standard Web Crypto and `fetch`: Node 22+, Deno, Bun, Cloudflare Workers, browsers. The timestamp freshness window is enforced inside `verifyInkAuth`; nonce single-use is enforced when a `NonceStore` is passed (otherwise `checkReplay` must be called separately). Nonce backing storage and its TTL policy are the integrator's choice.
|
|
97
99
|
|
|
98
100
|
## What's stable in v0.1
|
|
99
101
|
|
|
@@ -117,7 +119,7 @@ You will see `network.tulpa.*` on the wire (e.g. `network.tulpa.intent`) and `in
|
|
|
117
119
|
|
|
118
120
|
## Relationship to Tulpa
|
|
119
121
|
|
|
120
|
-
INK is developed by [Ad Astra Computing](https://adastracomputing.com) as the underlying protocol for [Tulpa](https://tulpa.network). The spec and the
|
|
122
|
+
INK is developed by [Ad Astra Computing](https://adastracomputing.com) as the underlying protocol for [Tulpa](https://tulpa.network). The spec and the library in this repo are deliberately free of Tulpa product code so other agent platforms can adopt INK without inheriting Tulpa's surface area. Tulpa's product integration (message orchestration, marketplace, user-facing APIs) lives in a separate, closed-source codebase.
|
|
121
123
|
|
|
122
124
|
## Security
|
|
123
125
|
|
package/SECURITY.md
CHANGED
|
@@ -39,7 +39,7 @@ In scope:
|
|
|
39
39
|
|
|
40
40
|
Out of scope:
|
|
41
41
|
|
|
42
|
-
- DoS via high-entropy inputs against the
|
|
42
|
+
- DoS via high-entropy inputs against the library
|
|
43
43
|
- Attacks that require a compromised identity system (e.g., a malicious PDS returning a fabricated DID document)
|
|
44
44
|
- Timing side-channels in the reference `@noble/ed25519` verification
|
|
45
45
|
- Attacks on Tulpa's product infrastructure (separate codebase, separate disclosure process)
|
|
@@ -76,7 +76,10 @@ Usage:
|
|
|
76
76
|
Options:
|
|
77
77
|
-w, --witness <url> Witness base URL (e.g. https://witness.tulpa.network)
|
|
78
78
|
-f, --file <path> Receipt JSON file. Omit to read from stdin.
|
|
79
|
-
-e, --event-hash <hex> Optional.
|
|
79
|
+
-e, --event-hash <hex> Optional. RFC 6962 leaf hash for the audit event:
|
|
80
|
+
SHA-256(0x00 || JCS(event-without-agentSignature)),
|
|
81
|
+
hex-encoded. When set, the inclusion proof is
|
|
82
|
+
re-walked from this leaf up to the claimed root.
|
|
80
83
|
-h, --help Show this help.
|
|
81
84
|
|
|
82
85
|
Exit codes:
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
export interface InclusionReceipt {
|
|
2
|
+
eventId: string;
|
|
3
|
+
leafIndex: number;
|
|
4
|
+
treeSize: number;
|
|
5
|
+
rootHash: string;
|
|
6
|
+
inclusionProof: string[];
|
|
7
|
+
/** ISO 8601 timestamp at which the witness committed the leaf. */
|
|
8
|
+
timestamp: string;
|
|
9
|
+
/** Base64url Ed25519 signature over the canonical bytes. */
|
|
10
|
+
serviceSignature: string;
|
|
11
|
+
}
|
|
12
|
+
export interface VerifyStep {
|
|
13
|
+
name: string;
|
|
14
|
+
pass: boolean;
|
|
15
|
+
detail?: string;
|
|
16
|
+
}
|
|
17
|
+
export interface InclusionReceiptVerifyResult {
|
|
18
|
+
valid: boolean;
|
|
19
|
+
steps: VerifyStep[];
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Verify an INK inclusion receipt.
|
|
23
|
+
*
|
|
24
|
+
* Always performs:
|
|
25
|
+
* - Structural validation of the receipt object
|
|
26
|
+
* - Service signature verification against `witnessPublicKey`
|
|
27
|
+
*
|
|
28
|
+
* Optionally performs (when the corresponding input is provided):
|
|
29
|
+
* - Leaf-to-root proof walk (`eventHash`)
|
|
30
|
+
* - Cross-check against a later signed checkpoint (`laterCheckpoint`)
|
|
31
|
+
*/
|
|
32
|
+
export declare function verifyInclusionReceipt(opts: {
|
|
33
|
+
receipt: InclusionReceipt;
|
|
34
|
+
/** Raw 32-byte Ed25519 public key of the witness service. */
|
|
35
|
+
witnessPublicKey: Uint8Array;
|
|
36
|
+
/** Optional RFC 6962 leaf hash for the underlying audit event:
|
|
37
|
+
* SHA-256(0x00 || JCS(event-without-agentSignature)), hex-encoded.
|
|
38
|
+
* Use `computeAuditMerkleLeafHash` to derive it. When provided, the
|
|
39
|
+
* inclusion proof is walked from this leaf up to the claimed rootHash. */
|
|
40
|
+
eventHash?: string;
|
|
41
|
+
/** Optional later checkpoint to cross-check the receipt against.
|
|
42
|
+
* Must come from a `/ink/v1/checkpoint` response that the verifier
|
|
43
|
+
* has separately validated as authentic. */
|
|
44
|
+
laterCheckpoint?: {
|
|
45
|
+
treeSize: number;
|
|
46
|
+
rootHash: string;
|
|
47
|
+
};
|
|
48
|
+
}): Promise<InclusionReceiptVerifyResult>;
|
|
49
|
+
export interface AuditQueryResponse {
|
|
50
|
+
protocol: "ink/0.1";
|
|
51
|
+
type: "network.tulpa.audit_query_response";
|
|
52
|
+
serviceDid: string;
|
|
53
|
+
messageId: string;
|
|
54
|
+
requester: string;
|
|
55
|
+
events: Array<Record<string, unknown> & {
|
|
56
|
+
id: string;
|
|
57
|
+
}>;
|
|
58
|
+
proofs: Array<{
|
|
59
|
+
eventId: string;
|
|
60
|
+
leafIndex: number;
|
|
61
|
+
inclusionProof: string[];
|
|
62
|
+
}>;
|
|
63
|
+
treeSize: number;
|
|
64
|
+
rootHash: string;
|
|
65
|
+
timestamp: string;
|
|
66
|
+
serviceSignature: string;
|
|
67
|
+
}
|
|
68
|
+
export interface AuditQueryResponseVerifyResult {
|
|
69
|
+
valid: boolean;
|
|
70
|
+
steps: VerifyStep[];
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Full §7.3 verification of a witness audit-query response. Use this in
|
|
74
|
+
* preference to `verifyAuditQueryResponseSignature`, which is the
|
|
75
|
+
* underlying primitive and verifies only the Ed25519 signature. This
|
|
76
|
+
* function additionally enforces:
|
|
77
|
+
*
|
|
78
|
+
* - Envelope shape (protocol, type, serviceDid, requester, messageId,
|
|
79
|
+
* timestamp, treeSize, rootHash, events[], proofs[])
|
|
80
|
+
* - Service signature with the right canonical bytes
|
|
81
|
+
* - Optional caller-supplied bindings: expected `messageId`,
|
|
82
|
+
* `requester`, `serviceDid` (each rejected on mismatch)
|
|
83
|
+
* - `events` and `proofs` align one-to-one by `eventId`
|
|
84
|
+
* - Every event includes a non-empty `agentSignature` field
|
|
85
|
+
* - Every proof walks from `computeAuditMerkleLeafHash(event)` up to
|
|
86
|
+
* the response's `rootHash` at `treeSize`
|
|
87
|
+
* - Optional `laterCheckpoint`: tree only grew, no fork at same size
|
|
88
|
+
*
|
|
89
|
+
* **Per-event agent-signature verification (§7.5 trust model).** A
|
|
90
|
+
* Merkle-valid response is necessary but not sufficient: the witness
|
|
91
|
+
* could in principle commit a fabricated "event" not signed by any
|
|
92
|
+
* agent, sign the resulting `(treeSize, rootHash)`, and the Merkle
|
|
93
|
+
* proof walks just fine. To detect this, callers MUST pass a
|
|
94
|
+
* `verifyEventSignature` callback that resolves the agent's published
|
|
95
|
+
* Ed25519 keys (typically via Agent Card §2) and validates
|
|
96
|
+
* `event.agentSignature`. The callback is REQUIRED, not optional: the
|
|
97
|
+
* verifier refuses to return `valid: true` without it, so a caller
|
|
98
|
+
* cannot accidentally accept witness-fabricated events.
|
|
99
|
+
*
|
|
100
|
+
* **Freshness.** A `valid: true` result attests that the response was a
|
|
101
|
+
* complete enumeration of the requester's visible events at the
|
|
102
|
+
* `(treeSize, rootHash)` snapshot the witness signed, NOT that it is
|
|
103
|
+
* the witness's current authoritative view. The signed envelope binds
|
|
104
|
+
* `timestamp`, but verifiers wanting "is this still current?"
|
|
105
|
+
* semantics MUST additionally fetch a fresh witness checkpoint and
|
|
106
|
+
* compare it (e.g. require `laterCheckpoint.treeSize === response.treeSize
|
|
107
|
+
* && laterCheckpoint.rootHash === response.rootHash` for "current", or
|
|
108
|
+
* use `laterCheckpoint` here only to prove the tree never rewound or
|
|
109
|
+
* forked).
|
|
110
|
+
*
|
|
111
|
+
* Returns `{valid, steps}` where each step explains pass/fail with detail.
|
|
112
|
+
* Pure function. Does not perform network I/O.
|
|
113
|
+
*/
|
|
114
|
+
export declare function verifyAuditQueryResponse(opts: {
|
|
115
|
+
response: AuditQueryResponse;
|
|
116
|
+
/** Raw 32-byte Ed25519 public key of the witness service. */
|
|
117
|
+
witnessPublicKey: Uint8Array;
|
|
118
|
+
/** Locally authenticated requester DID. Verifier MUST supply this so
|
|
119
|
+
* a response signed for Alice cannot be replayed to Bob. */
|
|
120
|
+
expectedRequester: string;
|
|
121
|
+
/** The `messageId` the verifier asked about. Bound for paranoia: the
|
|
122
|
+
* signed envelope already commits to messageId, so this catches
|
|
123
|
+
* client-side routing bugs before they become trust bugs. */
|
|
124
|
+
expectedMessageId: string;
|
|
125
|
+
/** Optional: witness DID the verifier expects (pinned out of band). */
|
|
126
|
+
expectedServiceDid?: string;
|
|
127
|
+
/** Optional later checkpoint to cross-check against. Same semantics
|
|
128
|
+
* as `verifyInclusionReceipt`. */
|
|
129
|
+
laterCheckpoint?: {
|
|
130
|
+
treeSize: number;
|
|
131
|
+
rootHash: string;
|
|
132
|
+
};
|
|
133
|
+
/** Per-event agent-signature verifier (REQUIRED by Auditability §7.5).
|
|
134
|
+
* The caller resolves the event's submitting agent's public key set
|
|
135
|
+
* (typically from the Agent Card) and returns true if
|
|
136
|
+
* `event.agentSignature` verifies. The verifier refuses to return
|
|
137
|
+
* `valid: true` without this: Merkle inclusion alone does not prove
|
|
138
|
+
* the agent produced the event. If a caller genuinely wants to
|
|
139
|
+
* bypass per-event signature checks (e.g. during a pure Merkle
|
|
140
|
+
* audit), they MUST explicitly pass a callback that does so. */
|
|
141
|
+
verifyEventSignature: (event: Record<string, unknown>) => Promise<boolean>;
|
|
142
|
+
}): Promise<AuditQueryResponseVerifyResult>;
|