@adastracomputing/ink 0.1.0-alpha.0
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 +63 -0
- package/CODE_OF_CONDUCT.md +42 -0
- package/LICENSE-APACHE +201 -0
- package/LICENSE-MIT +21 -0
- package/README.md +133 -0
- package/SECURITY.md +57 -0
- package/docs/key-rotation-rule.md +108 -0
- package/docs/logo.svg +8 -0
- package/docs/maturity.md +81 -0
- package/docs/threat-model.md +150 -0
- package/package.json +72 -0
- package/specs/ink-agent-containment-and-governance-extension-spec.md +508 -0
- package/specs/ink-auditability.md +652 -0
- package/specs/ink-authorization-chain.md +242 -0
- package/specs/ink-compatibility-policy.md +263 -0
- package/specs/ink-compliance-checklist.md +309 -0
- package/specs/ink-containment-phase1-implementation-spec.md +593 -0
- package/specs/ink-introduction-receipts-extension.md +501 -0
- package/specs/ink-key-rotation-spec.md +535 -0
- package/src/crypto/ink.ts +902 -0
- package/src/crypto/keys.ts +211 -0
- package/src/crypto/multi-key-verify.ts +170 -0
- package/src/crypto/sign.ts +155 -0
- package/src/crypto/verify.ts +1 -0
- package/src/discovery/agent-card.ts +508 -0
- package/src/index.ts +59 -0
- package/src/ink/checkpoint.ts +75 -0
- package/src/ink/discovery-gating.ts +147 -0
- package/src/ink/handshake-budget.ts +413 -0
- package/src/ink/receipts.ts +114 -0
- package/src/ink/transport-auth.ts +96 -0
- package/src/middleware/ink-auth.ts +263 -0
- package/src/models/agent-card.ts +63 -0
- package/src/models/ink-audit.ts +205 -0
- package/src/models/ink-handshake.ts +123 -0
- package/src/models/intent.ts +201 -0
- package/src/models/key-entry.ts +52 -0
- package/src/models/profile.ts +31 -0
- package/test-vectors/README.md +129 -0
- package/test-vectors/encryption.json +90 -0
- package/test-vectors/handshake.json +482 -0
- package/test-vectors/jcs.json +30 -0
- package/test-vectors/key-rotation.json +101 -0
- package/test-vectors/keys.json +32 -0
- package/test-vectors/receipts-and-audit.json +142 -0
- package/test-vectors/replay.json +88 -0
- package/test-vectors/signing.json +61 -0
- package/test-vectors/witness.json +394 -0
|
@@ -0,0 +1,394 @@
|
|
|
1
|
+
{
|
|
2
|
+
"description": "INK v0.1 witness test vectors — audit submit and query with INK transport auth, plus interop cases. All signatures use key material from keys.json.",
|
|
3
|
+
"vectors": [
|
|
4
|
+
{
|
|
5
|
+
"id": "audit-submit-valid",
|
|
6
|
+
"description": "Alice submits a signed audit event to the witness",
|
|
7
|
+
"input": {
|
|
8
|
+
"method": "POST",
|
|
9
|
+
"path": "/ink/v1/audit/submit",
|
|
10
|
+
"recipientDid": "did:web:witness.tulpa.network",
|
|
11
|
+
"body": {
|
|
12
|
+
"protocol": "ink/0.1",
|
|
13
|
+
"type": "network.tulpa.audit_submit",
|
|
14
|
+
"from": "did:plc:alice123test",
|
|
15
|
+
"to": "did:web:witness.tulpa.network",
|
|
16
|
+
"event": {
|
|
17
|
+
"id": "01JWIT0001",
|
|
18
|
+
"version": "ink-audit/1",
|
|
19
|
+
"agentId": "agent-alice-01",
|
|
20
|
+
"sequence": 1,
|
|
21
|
+
"previousEventHash": null,
|
|
22
|
+
"eventType": "message.sent",
|
|
23
|
+
"timestamp": "2026-03-25T12:00:00Z",
|
|
24
|
+
"messageId": "msg-witness-001",
|
|
25
|
+
"counterpartyId": "did:plc:bob456test",
|
|
26
|
+
"agentSignature": "9Z3iO9pQoTdn3JBu__nEqH7MC7XrqPlWS4xnyANaMoe0tVz6tp5yPMSxFWbpBN1rF2QfRELGhh37dzCXXC8vCg"
|
|
27
|
+
},
|
|
28
|
+
"nonce": "d2l0c3VibWl0MQ",
|
|
29
|
+
"timestamp": "2026-03-25T12:00:01Z"
|
|
30
|
+
},
|
|
31
|
+
"timestamp": "2026-03-25T12:00:01Z",
|
|
32
|
+
"signerPrivateKeyHex": "02362f546f26d9c252c9209d1218e3174654b04b5f08f2ee2b3fa7874111d086",
|
|
33
|
+
"eventSignatureBase64url": "9Z3iO9pQoTdn3JBu__nEqH7MC7XrqPlWS4xnyANaMoe0tVz6tp5yPMSxFWbpBN1rF2QfRELGhh37dzCXXC8vCg"
|
|
34
|
+
},
|
|
35
|
+
"expected": {
|
|
36
|
+
"canonicalBody": "{\"event\":{\"agentId\":\"agent-alice-01\",\"agentSignature\":\"9Z3iO9pQoTdn3JBu__nEqH7MC7XrqPlWS4xnyANaMoe0tVz6tp5yPMSxFWbpBN1rF2QfRELGhh37dzCXXC8vCg\",\"counterpartyId\":\"did:plc:bob456test\",\"eventType\":\"message.sent\",\"id\":\"01JWIT0001\",\"messageId\":\"msg-witness-001\",\"previousEventHash\":null,\"sequence\":1,\"timestamp\":\"2026-03-25T12:00:00Z\",\"version\":\"ink-audit/1\"},\"from\":\"did:plc:alice123test\",\"nonce\":\"d2l0c3VibWl0MQ\",\"protocol\":\"ink/0.1\",\"timestamp\":\"2026-03-25T12:00:01Z\",\"to\":\"did:web:witness.tulpa.network\",\"type\":\"network.tulpa.audit_submit\"}",
|
|
37
|
+
"signatureBase": "ink/0.1\nPOST\n/ink/v1/audit/submit\ndid:web:witness.tulpa.network\n{\"event\":{\"agentId\":\"agent-alice-01\",\"agentSignature\":\"9Z3iO9pQoTdn3JBu__nEqH7MC7XrqPlWS4xnyANaMoe0tVz6tp5yPMSxFWbpBN1rF2QfRELGhh37dzCXXC8vCg\",\"counterpartyId\":\"did:plc:bob456test\",\"eventType\":\"message.sent\",\"id\":\"01JWIT0001\",\"messageId\":\"msg-witness-001\",\"previousEventHash\":null,\"sequence\":1,\"timestamp\":\"2026-03-25T12:00:00Z\",\"version\":\"ink-audit/1\"},\"from\":\"did:plc:alice123test\",\"nonce\":\"d2l0c3VibWl0MQ\",\"protocol\":\"ink/0.1\",\"timestamp\":\"2026-03-25T12:00:01Z\",\"to\":\"did:web:witness.tulpa.network\",\"type\":\"network.tulpa.audit_submit\"}\n2026-03-25T12:00:01Z",
|
|
38
|
+
"signatureBase64url": "7VN7IJvoezRDTC_oJGu5fc8Xz2l0cgOYkmgRf3TcASp_6F62SjILXcSeSfljVWznLEReyTvNBOk4c-JTw6fZDQ",
|
|
39
|
+
"accepted": true
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"id": "audit-submit-invalid-path",
|
|
44
|
+
"description": "Submit signature fails when verified against /audit/query path",
|
|
45
|
+
"input": {
|
|
46
|
+
"method": "POST",
|
|
47
|
+
"path": "/ink/v1/audit/query",
|
|
48
|
+
"recipientDid": "did:web:witness.tulpa.network",
|
|
49
|
+
"body": {
|
|
50
|
+
"protocol": "ink/0.1",
|
|
51
|
+
"type": "network.tulpa.audit_submit",
|
|
52
|
+
"from": "did:plc:alice123test",
|
|
53
|
+
"to": "did:web:witness.tulpa.network",
|
|
54
|
+
"event": {
|
|
55
|
+
"id": "01JWIT0001",
|
|
56
|
+
"version": "ink-audit/1",
|
|
57
|
+
"agentId": "agent-alice-01",
|
|
58
|
+
"sequence": 1,
|
|
59
|
+
"previousEventHash": null,
|
|
60
|
+
"eventType": "message.sent",
|
|
61
|
+
"timestamp": "2026-03-25T12:00:00Z",
|
|
62
|
+
"messageId": "msg-witness-001",
|
|
63
|
+
"counterpartyId": "did:plc:bob456test",
|
|
64
|
+
"agentSignature": "9Z3iO9pQoTdn3JBu__nEqH7MC7XrqPlWS4xnyANaMoe0tVz6tp5yPMSxFWbpBN1rF2QfRELGhh37dzCXXC8vCg"
|
|
65
|
+
},
|
|
66
|
+
"nonce": "d2l0c3VibWl0MQ",
|
|
67
|
+
"timestamp": "2026-03-25T12:00:01Z"
|
|
68
|
+
},
|
|
69
|
+
"timestamp": "2026-03-25T12:00:01Z",
|
|
70
|
+
"originalSignatureBase64url": "7VN7IJvoezRDTC_oJGu5fc8Xz2l0cgOYkmgRf3TcASp_6F62SjILXcSeSfljVWznLEReyTvNBOk4c-JTw6fZDQ"
|
|
71
|
+
},
|
|
72
|
+
"expected": {
|
|
73
|
+
"accepted": false,
|
|
74
|
+
"reason": "Signature was computed over /audit/submit but verified against /audit/query"
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
"id": "audit-submit-invalid-recipient",
|
|
79
|
+
"description": "Submit signature fails when verified with wrong recipient DID",
|
|
80
|
+
"input": {
|
|
81
|
+
"method": "POST",
|
|
82
|
+
"path": "/ink/v1/audit/submit",
|
|
83
|
+
"recipientDid": "did:web:evil-witness.example.com",
|
|
84
|
+
"body": {
|
|
85
|
+
"protocol": "ink/0.1",
|
|
86
|
+
"type": "network.tulpa.audit_submit",
|
|
87
|
+
"from": "did:plc:alice123test",
|
|
88
|
+
"to": "did:web:witness.tulpa.network",
|
|
89
|
+
"event": {
|
|
90
|
+
"id": "01JWIT0001",
|
|
91
|
+
"version": "ink-audit/1",
|
|
92
|
+
"agentId": "agent-alice-01",
|
|
93
|
+
"sequence": 1,
|
|
94
|
+
"previousEventHash": null,
|
|
95
|
+
"eventType": "message.sent",
|
|
96
|
+
"timestamp": "2026-03-25T12:00:00Z",
|
|
97
|
+
"messageId": "msg-witness-001",
|
|
98
|
+
"counterpartyId": "did:plc:bob456test",
|
|
99
|
+
"agentSignature": "9Z3iO9pQoTdn3JBu__nEqH7MC7XrqPlWS4xnyANaMoe0tVz6tp5yPMSxFWbpBN1rF2QfRELGhh37dzCXXC8vCg"
|
|
100
|
+
},
|
|
101
|
+
"nonce": "d2l0c3VibWl0MQ",
|
|
102
|
+
"timestamp": "2026-03-25T12:00:01Z"
|
|
103
|
+
},
|
|
104
|
+
"timestamp": "2026-03-25T12:00:01Z",
|
|
105
|
+
"originalSignatureBase64url": "7VN7IJvoezRDTC_oJGu5fc8Xz2l0cgOYkmgRf3TcASp_6F62SjILXcSeSfljVWznLEReyTvNBOk4c-JTw6fZDQ"
|
|
106
|
+
},
|
|
107
|
+
"expected": {
|
|
108
|
+
"accepted": false,
|
|
109
|
+
"reason": "recipientDid mismatch — prevents routing a submit to a different witness"
|
|
110
|
+
}
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
"id": "audit-submit-timestamp-expired",
|
|
114
|
+
"description": "Submit rejected — timestamp more than 5 minutes in the past",
|
|
115
|
+
"input": {
|
|
116
|
+
"messageTimestamp": "2026-03-25T11:50:00Z",
|
|
117
|
+
"receiverClock": "2026-03-25T12:00:00Z",
|
|
118
|
+
"nonce": "d2l0c3VibWl0MQ"
|
|
119
|
+
},
|
|
120
|
+
"expected": {
|
|
121
|
+
"accepted": false,
|
|
122
|
+
"errorCode": "expired_message"
|
|
123
|
+
}
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
"id": "audit-submit-timestamp-future",
|
|
127
|
+
"description": "Submit rejected — timestamp more than 30 seconds in the future",
|
|
128
|
+
"input": {
|
|
129
|
+
"messageTimestamp": "2026-03-25T12:01:00Z",
|
|
130
|
+
"receiverClock": "2026-03-25T12:00:00Z",
|
|
131
|
+
"nonce": "d2l0ZnV0dXJlMQ"
|
|
132
|
+
},
|
|
133
|
+
"expected": {
|
|
134
|
+
"accepted": false,
|
|
135
|
+
"errorCode": "expired_message"
|
|
136
|
+
}
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
"id": "audit-submit-body-tamper",
|
|
140
|
+
"description": "Submit signature fails when event content is tampered after signing",
|
|
141
|
+
"input": {
|
|
142
|
+
"method": "POST",
|
|
143
|
+
"path": "/ink/v1/audit/submit",
|
|
144
|
+
"recipientDid": "did:web:witness.tulpa.network",
|
|
145
|
+
"body": {
|
|
146
|
+
"protocol": "ink/0.1",
|
|
147
|
+
"type": "network.tulpa.audit_submit",
|
|
148
|
+
"from": "did:plc:alice123test",
|
|
149
|
+
"to": "did:web:witness.tulpa.network",
|
|
150
|
+
"event": {
|
|
151
|
+
"id": "01JWIT0001",
|
|
152
|
+
"version": "ink-audit/1",
|
|
153
|
+
"agentId": "agent-alice-01",
|
|
154
|
+
"sequence": 1,
|
|
155
|
+
"previousEventHash": null,
|
|
156
|
+
"eventType": "message.rejected",
|
|
157
|
+
"timestamp": "2026-03-25T12:00:00Z",
|
|
158
|
+
"messageId": "msg-witness-001",
|
|
159
|
+
"counterpartyId": "did:plc:bob456test",
|
|
160
|
+
"agentSignature": "9Z3iO9pQoTdn3JBu__nEqH7MC7XrqPlWS4xnyANaMoe0tVz6tp5yPMSxFWbpBN1rF2QfRELGhh37dzCXXC8vCg"
|
|
161
|
+
},
|
|
162
|
+
"nonce": "d2l0c3VibWl0MQ",
|
|
163
|
+
"timestamp": "2026-03-25T12:00:01Z"
|
|
164
|
+
},
|
|
165
|
+
"timestamp": "2026-03-25T12:00:01Z",
|
|
166
|
+
"originalSignatureBase64url": "7VN7IJvoezRDTC_oJGu5fc8Xz2l0cgOYkmgRf3TcASp_6F62SjILXcSeSfljVWznLEReyTvNBOk4c-JTw6fZDQ"
|
|
167
|
+
},
|
|
168
|
+
"expected": {
|
|
169
|
+
"accepted": false,
|
|
170
|
+
"reason": "Transport signature fails because body was modified"
|
|
171
|
+
}
|
|
172
|
+
},
|
|
173
|
+
{
|
|
174
|
+
"id": "audit-submit-event-signature-invalid",
|
|
175
|
+
"description": "Transport auth valid but embedded event signature is invalid — witness should reject",
|
|
176
|
+
"input": {
|
|
177
|
+
"method": "POST",
|
|
178
|
+
"path": "/ink/v1/audit/submit",
|
|
179
|
+
"recipientDid": "did:web:witness.tulpa.network",
|
|
180
|
+
"body": {
|
|
181
|
+
"protocol": "ink/0.1",
|
|
182
|
+
"type": "network.tulpa.audit_submit",
|
|
183
|
+
"from": "did:plc:alice123test",
|
|
184
|
+
"to": "did:web:witness.tulpa.network",
|
|
185
|
+
"event": {
|
|
186
|
+
"id": "01JWIT0001",
|
|
187
|
+
"version": "ink-audit/1",
|
|
188
|
+
"agentId": "agent-alice-01",
|
|
189
|
+
"sequence": 1,
|
|
190
|
+
"previousEventHash": null,
|
|
191
|
+
"eventType": "message.sent",
|
|
192
|
+
"timestamp": "2026-03-25T12:00:00Z",
|
|
193
|
+
"messageId": "msg-witness-001",
|
|
194
|
+
"counterpartyId": "did:plc:bob456test",
|
|
195
|
+
"agentSignature": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
|
|
196
|
+
},
|
|
197
|
+
"nonce": "d2l0c3VibWl0MQ",
|
|
198
|
+
"timestamp": "2026-03-25T12:00:01Z"
|
|
199
|
+
},
|
|
200
|
+
"timestamp": "2026-03-25T12:00:01Z",
|
|
201
|
+
"transportSignatureBase64url": "kF25C_Fk8U9S_gW8ZCcRQ-D7Q2HFwwsNfzexBH9fvePZhEOR1u4YHOIBbu_dZ9h3dj3x9NypKYcULd0NoibgBQ",
|
|
202
|
+
"note": "Transport signature is valid over the body (which contains a forged event signature). The witness must verify the inner event signature separately."
|
|
203
|
+
},
|
|
204
|
+
"expected": {
|
|
205
|
+
"transportAuthValid": true,
|
|
206
|
+
"eventSignatureValid": false,
|
|
207
|
+
"accepted": false,
|
|
208
|
+
"reason": "Inner event agentSignature does not verify against the agent's public key"
|
|
209
|
+
}
|
|
210
|
+
},
|
|
211
|
+
{
|
|
212
|
+
"id": "audit-query-valid",
|
|
213
|
+
"description": "Alice sends a signed audit query to the witness (POST, not GET)",
|
|
214
|
+
"input": {
|
|
215
|
+
"method": "POST",
|
|
216
|
+
"path": "/ink/v1/audit/query",
|
|
217
|
+
"recipientDid": "did:web:witness.tulpa.network",
|
|
218
|
+
"body": {
|
|
219
|
+
"protocol": "ink/0.1",
|
|
220
|
+
"type": "network.tulpa.audit_query",
|
|
221
|
+
"from": "did:plc:alice123test",
|
|
222
|
+
"to": "did:web:witness.tulpa.network",
|
|
223
|
+
"messageId": "msg-witness-001",
|
|
224
|
+
"nonce": "d2l0cXVlcnkx",
|
|
225
|
+
"timestamp": "2026-03-25T13:00:00Z"
|
|
226
|
+
},
|
|
227
|
+
"timestamp": "2026-03-25T13:00:00Z",
|
|
228
|
+
"signerPrivateKeyHex": "02362f546f26d9c252c9209d1218e3174654b04b5f08f2ee2b3fa7874111d086",
|
|
229
|
+
"note": "Query is now POST with a signed body. Sender identity is derived from verified auth, not caller-supplied input."
|
|
230
|
+
},
|
|
231
|
+
"expected": {
|
|
232
|
+
"canonicalBody": "{\"from\":\"did:plc:alice123test\",\"messageId\":\"msg-witness-001\",\"nonce\":\"d2l0cXVlcnkx\",\"protocol\":\"ink/0.1\",\"timestamp\":\"2026-03-25T13:00:00Z\",\"to\":\"did:web:witness.tulpa.network\",\"type\":\"network.tulpa.audit_query\"}",
|
|
233
|
+
"signatureBase": "ink/0.1\nPOST\n/ink/v1/audit/query\ndid:web:witness.tulpa.network\n{\"from\":\"did:plc:alice123test\",\"messageId\":\"msg-witness-001\",\"nonce\":\"d2l0cXVlcnkx\",\"protocol\":\"ink/0.1\",\"timestamp\":\"2026-03-25T13:00:00Z\",\"to\":\"did:web:witness.tulpa.network\",\"type\":\"network.tulpa.audit_query\"}\n2026-03-25T13:00:00Z",
|
|
234
|
+
"signatureBase64url": "HxwK-MCsd1myi3bgLZ6qP1oAe3U_kErq7ztNmieSw789MYFJJkZ8qm4oxtZNShSxHFjivJbBA4lyrJjlHHT-BA",
|
|
235
|
+
"accepted": true
|
|
236
|
+
}
|
|
237
|
+
},
|
|
238
|
+
{
|
|
239
|
+
"id": "audit-query-invalid-path",
|
|
240
|
+
"description": "Query signature fails when verified against /audit/submit path",
|
|
241
|
+
"input": {
|
|
242
|
+
"method": "POST",
|
|
243
|
+
"path": "/ink/v1/audit/submit",
|
|
244
|
+
"recipientDid": "did:web:witness.tulpa.network",
|
|
245
|
+
"body": {
|
|
246
|
+
"protocol": "ink/0.1",
|
|
247
|
+
"type": "network.tulpa.audit_query",
|
|
248
|
+
"from": "did:plc:alice123test",
|
|
249
|
+
"to": "did:web:witness.tulpa.network",
|
|
250
|
+
"messageId": "msg-witness-001",
|
|
251
|
+
"nonce": "d2l0cXVlcnkx",
|
|
252
|
+
"timestamp": "2026-03-25T13:00:00Z"
|
|
253
|
+
},
|
|
254
|
+
"timestamp": "2026-03-25T13:00:00Z",
|
|
255
|
+
"originalSignatureBase64url": "HxwK-MCsd1myi3bgLZ6qP1oAe3U_kErq7ztNmieSw789MYFJJkZ8qm4oxtZNShSxHFjivJbBA4lyrJjlHHT-BA"
|
|
256
|
+
},
|
|
257
|
+
"expected": {
|
|
258
|
+
"accepted": false,
|
|
259
|
+
"reason": "Signature was computed over /audit/query but verified against /audit/submit"
|
|
260
|
+
}
|
|
261
|
+
},
|
|
262
|
+
{
|
|
263
|
+
"id": "audit-query-body-tamper",
|
|
264
|
+
"description": "Query signature fails when messageId is tampered",
|
|
265
|
+
"input": {
|
|
266
|
+
"method": "POST",
|
|
267
|
+
"path": "/ink/v1/audit/query",
|
|
268
|
+
"recipientDid": "did:web:witness.tulpa.network",
|
|
269
|
+
"body": {
|
|
270
|
+
"protocol": "ink/0.1",
|
|
271
|
+
"type": "network.tulpa.audit_query",
|
|
272
|
+
"from": "did:plc:alice123test",
|
|
273
|
+
"to": "did:web:witness.tulpa.network",
|
|
274
|
+
"messageId": "msg-TAMPERED-001",
|
|
275
|
+
"nonce": "d2l0cXVlcnkx",
|
|
276
|
+
"timestamp": "2026-03-25T13:00:00Z"
|
|
277
|
+
},
|
|
278
|
+
"timestamp": "2026-03-25T13:00:00Z",
|
|
279
|
+
"originalSignatureBase64url": "HxwK-MCsd1myi3bgLZ6qP1oAe3U_kErq7ztNmieSw789MYFJJkZ8qm4oxtZNShSxHFjivJbBA4lyrJjlHHT-BA"
|
|
280
|
+
},
|
|
281
|
+
"expected": {
|
|
282
|
+
"accepted": false,
|
|
283
|
+
"reason": "Body was modified after signing"
|
|
284
|
+
}
|
|
285
|
+
},
|
|
286
|
+
{
|
|
287
|
+
"id": "audit-query-timestamp-expired",
|
|
288
|
+
"description": "Query rejected — timestamp expired",
|
|
289
|
+
"input": {
|
|
290
|
+
"messageTimestamp": "2026-03-25T12:50:00Z",
|
|
291
|
+
"receiverClock": "2026-03-25T13:00:00Z",
|
|
292
|
+
"nonce": "d2l0cXVlcnkx"
|
|
293
|
+
},
|
|
294
|
+
"expected": {
|
|
295
|
+
"accepted": false,
|
|
296
|
+
"errorCode": "expired_message"
|
|
297
|
+
}
|
|
298
|
+
},
|
|
299
|
+
{
|
|
300
|
+
"id": "audit-query-duplicate-nonce",
|
|
301
|
+
"description": "Query rejected — duplicate nonce",
|
|
302
|
+
"input": {
|
|
303
|
+
"messageTimestamp": "2026-03-25T13:00:00Z",
|
|
304
|
+
"receiverClock": "2026-03-25T13:00:00Z",
|
|
305
|
+
"nonce": "d2l0cXVlcnkx",
|
|
306
|
+
"previouslySeenNonces": [
|
|
307
|
+
"d2l0cXVlcnkx"
|
|
308
|
+
]
|
|
309
|
+
},
|
|
310
|
+
"expected": {
|
|
311
|
+
"accepted": false,
|
|
312
|
+
"errorCode": "duplicate_nonce"
|
|
313
|
+
}
|
|
314
|
+
},
|
|
315
|
+
{
|
|
316
|
+
"id": "interop-submit-path-cross-endpoint",
|
|
317
|
+
"description": "Interop: submit signature verified against query path fails — prevents cross-endpoint replay between main worker and witness",
|
|
318
|
+
"input": {
|
|
319
|
+
"note": "Agent builds a signed audit_submit. If replayed against /audit/query, verification must fail.",
|
|
320
|
+
"method": "POST",
|
|
321
|
+
"originalPath": "/ink/v1/audit/submit",
|
|
322
|
+
"replayPath": "/ink/v1/audit/query",
|
|
323
|
+
"recipientDid": "did:web:witness.tulpa.network",
|
|
324
|
+
"body": {
|
|
325
|
+
"protocol": "ink/0.1",
|
|
326
|
+
"type": "network.tulpa.audit_submit",
|
|
327
|
+
"from": "did:plc:alice123test",
|
|
328
|
+
"to": "did:web:witness.tulpa.network",
|
|
329
|
+
"event": {
|
|
330
|
+
"id": "01JWIT0001",
|
|
331
|
+
"version": "ink-audit/1",
|
|
332
|
+
"agentId": "agent-alice-01",
|
|
333
|
+
"sequence": 1,
|
|
334
|
+
"previousEventHash": null,
|
|
335
|
+
"eventType": "message.sent",
|
|
336
|
+
"timestamp": "2026-03-25T12:00:00Z",
|
|
337
|
+
"messageId": "msg-witness-001",
|
|
338
|
+
"counterpartyId": "did:plc:bob456test",
|
|
339
|
+
"agentSignature": "9Z3iO9pQoTdn3JBu__nEqH7MC7XrqPlWS4xnyANaMoe0tVz6tp5yPMSxFWbpBN1rF2QfRELGhh37dzCXXC8vCg"
|
|
340
|
+
},
|
|
341
|
+
"nonce": "d2l0c3VibWl0MQ",
|
|
342
|
+
"timestamp": "2026-03-25T12:00:01Z"
|
|
343
|
+
},
|
|
344
|
+
"timestamp": "2026-03-25T12:00:01Z",
|
|
345
|
+
"originalSignatureBase64url": "7VN7IJvoezRDTC_oJGu5fc8Xz2l0cgOYkmgRf3TcASp_6F62SjILXcSeSfljVWznLEReyTvNBOk4c-JTw6fZDQ"
|
|
346
|
+
},
|
|
347
|
+
"expected": {
|
|
348
|
+
"accepted": false,
|
|
349
|
+
"reason": "Path binding prevents cross-endpoint replay"
|
|
350
|
+
}
|
|
351
|
+
},
|
|
352
|
+
{
|
|
353
|
+
"id": "interop-query-recipient-cross-witness",
|
|
354
|
+
"description": "Interop: query signed for one witness fails on another — prevents cross-witness replay",
|
|
355
|
+
"input": {
|
|
356
|
+
"note": "Agent signs query to did:web:witness.tulpa.network. If replayed against a different witness DID, verification must fail.",
|
|
357
|
+
"method": "POST",
|
|
358
|
+
"path": "/ink/v1/audit/query",
|
|
359
|
+
"originalRecipient": "did:web:witness.tulpa.network",
|
|
360
|
+
"replayRecipient": "did:web:evil-witness.example.com",
|
|
361
|
+
"body": {
|
|
362
|
+
"protocol": "ink/0.1",
|
|
363
|
+
"type": "network.tulpa.audit_query",
|
|
364
|
+
"from": "did:plc:alice123test",
|
|
365
|
+
"to": "did:web:witness.tulpa.network",
|
|
366
|
+
"messageId": "msg-witness-001",
|
|
367
|
+
"nonce": "d2l0cXVlcnkx",
|
|
368
|
+
"timestamp": "2026-03-25T13:00:00Z"
|
|
369
|
+
},
|
|
370
|
+
"timestamp": "2026-03-25T13:00:00Z",
|
|
371
|
+
"originalSignatureBase64url": "HxwK-MCsd1myi3bgLZ6qP1oAe3U_kErq7ztNmieSw789MYFJJkZ8qm4oxtZNShSxHFjivJbBA4lyrJjlHHT-BA"
|
|
372
|
+
},
|
|
373
|
+
"expected": {
|
|
374
|
+
"accepted": false,
|
|
375
|
+
"reason": "Recipient binding prevents cross-witness replay"
|
|
376
|
+
}
|
|
377
|
+
},
|
|
378
|
+
{
|
|
379
|
+
"id": "interop-main-worker-intent-to-witness",
|
|
380
|
+
"description": "Interop: intent signature from main worker cannot be replayed as witness submit",
|
|
381
|
+
"input": {
|
|
382
|
+
"note": "An intent signed for /ink/v1/intent with recipient did:plc:bob456test cannot be replayed against /ink/v1/audit/submit with recipient did:web:witness.tulpa.network. Both path and recipient differ.",
|
|
383
|
+
"intentPath": "/ink/v1/intent",
|
|
384
|
+
"intentRecipient": "did:plc:bob456test",
|
|
385
|
+
"submitPath": "/ink/v1/audit/submit",
|
|
386
|
+
"submitRecipient": "did:web:witness.tulpa.network"
|
|
387
|
+
},
|
|
388
|
+
"expected": {
|
|
389
|
+
"accepted": false,
|
|
390
|
+
"reason": "Both path and recipient binding prevent cross-service replay"
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
]
|
|
394
|
+
}
|