@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,309 @@
|
|
|
1
|
+
# INK v0.1 Compliance Checklist and Implementation Matrix
|
|
2
|
+
|
|
3
|
+
## Status
|
|
4
|
+
Draft, v0.1 alpha conformance
|
|
5
|
+
|
|
6
|
+
## Purpose
|
|
7
|
+
|
|
8
|
+
This checklist lets an independent implementer verify INK conformance without reading Tulpa source code. Each requirement maps to a spec section, test vector family and implementation status.
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## How to Read This Document
|
|
13
|
+
|
|
14
|
+
**Requirement levels** follow RFC 2119:
|
|
15
|
+
- **MUST**, absolute requirement for conformance
|
|
16
|
+
- **SHOULD**, recommended; deviations require justification
|
|
17
|
+
- **MAY**, truly optional; advertised via capability
|
|
18
|
+
|
|
19
|
+
**Status column** applies to the Tulpa reference implementation:
|
|
20
|
+
- **Required**, part of the v1 wire contract
|
|
21
|
+
- **Optional**, capability-gated, not assumed
|
|
22
|
+
- **Extension**, defined but not required for base interop
|
|
23
|
+
- **Future**, specified for later versions
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## 1. Discovery
|
|
28
|
+
|
|
29
|
+
| # | Requirement | Level | Status | Spec | Vectors | Tests |
|
|
30
|
+
|---|-----------|-------|--------|------|---------|-------|
|
|
31
|
+
| D1 | Agent Card served at `GET /ink/v1/{agentId}/agent.json` | MUST | Required | Protocol §2 |, | `test/ink-discovery-gating.test.ts` |
|
|
32
|
+
| D2 | Agent Card includes `protocol`, `agentId`, `publicKeyMultibase`, `endpoint` | MUST | Required | Protocol §2 |, | `test/ink-discovery-gating.test.ts` |
|
|
33
|
+
| D3 | Agent Card includes `capabilities.intentsAccepted` and `intentsSent` | MUST | Required | Protocol §2 |, | `test/ink-discovery-gating.test.ts` |
|
|
34
|
+
| D4 | Agent Card includes `keys.signing[]` with key-set model | SHOULD | Required | Key Rotation §5 | `key-rotation.json` | `test/ink-key-rotation.test.ts` |
|
|
35
|
+
| D5 | Agent Card includes `currentSigningKeyId` and `keySetVersion` | SHOULD | Required | Key Rotation §5 | `key-rotation.json` | `test/ink-key-rotation.test.ts` |
|
|
36
|
+
| D6 | Legacy single-key Agent Cards accepted (no `keys` block) | MUST | Required | Key Rotation §16 | `key-rotation.json` | `test/ink-key-rotation.test.ts` |
|
|
37
|
+
| D7 | Agent Card includes receipt capability advertisement | MAY | Optional | Auditability §1 |, | `test/ink-discovery-gating.test.ts` |
|
|
38
|
+
| D8 | Agent Card includes third-party audit service advertisement | MAY | Optional | Auditability §7 |, | `test/ink-discovery-gating.test.ts` |
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## 2. Transport Signing
|
|
43
|
+
|
|
44
|
+
| # | Requirement | Level | Status | Spec | Vectors | Tests |
|
|
45
|
+
|---|-----------|-------|--------|------|---------|-------|
|
|
46
|
+
| S1 | Signature base: `ink/0.1\nMETHOD\nPATH\nrecipientDid\nJCS(body)\ntimestamp` | MUST | Required | Protocol §3.3 | `signing.json` | `test/security-fixes.test.ts` |
|
|
47
|
+
| S2 | Ed25519 signature over UTF-8 encoded signature base | MUST | Required | Protocol §3.3 | `signing.json` | `test/security-fixes.test.ts` |
|
|
48
|
+
| S3 | Auth header: `INK-Ed25519 <base64url(sig)>` | MUST | Required | Protocol §3.3 | `signing.json` | `test/security-fixes.test.ts` |
|
|
49
|
+
| S4 | Auth header extended: `INK-Ed25519 <sig> keyId=<keyId>` (optional) | SHOULD | Required | Key Rotation §13 | `key-rotation.json` | `test/ink-auth-header.test.ts` |
|
|
50
|
+
| S5 | base64url encoding uses no-padding (RFC 4648 §5) | MUST | Required | Protocol §3.3 | `signing.json` | `test/security-fixes.test.ts` |
|
|
51
|
+
| S6 | JCS canonicalization per RFC 8785 | MUST | Required | Protocol §3.3 | `jcs.json` | `test/security-fixes.test.ts` |
|
|
52
|
+
| S7 | Verification fails on wrong path | MUST | Required | Protocol §3.3 | `signing.json` | `test/security-fixes.test.ts` |
|
|
53
|
+
| S8 | Verification fails on tampered body | MUST | Required | Protocol §3.3 | `signing.json` | `test/security-fixes.test.ts` |
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## 3. Replay Protection
|
|
58
|
+
|
|
59
|
+
| # | Requirement | Level | Status | Spec | Vectors | Tests |
|
|
60
|
+
|---|-----------|-------|--------|------|---------|-------|
|
|
61
|
+
| R1 | Reject timestamps older than 5 minutes | MUST | Required | Protocol §3.5 | `replay.json` | `test/security-fixes.test.ts` |
|
|
62
|
+
| R2 | Reject timestamps more than 30 seconds in the future | MUST | Required | Protocol §3.5 | `replay.json` | `test/security-fixes.test.ts` |
|
|
63
|
+
| R3 | Reject duplicate nonces within the freshness window | MUST | Required | Protocol §3.5 | `replay.json` | `test/security-fixes.test.ts` |
|
|
64
|
+
| R4 | Accept valid nonce + fresh timestamp | MUST | Required | Protocol §3.5 | `replay.json` | `test/security-fixes.test.ts` |
|
|
65
|
+
| R5 | Nonce recorded only after all rejection checks pass | SHOULD | Required | Auth Chain Audit |, | `test/security-fixes.test.ts` |
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## 4. Encryption
|
|
70
|
+
|
|
71
|
+
| # | Requirement | Level | Status | Spec | Vectors | Tests |
|
|
72
|
+
|---|-----------|-------|--------|------|---------|-------|
|
|
73
|
+
| E1 | ECIES: X25519 ECDH + HKDF-SHA256 + AES-256-GCM | MUST (if encryption supported) | Required | Protocol §3.4 | `encryption.json` | `test/security-fixes.test.ts` |
|
|
74
|
+
| E2 | HKDF salt: `"ink/0.1"`, info: `"ink/0.1/encrypt"` | MUST | Required | Protocol §3.4 | `encryption.json` | `test/security-fixes.test.ts` |
|
|
75
|
+
| E3 | AAD: `"ink/0.1:envelope\n"` + JCS(protocol, type, from, ephemeralKey, nonce, timestamp, messageNonce) | MUST | Required | Protocol §3.4 | `encryption.json` | `test/security-fixes.test.ts` |
|
|
76
|
+
| E4 | Encrypted envelope type: `network.tulpa.encrypted` | MUST | Required | Protocol §3.4 | `encryption.json` | `test/security-fixes.test.ts` |
|
|
77
|
+
| E5 | `schedule_meeting` and `context_share` require encryption | MUST | Required | Protocol §3.4 |, | `test/security-fixes.test.ts` |
|
|
78
|
+
| E6 | Decryption validates inner/outer envelope consistency | MUST | Required | Protocol §3.4 |, | `test/security-fixes.test.ts` |
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## 5. Message Envelope
|
|
83
|
+
|
|
84
|
+
| # | Requirement | Level | Status | Spec | Vectors | Tests |
|
|
85
|
+
|---|-----------|-------|--------|------|---------|-------|
|
|
86
|
+
| M1 | Envelope includes `protocol`, `type`, `from`, `to`, `timestamp`, `nonce` (handshake messages also include `correlationId`) | MUST | Required | Protocol §3.1 | `signing.json` | `test/security-fixes.test.ts` |
|
|
87
|
+
| M2 | `protocol` field is `"ink/0.1"` | MUST | Required | Protocol §3.1 | `signing.json` | `test/security-fixes.test.ts` |
|
|
88
|
+
| M3 | `signingKeyId` optional field for key rotation | SHOULD | Required | Key Rotation §13 | `key-rotation.json` | `test/ink-auth-header.test.ts` |
|
|
89
|
+
| M4 | Unknown fields preserved during canonicalization | MUST | Required | Compat Policy §3.1 | `jcs.json` | `test/security-fixes.test.ts` |
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## 6. Handshake
|
|
94
|
+
|
|
95
|
+
| # | Requirement | Level | Status | Spec | Vectors | Tests |
|
|
96
|
+
|---|-----------|-------|--------|------|---------|-------|
|
|
97
|
+
| H1 | Challenge: `network.tulpa.challenge` with INK-Ed25519 auth | MUST | Required | Protocol §5 | `handshake.json` | `test/ink-handshake-schemas.test.ts` |
|
|
98
|
+
| H2 | Rejection: `network.tulpa.rejection` with reason code | MUST | Required | Protocol §5 | `handshake.json` | `test/ink-handshake-schemas.test.ts` |
|
|
99
|
+
| H3 | Resolution: `network.tulpa.resolution` with outcome | MUST | Required | Protocol §5 | `handshake.json` | `test/ink-handshake-schemas.test.ts` |
|
|
100
|
+
| H4 | Resolution outcome: `accepted`, `declined`, `escalated_to_human`, `expired` | MUST | Required | Protocol §5 | `handshake.json` | `test/ink-handshake-schemas.test.ts` |
|
|
101
|
+
| H5 | Handshake messages signed with same signature base rules | MUST | Required | Protocol §3.3/§5 | `handshake.json` | `test/ink-handshake-schemas.test.ts` |
|
|
102
|
+
| H6 | Path binding: signature for `/challenge` rejects at `/rejection` | MUST | Required | Protocol §3.3 | `handshake.json` | `test/ink-handshake-schemas.test.ts` |
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
## 7. Receipts
|
|
107
|
+
|
|
108
|
+
| # | Requirement | Level | Status | Spec | Vectors | Tests |
|
|
109
|
+
|---|-----------|-------|--------|------|---------|-------|
|
|
110
|
+
| RC1 | Receipt type: `network.tulpa.receipt` | MUST (if receipts supported) | Optional | Auditability §1 | `receipts-and-audit.json` | `test/ink-receipt-generation.test.ts` |
|
|
111
|
+
| RC2 | Dispositions: `received`, `delivered`, `acted`, `rejected`, `expired` | MUST | Optional | Auditability §1 | `receipts-and-audit.json` | `test/ink-receipt-generation.test.ts` |
|
|
112
|
+
| RC3 | `messageHash`: SHA-256 of JCS-canonicalized original message (hex) | MUST | Optional | Auditability §1 | `receipts-and-audit.json` | `test/ink-receipt-generation.test.ts` |
|
|
113
|
+
| RC4 | Receipts are Ed25519 signed | MUST | Optional | Auditability §1 | `receipts-and-audit.json` | `test/ink-receipt-generation.test.ts` |
|
|
114
|
+
| RC5 | No receipt sent for receipts (loop prevention) | MUST | Optional | Auditability §1 |, | `test/ink-receipt-generation.test.ts` |
|
|
115
|
+
| RC6 | Receipt transport uses INK-Ed25519 auth header | MUST | Optional | Auditability §1 | `receipts-and-audit.json` | `test/ink-receipt-generation.test.ts` |
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## 8. Bilateral Audit Exchange
|
|
120
|
+
|
|
121
|
+
| # | Requirement | Level | Status | Spec | Vectors | Tests |
|
|
122
|
+
|---|-----------|-------|--------|------|---------|-------|
|
|
123
|
+
| A1 | Audit events: hash-chained with `previousEventHash` (SHA-256 hex) | MUST (if audit supported) | Optional | Auditability §2 | `receipts-and-audit.json` | `test/ink-receipt-generation.test.ts` |
|
|
124
|
+
| A2 | Audit events: signed with `agentSignature` (Ed25519) | MUST | Optional | Auditability §2 | `receipts-and-audit.json` | `test/ink-receipt-generation.test.ts` |
|
|
125
|
+
| A3 | Monotonic `sequence` per agent | MUST | Optional | Auditability §2 | `receipts-and-audit.json` | `test/ink-receipt-generation.test.ts` |
|
|
126
|
+
| A4 | Audit query: `network.tulpa.audit_query` with INK auth | MUST | Optional | Auditability §3 | `receipts-and-audit.json` | `test/ink-receipt-generation.test.ts` |
|
|
127
|
+
| A5 | Audit response: filtered to sender/recipient only | MUST | Optional | Auditability §3 |, | `test/ink-receipt-generation.test.ts` |
|
|
128
|
+
| A6 | Fork detection: same sequence + different hash = tampered | MUST | Optional | Auditability §2 | `receipts-and-audit.json` | `test/security-round25.test.ts` |
|
|
129
|
+
| A7 | `signingKeyId` recorded as top-level `InkAuditEvent.signingKeyId` field | SHOULD | Required | Key Rotation Phase 3 | `key-rotation.json` | `test/ink-key-rotation.test.ts` |
|
|
130
|
+
| A8 | Response slices have strictly +1 sequence continuity (no gaps within a slice) | MUST | Required | Auditability §3 | `receipts-and-audit.json` | `test/security-round25.test.ts` |
|
|
131
|
+
| A9 | `previousEventHash` MUST equal SHA-256(JCS(prior event without `agentSignature`)) for every event after the first in a slice | MUST | Required | Auditability §2 | `receipts-and-audit.json` | `test/security-round25.test.ts` |
|
|
132
|
+
| A10 | Consumers run both `verifyAuditResponseSignature` and `verifyAuditEventChain` before treating events as authoritative | MUST | Required | Auditability §3 |, | `test/security-round25.test.ts` |
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## 9. Third-Party Witness
|
|
137
|
+
|
|
138
|
+
| # | Requirement | Level | Status | Spec | Vectors | Tests |
|
|
139
|
+
|---|-----------|-------|--------|------|---------|-------|
|
|
140
|
+
| W1 | Submit: `POST /ink/v1/audit/submit` with INK-Ed25519 + embedded event signature | MUST (if witness supported) | Optional | Auditability §7 | `witness.json` | `test/security-fixes.test.ts`, `witness/witness/test/endpoints.test.ts (witness repo)` |
|
|
141
|
+
| W2 | Query: `POST /ink/v1/audit/query` with INK-Ed25519 | MUST | Optional | Auditability §7 | `witness.json` | `test/security-fixes.test.ts`, `witness/witness/test/endpoints.test.ts (witness repo)` |
|
|
142
|
+
| W3 | Access control: requester must be event agent or counterparty | MUST | Optional | Auditability §7 | `witness.json` | `witness/witness/test/endpoints.test.ts (witness repo)` |
|
|
143
|
+
| W4 | Merkle tree: RFC 6962-style binary tree | MUST | Optional | Auditability §7 |, | `witness/witness/test/merkle.test.ts (witness repo)` |
|
|
144
|
+
| W5 | Inclusion receipt: signed by witness service | MUST | Optional | Auditability §7 |, | `witness/witness/test/endpoints.test.ts (witness repo)` |
|
|
145
|
+
| W6 | Checkpoint: C2SP tlog-checkpoint format at `GET /ink/v1/checkpoint` | SHOULD | Optional | Auditability §7 |, | `witness/witness/test/endpoints.test.ts (witness repo)` |
|
|
146
|
+
| W7 | Transport auth on submit: dual signature (transport + event) | MUST | Optional | Auditability §7 | `witness.json` | `witness/witness/test/endpoints.test.ts (witness repo)` |
|
|
147
|
+
| W8 | Submit includes `signingKeyId` in transport auth | SHOULD | Required | Key Rotation Phase 3 |, | `test/ink-key-rotation.test.ts` |
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
## 10. Key Rotation
|
|
152
|
+
|
|
153
|
+
| # | Requirement | Level | Status | Spec | Vectors | Tests |
|
|
154
|
+
|---|-----------|-------|--------|------|---------|-------|
|
|
155
|
+
| K1 | `agentId` stable across key rotation | MUST | Required | Key Rotation §4 |, | `test/ink-key-rotation-e2e.test.ts` |
|
|
156
|
+
| K2 | Agent Card key-set: `keys.signing[]` with `keyId`, `algorithm`, `publicKeyMultibase`, `status`, `validFrom` | MUST | Required | Key Rotation §5 | `key-rotation.json` | `test/ink-key-rotation.test.ts` |
|
|
157
|
+
| K3 | Key statuses: `active`, `retired`, `revoked` | MUST | Required | Key Rotation §5.3 | `key-rotation.json` | `test/ink-key-rotation.test.ts` |
|
|
158
|
+
| K4 | Verification order: hinted key → active → retired → skip revoked | MUST | Required | Key Rotation §6.4 | `key-rotation.json` | `test/ink-key-rotation.test.ts` |
|
|
159
|
+
| K5 | Retired keys valid for historical verification | MUST | Required | Key Rotation §6.2 | `key-rotation.json` | `test/ink-key-rotation.test.ts` |
|
|
160
|
+
| K6 | Revoked keys rejected for signatures after `revokedAt` | MUST | Required | Key Rotation §6.3 | `key-rotation.json` | `test/ink-key-rotation.test.ts` |
|
|
161
|
+
| K7 | Cache refresh on verification miss (max 1 retry) | SHOULD | Required | Key Rotation §9.2 | `key-rotation.json` | `test/ink-key-rotation-e2e.test.ts` |
|
|
162
|
+
| K8 | `keyId` emitted on outbound messages (auth header + envelope) | SHOULD | Required | Key Rotation §13 | `key-rotation.json` | `test/ink-auth-header.test.ts` |
|
|
163
|
+
| K9 | `keyId` in auth header takes precedence over body `signingKeyId` | SHOULD | Required | Key Rotation §13 | `key-rotation.json` | `test/ink-key-rotation.test.ts` |
|
|
164
|
+
| K10 | Historical keys retained minimum 90 days | SHOULD | Required | Key Rotation §11.2 |, |, |
|
|
165
|
+
| K11 | `keySetVersion` monotonically incremented on rotation/revocation | MUST | Required | Key Rotation §5 |, | `test/ink-key-rotation-e2e.test.ts` |
|
|
166
|
+
| K12 | Rotation audit events: `key.rotated`, `key.revoked` | SHOULD | Required | Audit Bridge | `key-rotation.json` | `test/ink-key-rotation.test.ts` |
|
|
167
|
+
| K13 | Retired-key verification result includes `keyStatus` | SHOULD | Required | Multi-Key Verify |, | `test/ink-key-rotation.test.ts` |
|
|
168
|
+
|
|
169
|
+
---
|
|
170
|
+
|
|
171
|
+
## 11. Authorization Chains
|
|
172
|
+
|
|
173
|
+
| # | Requirement | Level | Status | Spec | Vectors | Tests |
|
|
174
|
+
|---|-----------|-------|--------|------|---------|-------|
|
|
175
|
+
| AC1 | `provenance` field on message envelope | MAY | Extension | Auth Chain §1 |, | `test/security-fixes.test.ts` |
|
|
176
|
+
| AC2 | Delegation token: signed scope + expiry | MAY | Extension | Auth Chain §2 |, | `test/security-fixes.test.ts` |
|
|
177
|
+
| AC3 | Multi-hop chains: ordered hops with permission attenuation | MAY | Extension | Auth Chain §3 |, |, |
|
|
178
|
+
| AC4 | `allowedTransports` constraint on delegation hops | SHOULD | Required | Containment §7 |, | `test/ink-transport-auth.test.ts` |
|
|
179
|
+
| AC5 | Transport attenuation: child hops subset of parent transports | MUST | Required | Containment §7 |, | `test/ink-transport-auth.test.ts` |
|
|
180
|
+
| AC6 | Omitted `allowedTransports` defaults to `["ink_http"]` (v0.3+ tokens) | MUST | Required | Containment §7 |, | `test/ink-transport-auth.test.ts` |
|
|
181
|
+
| AC7 | Legacy tokens: version-gated migration with permissive default | MUST | Required | Containment §7 |, | `test/ink-transport-auth.test.ts` |
|
|
182
|
+
|
|
183
|
+
---
|
|
184
|
+
|
|
185
|
+
## 12. Error Semantics
|
|
186
|
+
|
|
187
|
+
| # | Requirement | Level | Status | Spec | Vectors | Tests |
|
|
188
|
+
|---|-----------|-------|--------|------|---------|-------|
|
|
189
|
+
| ER1 | `missing_authorization`, no auth header | MUST | Required | Protocol §3.3 | `handshake.json` | `test/ink-handshake-schemas.test.ts` |
|
|
190
|
+
| ER2 | `invalid_auth_scheme`, wrong auth scheme | MUST | Required | Protocol §3.3 |, | `test/security-fixes.test.ts` |
|
|
191
|
+
| ER3 | `invalid_signature`, signature does not verify | MUST | Required | Protocol §3.3 | `signing.json` | `test/security-fixes.test.ts` |
|
|
192
|
+
| ER4 | `timestamp_expired`, older than 5 minutes | MUST | Required | Protocol §3.5 | `replay.json` | `test/security-fixes.test.ts` |
|
|
193
|
+
| ER5 | `timestamp_too_far_future`, more than 30s ahead | MUST | Required | Protocol §3.5 | `replay.json` | `test/security-fixes.test.ts` |
|
|
194
|
+
| ER6a | `nonce_handling_required`, `verifyInkAuth` invoked without a `nonceStore` (fail-closed default) | MUST | Required | Protocol §3.5 | `replay.json` | `test/security-round25.test.ts` |
|
|
195
|
+
| ER6b | `missing_nonce`, body.nonce missing or out of `[16,256]` charset bounds when `nonceStore` is supplied | MUST | Required | Protocol §3.5 | `replay.json` | `test/security-round25.test.ts` |
|
|
196
|
+
| ER6c | `nonce_replay`, `nonceStore.has(nonce)` returned true after successful signature verify | MUST | Required | Protocol §3.5 | `replay.json` | `test/security-round25.test.ts` |
|
|
197
|
+
| ER6d | `nonce_store_error`, `nonceStore.has` or `.add` threw (fail-closed) | MUST | Required | Protocol §3.5 |, | `test/security-round25.test.ts` |
|
|
198
|
+
| ER6e | `duplicate_nonce`, returned by the standalone `checkReplay` helper when a nonce is in `previouslySeenNonces` | MUST | Required | Protocol §3.5 | `replay.json` | `test/security-fixes.test.ts` |
|
|
199
|
+
| ER7 | `unsupported_intent`, unknown intent type | MUST | Required | Protocol §3.1 |, | `test/security-fixes.test.ts` |
|
|
200
|
+
| ER8 | `encryption_required`, plaintext where encrypted required | MUST | Required | Protocol §3.4 |, | `test/security-fixes.test.ts` |
|
|
201
|
+
| ER9 | `rate_limited`, request rate exceeded | SHOULD | Required | Protocol §4 |, | `test/security-fixes.test.ts` |
|
|
202
|
+
| ER10 | `handshake_budget_exhausted`, per-correlation budget hit | SHOULD | Required | Containment §5 |, | `test/ink-handshake-budget.test.ts` |
|
|
203
|
+
| ER11 | `sender_rate_limited`, per-sender rate limit hit | SHOULD | Required | Containment §5 |, | `test/ink-handshake-budget.test.ts` |
|
|
204
|
+
| ER12 | `counterparty_cooldown`, recipient broadly rate-limiting | SHOULD | Required | Containment §5 |, | `test/ink-handshake-budget.test.ts` |
|
|
205
|
+
| ER13 | `delegation_budget_exhausted`, delegation issuance limit hit | SHOULD | Required | Containment §4 |, | `test/ink-transport-auth.test.ts` |
|
|
206
|
+
| ER14 | `transport_scope_violation`, invocation transport not in token | MUST | Required | Containment §7 |, | `test/ink-transport-auth.test.ts` |
|
|
207
|
+
|
|
208
|
+
---
|
|
209
|
+
|
|
210
|
+
## 13. Containment (Phase 1)
|
|
211
|
+
|
|
212
|
+
| # | Requirement | Level | Status | Spec | Vectors | Tests |
|
|
213
|
+
|---|-----------|-------|--------|------|---------|-------|
|
|
214
|
+
| CT1 | Agent Card `visibility` field: `public`, `network_only`, `capability_gated`, `private` | SHOULD | Required | Containment §6 |, | `test/ink-discovery-gating.test.ts` |
|
|
215
|
+
| CT2 | Unauthenticated GET returns redacted card for non-public visibility | MUST | Required | Containment §6 |, | `test/ink-discovery-gating.test.ts` |
|
|
216
|
+
| CT3 | Redacted card includes only: `agentId`, `displayName`, `supportsInk`, `discoveryMode` | MUST | Required | Containment §6 |, | `test/ink-discovery-gating.test.ts` |
|
|
217
|
+
| CT4 | `POST /ink/v1/{agentId}/agent-card-query` with INK-Ed25519 auth | MUST (if `capability_gated`) | Required | Containment §6 |, | `test/ink-discovery-gating.test.ts` |
|
|
218
|
+
| CT5 | Authenticated query denied for unknown requester | MUST | Required | Containment §6 |, | `test/ink-discovery-gating.test.ts` |
|
|
219
|
+
| CT6 | `private` visibility returns 404 on unauthenticated GET | MUST | Required | Containment §6 |, | `test/ink-discovery-gating.test.ts` |
|
|
220
|
+
| CT7 | Per-correlation handshake budget: max 3 challenges | SHOULD | Required | Containment §5 |, | `test/ink-handshake-budget.test.ts` |
|
|
221
|
+
| CT8 | Rejection and resolution are terminal per correlationId | MUST | Required | Containment §5 |, | `test/ink-handshake-budget.test.ts` |
|
|
222
|
+
| CT9 | Total state transitions capped at 5 per correlationId | SHOULD | Required | Containment §5 |, | `test/ink-handshake-budget.test.ts` |
|
|
223
|
+
| CT10 | Handshake TTL bounded by intent `expiresAt` or 24h | SHOULD | Required | Containment §5 |, | `test/ink-handshake-budget.test.ts` |
|
|
224
|
+
| CT11 | Per-sender intent rate limit: 10/minute | SHOULD | Required | Containment §5 |, | `test/ink-handshake-budget.test.ts` |
|
|
225
|
+
| CT12 | First budget violation returns typed rejection with backoff hint | MUST | Required | Containment §5 |, | `test/ink-handshake-budget.test.ts` |
|
|
226
|
+
| CT13 | Subsequent violations are silent drops (no amplification) | MUST | Required | Containment §5 |, | `test/ink-handshake-budget.test.ts` |
|
|
227
|
+
| CT14 | `backoffHint` optional on rejection: `retryAfterSeconds`, `cooldownUntil`, `backoffClass` | MAY | Required | Containment §5 |, | `test/ink-handshake-budget.test.ts` |
|
|
228
|
+
| CT15 | Agent Card `governance` block: `maxAcceptedDelegationDepth`, `supportedTransports`, `handshakeBudget` | MAY | Required | Containment §9 |, |, |
|
|
229
|
+
| CT16 | Containment audit events: `transport_scope_violation`, `handshake_rate_limited`, `handshake_budget_exhausted`, `discovery_query_*` | SHOULD | Required | Containment §9 |, | `test/ink-transport-auth.test.ts` |
|
|
230
|
+
|
|
231
|
+
---
|
|
232
|
+
|
|
233
|
+
## 14. Interoperability Profiles
|
|
234
|
+
|
|
235
|
+
An implementation MAY conform to one or more of these profiles:
|
|
236
|
+
|
|
237
|
+
### 14.1 Sender-Only
|
|
238
|
+
|
|
239
|
+
Minimum requirements: S1–S8, R1–R4, M1–M4, D1–D3, ER1–ER6
|
|
240
|
+
|
|
241
|
+
Can send INK messages and verify responses but does not accept inbound messages.
|
|
242
|
+
|
|
243
|
+
### 14.2 Receiver-Only
|
|
244
|
+
|
|
245
|
+
Minimum requirements: S1–S8, R1–R5, M1–M4, D1–D3, H1–H6, ER1–ER9
|
|
246
|
+
|
|
247
|
+
Can receive and verify INK messages but does not initiate.
|
|
248
|
+
|
|
249
|
+
### 14.3 Full Peer
|
|
250
|
+
|
|
251
|
+
All required items from sections 1–6 and 10–12.
|
|
252
|
+
|
|
253
|
+
### 14.4 Audit-Capable Peer
|
|
254
|
+
|
|
255
|
+
Full peer requirements plus sections 7–8.
|
|
256
|
+
|
|
257
|
+
### 14.5 Witness Service
|
|
258
|
+
|
|
259
|
+
Sections 2 (S1–S8) and 9 (W1–W8). Does not need to implement message envelope or handshake.
|
|
260
|
+
|
|
261
|
+
---
|
|
262
|
+
|
|
263
|
+
### 14.6 Containment-Hardened Peer
|
|
264
|
+
|
|
265
|
+
Full peer requirements plus section 13 (CT1–CT16). Adds transport scoping, discovery gating and handshake budgets.
|
|
266
|
+
|
|
267
|
+
---
|
|
268
|
+
|
|
269
|
+
## 16. Test Vector Coverage Matrix
|
|
270
|
+
|
|
271
|
+
| Vector File | Sections Covered | Vector Count |
|
|
272
|
+
|-------------|-----------------|--------------|
|
|
273
|
+
| `keys.json` | Fixed key material for all vectors |, |
|
|
274
|
+
| `signing.json` | S1–S8 | 3 |
|
|
275
|
+
| `encryption.json` | E1–E6 | 2 |
|
|
276
|
+
| `jcs.json` | S6, M4 | 4 |
|
|
277
|
+
| `replay.json` | R1–R4 | 6 |
|
|
278
|
+
| `receipts-and-audit.json` | RC1–RC6, A1–A6 | 4 |
|
|
279
|
+
| `handshake.json` | H1–H6, ER1, ER4–ER6 | 22 |
|
|
280
|
+
| `witness.json` | W1–W3, W7, S1–S8 | 15 |
|
|
281
|
+
| `key-rotation.json` | K1–K9, K12 | 8 |
|
|
282
|
+
|
|
283
|
+
**Total deterministic vectors:** 64
|
|
284
|
+
|
|
285
|
+
---
|
|
286
|
+
|
|
287
|
+
## 17. Implementation Status Summary
|
|
288
|
+
|
|
289
|
+
| Area | Required | Implemented | Tested | Vectors |
|
|
290
|
+
|------|----------|------------|--------|---------|
|
|
291
|
+
| Discovery | 8 | 8 | 8 | 3 |
|
|
292
|
+
| Transport Signing | 8 | 8 | 8 | 3 |
|
|
293
|
+
| Replay Protection | 5 | 5 | 5 | 6 |
|
|
294
|
+
| Encryption | 6 | 6 | 6 | 2 |
|
|
295
|
+
| Message Envelope | 4 | 4 | 4 | 3 |
|
|
296
|
+
| Handshake | 6 | 6 | 6 | 22 |
|
|
297
|
+
| Receipts | 6 | 6 | 6 | 4 |
|
|
298
|
+
| Bilateral Audit | 7 | 7 | 7 | 4 |
|
|
299
|
+
| Witness | 8 | 8 | 8 | 15 |
|
|
300
|
+
| Key Rotation | 13 | 13 | 12 | 8 |
|
|
301
|
+
| Auth Chains | 7 | 6 | 6 | 0 |
|
|
302
|
+
| Error Semantics | 14 | 14 | 14 |, |
|
|
303
|
+
| Containment | 16 | 16 | 15 | 0 |
|
|
304
|
+
| **Total** | **108** | **107** | **105** | **67** |
|
|
305
|
+
|
|
306
|
+
**Notes:**
|
|
307
|
+
- AC3 (multi-hop chains) is designed but not fully implemented, extension status
|
|
308
|
+
- K10 (90-day retention) is enforced by design (keys never deleted) but not explicitly tested with time simulation
|
|
309
|
+
- CT15 (governance block) is schema-defined but not yet tested with governance-specific assertions
|