@7h3/protocol 0.1.2 → 0.4.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/.dockerignore +19 -0
- package/.github/dependabot.yml +32 -0
- package/.github/workflows/ci.yml +31 -0
- package/.github/workflows/publish.yml +59 -0
- package/.github/workflows/scorecard.yml +37 -0
- package/7h3.example.yaml +125 -0
- package/CHANGELOG.md +92 -0
- package/CONTRIBUTING.md +82 -0
- package/Dockerfile +73 -0
- package/GOVERNANCE.md +62 -0
- package/README.md +323 -6
- package/SECURITY.md +70 -0
- package/bench-results/replay-cache-full-1777891033256.json +10 -0
- package/bench-results/replay-cache-full-1777896317488.json +10 -0
- package/bench-results/replay-cache-full-1777900993184.json +10 -0
- package/bench-results/replay-cache-full-1777901019285.json +10 -0
- package/bench-results/replay-cache-quick-1777870170126.json +10 -0
- package/bench-results/signature-profiles-quick-1775875160079.json +85 -0
- package/bench-results/signature-profiles-quick-1775983539716.json +85 -0
- package/bench-results/signature-profiles-quick-1776237913190.json +85 -0
- package/bench-results/wire-codecs-full-1777891019803.json +93 -0
- package/bench-results/wire-codecs-full-1777896260964.json +93 -0
- package/bench-results/wire-codecs-full-1777901004247.json +93 -0
- package/bench-results/wire-codecs-quick-1775972879056.json +93 -0
- package/bench-results/wire-codecs-quick-1775983541111.json +93 -0
- package/bench-results/wire-codecs-quick-1776237914299.json +93 -0
- package/bench-results/wire-codecs-quick-1777841285236.json +93 -0
- package/bench-results/wire-codecs-quick-1777841321772.json +93 -0
- package/bench-results/wire-codecs-quick-1777841330408.json +93 -0
- package/bench-results/wire-codecs-quick-1777852886082.json +93 -0
- package/bench-results/wire-codecs-quick-1777852988773.json +93 -0
- package/bench-results/wire-codecs-quick-1777870188095.json +93 -0
- package/bench-results/wire-codecs-quick-1777870263918.json +93 -0
- package/bench-results/wire-codecs-quick-1777870455034.json +93 -0
- package/bench-results/wire-codecs-quick-1778816163081.json +93 -0
- package/bench-results/wire-codecs-quick-1778843936130.json +93 -0
- package/bin/7h3.ts +385 -0
- package/conformance/7h3_v0_1.json +77 -0
- package/conformance/7h3_v0_1_binary.json +20 -0
- package/conformance/aip_v0_1_binary.json +20 -0
- package/docker-compose.yaml +77 -0
- package/docs/ADOPTION_PLAN.md +120 -0
- package/docs/AGENTS.md +77 -0
- package/docs/AIP_RFC_v0.1.md +97 -0
- package/docs/AI_DECISION_CARD.md +122 -0
- package/docs/AI_RUNTIME_POLICY.json +126 -0
- package/docs/AI_RUNTIME_POLICY.yaml +110 -0
- package/docs/BACKPRESSURE_TUNING.md +65 -0
- package/docs/BENCHMARK_CLAIM_MATRIX.md +42 -0
- package/docs/BENCHMARK_REPORT_TEMPLATE.md +169 -0
- package/docs/BINARY_CODEC_BENCH.md +23 -0
- package/docs/CLEAN_CLONE_RUNBOOK.md +36 -0
- package/docs/CLOCK_SKEW_POLICY.md +30 -0
- package/docs/DISTRIBUTED_REPLAY.md +142 -0
- package/docs/FUZZ_CAMPAIGN.md +121 -0
- package/docs/GATEWAY.md +195 -0
- package/docs/KEY_MANAGEMENT_POLICY.md +53 -0
- package/docs/KEY_REVOCATION.md +69 -0
- package/docs/MCP_WRAPPER.md +159 -0
- package/docs/MIGRATION_GUIDE.md +40 -0
- package/docs/OPERATORS.md +184 -0
- package/docs/PERF_REGRESSION_POLICY.md +34 -0
- package/docs/PROJECT_EXAMINATION_2026-05-31.md +219 -0
- package/docs/RELEASE_BENCHMARK_REPORT_2026-05-15.md +135 -0
- package/docs/RELEASE_GATE.md +25 -0
- package/docs/RELEASE_NOTES_v0.1.0.md +54 -0
- package/docs/SECURITY_REVIEW_2026-06-05.md +165 -0
- package/docs/TELEMETRY.md +41 -0
- package/docs/THREAT_MODEL.md +89 -0
- package/docs/VERSIONING_POLICY.md +30 -0
- package/docs/assets/banner.png +0 -0
- package/eslint.config.js +15 -0
- package/fuzz/ts/harness-decode.ts +136 -0
- package/fuzz/ts/harness-verify.ts +121 -0
- package/fuzz/ts/run.ts +35 -0
- package/mcp-server/README.md +38 -0
- package/mcp-server/package-lock.json +1187 -0
- package/mcp-server/package.json +35 -0
- package/mcp-server/src/index.ts +236 -0
- package/mcp-server/tsconfig.json +14 -0
- package/package.json +79 -13
- package/scripts/aip-framework-quickstart.ts +110 -0
- package/scripts/aip-mcp-gateway.ts +38 -0
- package/scripts/aip-mcp-wrap-demo.ts +72 -0
- package/scripts/aip-quickstart.ts +60 -0
- package/scripts/bench-diff.ts +118 -0
- package/scripts/bench-protocol-e2e.ts +937 -0
- package/scripts/bench-protocol-openloop.ts +1397 -0
- package/scripts/bench-replay-cache.ts +76 -0
- package/scripts/bench-signature-profiles.ts +180 -0
- package/scripts/bench-wire-codecs.ts +161 -0
- package/scripts/build-binary-conformance.ts +36 -0
- package/scripts/build-release-dashboard.ts +175 -0
- package/scripts/canary-rollout.ts +38 -0
- package/scripts/mcpGatewayCli.test.ts +116 -0
- package/scripts/prepare-aip-package.ts +88 -0
- package/scripts/regen-conformance-sigs.ts +18 -0
- package/scripts/release-gate.ts +19 -0
- package/scripts/validate-runtime-policy.ts +18 -0
- package/sdk/browser/index.test.ts +162 -0
- package/sdk/browser/index.ts +257 -0
- package/sdk/browser/package.json +13 -0
- package/sdk/go/go.mod +3 -0
- package/sdk/go/http.go +135 -0
- package/sdk/go/protocol.go +324 -0
- package/sdk/go/protocol_test.go +334 -0
- package/sdk/go/webhook.go +136 -0
- package/sdk/python/README.md +18 -0
- package/sdk/python/protocol_7h3/__init__.py +46 -0
- package/sdk/python/protocol_7h3/http.py +212 -0
- package/sdk/python/protocol_7h3/keys.py +149 -0
- package/sdk/python/protocol_7h3/protocol.py +525 -0
- package/sdk/python/protocol_7h3/queue.py +118 -0
- package/sdk/python/protocol_7h3/webhook.py +116 -0
- package/sdk/python/pyproject.toml +40 -0
- package/sdk/python/tests/test_conformance.py +110 -0
- package/sdk/python/tests/test_http.py +305 -0
- package/sdk/python/tests/test_keys.py +417 -0
- package/sdk/python/tests/test_queue.py +120 -0
- package/sdk/python/tests/test_webhook.py +345 -0
- package/sdk/rust/Cargo.lock +371 -0
- package/sdk/rust/Cargo.toml +25 -0
- package/sdk/rust/README.md +31 -0
- package/sdk/rust/fuzz/Cargo.toml +29 -0
- package/sdk/rust/fuzz/fuzz_targets/fuzz_canonicalize.rs +46 -0
- package/sdk/rust/fuzz/fuzz_targets/fuzz_decode.rs +11 -0
- package/sdk/rust/src/bin/aip_mcp_gateway.rs +59 -0
- package/sdk/rust/src/http.rs +145 -0
- package/sdk/rust/src/keys.rs +161 -0
- package/sdk/rust/src/lib.rs +688 -0
- package/sdk/rust/src/queue.rs +79 -0
- package/sdk/rust/src/webhook.rs +86 -0
- package/sdk/rust/tests/conformance.rs +148 -0
- package/sdk/rust/tests/gateway.rs +130 -0
- package/sdk/rust/tests/http_webhook_queue.rs +201 -0
- package/sdk/rust/tests/keys.rs +189 -0
- package/src/agentAdapter.test.ts +48 -0
- package/src/agentAdapter.ts +56 -0
- package/src/auditLog.test.ts +145 -0
- package/src/auditLog.ts +147 -0
- package/src/conformance.test.ts +136 -0
- package/src/conformanceVectors.ts +99 -0
- package/src/frameworkAdapters.test.ts +290 -0
- package/src/frameworkAdapters.ts +261 -0
- package/src/gateway.test.ts +343 -0
- package/src/gateway.ts +171 -0
- package/src/grpcBinding.test.ts +211 -0
- package/src/grpcBinding.ts +103 -0
- package/src/httpBinding.test.ts +376 -0
- package/src/httpBinding.ts +163 -0
- package/src/index.ts +32 -0
- package/src/keyInfra.test.ts +278 -0
- package/src/keyInfra.ts +228 -0
- package/src/keyRegistry.ts +59 -0
- package/src/keyRotation.test.ts +78 -0
- package/src/keyRotation.ts +72 -0
- package/src/mcpGateway.test.ts +129 -0
- package/src/mcpGateway.ts +250 -0
- package/src/mcpTransports.test.ts +92 -0
- package/src/mcpTransports.ts +169 -0
- package/src/mcpWrapper.test.ts +179 -0
- package/src/mcpWrapper.ts +206 -0
- package/src/policyEnforcer.test.ts +99 -0
- package/src/policyEnforcer.ts +169 -0
- package/src/policyTelemetryFeedback.test.ts +25 -0
- package/src/policyTelemetryFeedback.ts +38 -0
- package/src/protocol.bench.ts +37 -0
- package/src/protocol.test.ts +155 -0
- package/src/protocol.ts +413 -0
- package/src/protocolAgent.test.ts +105 -0
- package/src/protocolAgent.ts +169 -0
- package/src/protocolBinary.test.ts +165 -0
- package/src/protocolBinary.ts +312 -0
- package/src/protocolCapabilities.ts +70 -0
- package/src/protocolFuzz.advanced.test.ts +235 -0
- package/src/protocolFuzz.test.ts +111 -0
- package/src/protocolNegative.test.ts +97 -0
- package/src/protocolReplay.test.ts +71 -0
- package/src/protocolReplay.ts +194 -0
- package/src/protocolTransport.test.ts +556 -0
- package/src/protocolTransport.ts +483 -0
- package/src/queueBinding.test.ts +130 -0
- package/src/queueBinding.ts +102 -0
- package/src/rateLimiter.test.ts +96 -0
- package/src/rateLimiter.ts +46 -0
- package/src/redisClient.ts +140 -0
- package/src/redisIntegration.test.ts +134 -0
- package/src/replayStores.test.ts +141 -0
- package/src/replayStores.ts +82 -0
- package/src/revocation.test.ts +98 -0
- package/src/revocation.ts +0 -0
- package/src/routePolicy.test.ts +87 -0
- package/src/routePolicy.ts +72 -0
- package/src/runtimePolicy.test.ts +49 -0
- package/src/runtimePolicy.ts +81 -0
- package/src/runtimePolicyManager.test.ts +29 -0
- package/src/runtimePolicyManager.ts +50 -0
- package/src/runtimePolicyPresets.ts +43 -0
- package/src/signedResponse.test.ts +111 -0
- package/src/signedResponse.ts +83 -0
- package/src/webhookBinding.test.ts +144 -0
- package/src/webhookBinding.ts +115 -0
- package/src/wsBinding.test.ts +221 -0
- package/src/wsBinding.ts +100 -0
- package/tsconfig.json +15 -0
- package/tsconfig.lib.json +23 -0
- package/vite.lib.config.ts +16 -0
- package/agentAdapter.d.ts +0 -26
- package/conformanceVectors.d.ts +0 -20
- package/frameworkAdapters.d.ts +0 -72
- package/index.d.ts +0 -20
- package/index.js +0 -1702
- package/keyRotation.d.ts +0 -20
- package/mcpGateway.d.ts +0 -37
- package/mcpTransports.d.ts +0 -62
- package/mcpWrapper.d.ts +0 -83
- package/policyEnforcer.d.ts +0 -50
- package/policyTelemetryFeedback.d.ts +0 -11
- package/protocol.d.ts +0 -66
- package/protocolAgent.d.ts +0 -58
- package/protocolBinary.d.ts +0 -8
- package/protocolCapabilities.d.ts +0 -24
- package/protocolReplay.d.ts +0 -35
- package/protocolTransport.d.ts +0 -73
- package/redisClient.d.ts +0 -49
- package/replayStores.d.ts +0 -32
- package/revocation.d.ts +0 -71
- package/runtimePolicy.d.ts +0 -24
- package/runtimePolicyManager.d.ts +0 -15
- package/runtimePolicyPresets.d.ts +0 -11
package/README.md
CHANGED
|
@@ -1,16 +1,333 @@
|
|
|
1
|
-
|
|
1
|
+
<div align="center">
|
|
2
|
+
<img src="./docs/assets/banner.png" alt="@7h3/protocol — AIP: Sign every message. Reject every replay." width="100%">
|
|
2
3
|
|
|
3
|
-
|
|
4
|
-
deterministic, signed, replay-safe AI-to-AI message envelopes.
|
|
4
|
+
<br/><br/>
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
[](https://www.npmjs.com/package/@7h3/protocol)
|
|
7
|
+
[](https://www.npmjs.com/package/@7h3/protocol-mcp)
|
|
8
|
+
[](https://pypi.org/project/aip7h3/)
|
|
9
|
+
[](https://crates.io/crates/aip7h3)
|
|
10
|
+
[](https://github.com/IceMasterT/7h3-protocol-aip/tree/main/src)
|
|
11
|
+
[](./package.json)
|
|
12
|
+
[](./tsconfig.json)
|
|
13
|
+
[](./LICENSE)
|
|
14
|
+
[](./docs/VERSIONING_POLICY.md)
|
|
15
|
+
|
|
16
|
+
<br/>
|
|
17
|
+
|
|
18
|
+
**The signing-and-replay layer your agent protocol forgot.**
|
|
19
|
+
|
|
20
|
+
<br/>
|
|
21
|
+
</div>
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Why it exists
|
|
26
|
+
|
|
27
|
+
The dominant agent protocols ship messages unsigned:
|
|
28
|
+
|
|
29
|
+
- **MCP** uses plain JSON-RPC 2.0 — no signatures, no replay protection. Parameters can be altered in transit; valid messages can be replayed indefinitely.
|
|
30
|
+
- **A2A** signs *Agent Cards* for domain identity — but not the per-message task traffic.
|
|
31
|
+
|
|
32
|
+
AIP fills exactly that gap. It is a hardening envelope you put *around* MCP or A2A traffic — not a competitor to them. Every message gets signed, TTL-bounded, and replay-checked before it reaches your handler.
|
|
33
|
+
|
|
34
|
+
Use it when agents trigger real side effects (writes, payments, tool calls) and you need tamper-evidence, replay-safety, and auditability.
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## Guarantees
|
|
39
|
+
|
|
40
|
+
| Property | Mechanism |
|
|
41
|
+
|---|---|
|
|
42
|
+
| **Authentic** | HMAC-SHA256 (HS256) or Ed25519 over a canonical payload — real WebCrypto, no hand-rolled crypto |
|
|
43
|
+
| **Deterministic** | Fixed-key-order canonicalization; signatures match byte-for-byte across TS / Python / Rust |
|
|
44
|
+
| **Replay-resistant** | `(sender, messageId, nonce)` uniqueness window + TTL / clock-skew enforcement |
|
|
45
|
+
| **Polyglot** | Shared conformance fixture set (`conformance/aip_v0_1.json`) proves parity across all three runtimes |
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## Install
|
|
7
50
|
|
|
8
51
|
```bash
|
|
9
52
|
npm install @7h3/protocol
|
|
10
53
|
```
|
|
11
54
|
|
|
12
|
-
|
|
55
|
+
Python and Rust SDKs live under `sdk/python` (`from aip7h3 import …`) and `sdk/rust` (`use aip7h3::…`).
|
|
56
|
+
|
|
57
|
+
### MCP server (for Claude Code / Claude Desktop)
|
|
58
|
+
|
|
59
|
+
The companion `@7h3/protocol-mcp` package installs five tools into your AI assistant for generating secrets, keypairs, and boilerplate.
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
# Claude Code
|
|
63
|
+
claude mcp add aip -- npx @7h3/protocol-mcp
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
```json
|
|
67
|
+
// Claude Desktop — claude_desktop_config.json
|
|
68
|
+
{
|
|
69
|
+
"mcpServers": {
|
|
70
|
+
"aip": { "command": "npx", "args": ["@7h3/protocol-mcp"] }
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
| Tool | What it does |
|
|
76
|
+
|---|---|
|
|
77
|
+
| `aip_generate_secret` | 32-byte HMAC secret → `AIP_SECRET` |
|
|
78
|
+
| `aip_generate_keypair` | Ed25519 keypair → env vars |
|
|
79
|
+
| `aip_wrap_mcp_server` | Ready-to-paste boilerplate for your MCP server |
|
|
80
|
+
| `aip_sign` | Sign a test envelope (debugging / fixture generation) |
|
|
81
|
+
| `aip_verify` | Verify an envelope's signature and shape |
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## Quick start
|
|
86
|
+
|
|
87
|
+
### HMAC (shared secret — simplest path)
|
|
13
88
|
|
|
14
89
|
```ts
|
|
15
|
-
import {
|
|
90
|
+
import {
|
|
91
|
+
createEnvelope, signEnvelopeHmac, verifyEnvelopeHmac, validateEnvelope,
|
|
92
|
+
} from '@7h3/protocol'
|
|
93
|
+
|
|
94
|
+
const secret = 'shared-secret'
|
|
95
|
+
const envelope = await signEnvelopeHmac(
|
|
96
|
+
createEnvelope({ sender: 'planner', recipient: 'worker', intent: 'TASK', content: 'do-the-thing' }),
|
|
97
|
+
secret,
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
const diagnostics = validateEnvelope(envelope) // shape / TTL / version checks
|
|
101
|
+
const ok = await verifyEnvelopeHmac(envelope, secret) // tamper + auth check
|
|
102
|
+
// → replay-check downstream via your transport's replay cache
|
|
16
103
|
```
|
|
104
|
+
|
|
105
|
+
### Ed25519 (asymmetric — production recommendation)
|
|
106
|
+
|
|
107
|
+
> **Why Ed25519?** HMAC is a shared secret — any peer that can verify can also forge. Ed25519 is asymmetric: you sign with a private key, peers verify with your public key only. Compromising a peer does not compromise your signing key.
|
|
108
|
+
|
|
109
|
+
```ts
|
|
110
|
+
import {
|
|
111
|
+
generateEd25519KeypairBase64Url, createEnvelope,
|
|
112
|
+
signEnvelopeEd25519, verifyEnvelopeEd25519,
|
|
113
|
+
} from '@7h3/protocol'
|
|
114
|
+
|
|
115
|
+
const { privateKey, publicKey } = await generateEd25519KeypairBase64Url()
|
|
116
|
+
const envelope = await signEnvelopeEd25519(
|
|
117
|
+
createEnvelope({ sender: 'planner', recipient: 'worker', intent: 'TASK', content: 'do-the-thing' }),
|
|
118
|
+
privateKey, 'k1',
|
|
119
|
+
)
|
|
120
|
+
const ok = await verifyEnvelopeEd25519(envelope, publicKey)
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
## MCP hardening wrapper
|
|
126
|
+
|
|
127
|
+
Wrap any existing MCP server or client — handler signature does not change:
|
|
128
|
+
|
|
129
|
+
```ts
|
|
130
|
+
import { wrapMcpServer, wrapMcpClient, signEnvelopeEd25519 } from '@7h3/protocol'
|
|
131
|
+
|
|
132
|
+
// Server side
|
|
133
|
+
const secureServer = wrapMcpServer(myMcpHandler, {
|
|
134
|
+
selfAgentId: 'my-server',
|
|
135
|
+
sign: (e) => signEnvelopeEd25519(e, serverPrivateKey, 'k1'),
|
|
136
|
+
})
|
|
137
|
+
|
|
138
|
+
// Client side
|
|
139
|
+
const { send } = wrapMcpClient({
|
|
140
|
+
selfAgentId: 'my-client',
|
|
141
|
+
peerAgentId: 'my-server',
|
|
142
|
+
sign: (e) => signEnvelopeEd25519(e, clientPrivateKey, 'k1'),
|
|
143
|
+
receive: { signatureResolver: async ({ keyId }) => ({ alg: 'ED25519', publicKey: serverPublicKey }) },
|
|
144
|
+
})
|
|
145
|
+
const response = await send({ jsonrpc: '2.0', id: 1, method: 'tools/list' }, fetch)
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
The wrapper enforces four bindings beyond signature verification:
|
|
149
|
+
|
|
150
|
+
| Binding | Attack defeated |
|
|
151
|
+
|---|---|
|
|
152
|
+
| **Recipient** | Server rejects envelopes not addressed to `selfAgentId` — cross-server relay |
|
|
153
|
+
| **Sender** | Client accepts responses only from `peerAgentId` — response spoofing |
|
|
154
|
+
| **Correlation** | Client enforces `correlationId === request messageId` — response substitution |
|
|
155
|
+
| **Replay** | `InMemoryReplayCache` injected by default — replay of prior requests |
|
|
156
|
+
|
|
157
|
+
Demo: `npm run aip:mcp:wrap`
|
|
158
|
+
|
|
159
|
+
---
|
|
160
|
+
|
|
161
|
+
## Wire formats
|
|
162
|
+
|
|
163
|
+
Three formats — choose by context:
|
|
164
|
+
|
|
165
|
+
| Format | Use case |
|
|
166
|
+
|---|---|
|
|
167
|
+
| `json` | Human-readable, debug-friendly |
|
|
168
|
+
| `compact` | Minified JSON — smaller over HTTP |
|
|
169
|
+
| `binary` | MessagePack (magic `AIPB`) — highest throughput, lowest parse overhead |
|
|
170
|
+
|
|
171
|
+
```ts
|
|
172
|
+
import { encodeEnvelope, decodeEnvelope } from '@7h3/protocol'
|
|
173
|
+
|
|
174
|
+
const wire = encodeEnvelope(envelope, 'binary') // Uint8Array
|
|
175
|
+
const back = decodeEnvelope(wire) // ProtocolEnvelope
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
## Distributed replay store (Redis)
|
|
181
|
+
|
|
182
|
+
Production deployments need a shared replay store across agent instances:
|
|
183
|
+
|
|
184
|
+
```ts
|
|
185
|
+
import { createRedisReplayStore, DistributedReplayCache } from '@7h3/protocol'
|
|
186
|
+
|
|
187
|
+
const store = createRedisReplayStore(redisClient, {
|
|
188
|
+
errorBehavior: 'fallback', // degrade to local store on Redis outage — never silent
|
|
189
|
+
onDegraded: (err) => telemetry.error('replay-store-degraded', err),
|
|
190
|
+
})
|
|
191
|
+
const replayCache = new DistributedReplayCache(store)
|
|
192
|
+
|
|
193
|
+
// Pass replayCache into receiveEnvelope or wrapMcpServer/wrapMcpClient
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
- Atomic `SET NX PX` reserve — no double-processing under concurrent writes
|
|
197
|
+
- `reserveMany` batch pipeline — low overhead for high-volume handlers
|
|
198
|
+
- `errorBehavior: 'fallback' | 'reject' | 'allow'` — operator controls degradation posture
|
|
199
|
+
- See `docs/DISTRIBUTED_REPLAY.md`
|
|
200
|
+
|
|
201
|
+
---
|
|
202
|
+
|
|
203
|
+
## Fleet-wide key revocation
|
|
204
|
+
|
|
205
|
+
```ts
|
|
206
|
+
import { createRedisRevocationStore, withRevocationCheck } from '@7h3/protocol'
|
|
207
|
+
|
|
208
|
+
const revocationStore = createRedisRevocationStore(redisClient) // fail-closed default
|
|
209
|
+
const secureResolver = withRevocationCheck(mySignatureResolver, revocationStore)
|
|
210
|
+
// Revoked key → resolver returns undefined → verification fails
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
- Cached reads (5 s TTL by default) — low overhead on the verify hot path
|
|
214
|
+
- Fail-closed default: Redis outage → reject, not allow
|
|
215
|
+
- See `docs/KEY_REVOCATION.md`
|
|
216
|
+
|
|
217
|
+
---
|
|
218
|
+
|
|
219
|
+
## Transport adapters
|
|
220
|
+
|
|
221
|
+
Zero new runtime dependencies — only Node built-ins and global `fetch`:
|
|
222
|
+
|
|
223
|
+
```ts
|
|
224
|
+
import { serveMcpOverStdio, createStdioMcpClient } from '@7h3/protocol'
|
|
225
|
+
import { createHttpMcpHandler, createHttpMcpClient } from '@7h3/protocol'
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
| Adapter | Notes |
|
|
229
|
+
|---|---|
|
|
230
|
+
| `serveMcpOverStdio` + `createStdioMcpClient` | Newline-delimited; in-order sequential chain prevents response interleaving |
|
|
231
|
+
| `createHttpMcpHandler` + `createHttpMcpClient` | `node:http` handler + `fetch` client; supports `binary` wire format |
|
|
232
|
+
|
|
233
|
+
---
|
|
234
|
+
|
|
235
|
+
## Framework adapters
|
|
236
|
+
|
|
237
|
+
LangChain, LlamaIndex, and JSON-RPC bridge adapters wrap `AipAgentAdapter` to translate between AIP envelopes and framework-native message types:
|
|
238
|
+
|
|
239
|
+
```ts
|
|
240
|
+
import { LangChainAipAdapter, LlamaIndexAipAdapter, JsonRpcBridge } from '@7h3/protocol'
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
---
|
|
244
|
+
|
|
245
|
+
## Policy and telemetry
|
|
246
|
+
|
|
247
|
+
Runtime policy controls transport behavior, retry, rate limits, and safety invariants — loaded from `AI_RUNTIME_POLICY.yaml` or inline:
|
|
248
|
+
|
|
249
|
+
```ts
|
|
250
|
+
import { loadRuntimePolicy, validateRuntimePolicy, PolicyEnforcer } from '@7h3/protocol'
|
|
251
|
+
|
|
252
|
+
const policy = await loadRuntimePolicy({ path: './AI_RUNTIME_POLICY.yaml' })
|
|
253
|
+
const enforcer = new PolicyEnforcer(policy)
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
See `docs/TELEMETRY.md`, `docs/AI_DECISION_CARD.md`, `docs/OPERATORS.md`.
|
|
257
|
+
|
|
258
|
+
---
|
|
259
|
+
|
|
260
|
+
## Polyglot parity
|
|
261
|
+
|
|
262
|
+
All three SDKs are driven by the same conformance fixture set at `conformance/aip_v0_1.json`. Signatures verified against known vectors in all three runtimes:
|
|
263
|
+
|
|
264
|
+
```bash
|
|
265
|
+
npm test # TypeScript (131 tests / 23 files)
|
|
266
|
+
npm run conformance:python # Python unittest
|
|
267
|
+
npm run conformance:rust # Rust cargo test (7 tests)
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
---
|
|
271
|
+
|
|
272
|
+
## Status
|
|
273
|
+
|
|
274
|
+
**Version: 0.1.2** · Wire protocol: `aip/0.1`
|
|
275
|
+
|
|
276
|
+
| What | Status |
|
|
277
|
+
|---|---|
|
|
278
|
+
| Core test suite | ✅ 131 tests / 23 files — all green |
|
|
279
|
+
| Cryptography | ✅ Real WebCrypto — HMAC-SHA256 + Ed25519 (no hand-rolled crypto) |
|
|
280
|
+
| Deterministic canonicalization | ✅ Fixed key order; byte-identical across runtimes |
|
|
281
|
+
| TS/Python/Rust parity | ✅ Shared conformance fixtures; all pass |
|
|
282
|
+
| Distributed replay (Redis) | ✅ Atomic `SET NX PX`; batch pipeline; graceful degradation |
|
|
283
|
+
| Fleet-wide revocation (Redis) | ✅ Fail-closed; cached reads; stale-serve during outage |
|
|
284
|
+
| MCP hardening wrapper | ✅ 4 bindings; all independently tested |
|
|
285
|
+
| Property-based fuzz tests | ✅ 8 properties via fast-check (wire decoder, canonicalization, replay) |
|
|
286
|
+
| Live-Redis integration test | ✅ Auto-skips if no server present — no false passes |
|
|
287
|
+
| Formal fuzz campaign | ✅ TypeScript mutation harnesses run clean (50k/20k rounds, 0 crashes); Rust targets built and run (4.9M iterations, no panics in `canonicalize_envelope`/`decode_envelope`) — see [`docs/FUZZ_CAMPAIGN.md`](./docs/FUZZ_CAMPAIGN.md) |
|
|
288
|
+
| Independent security audit | ⚠️ Not yet performed by an external reviewer — internal AI-assisted review completed 2026-06-05, 2 bugs found and fixed (see [`docs/SECURITY_REVIEW_2026-06-05.md`](./docs/SECURITY_REVIEW_2026-06-05.md)); cryptographic primitives are standard WebCrypto; parsing/replay/canonicalization logic remains unaudited by a qualified third party |
|
|
289
|
+
| Python Ed25519 | ✅ Pure-Python fallback — no external packages required; tries `cryptography` → `PyNaCl` → pure Python in order |
|
|
290
|
+
| Rust crates.io publish | ✅ Metadata complete; `cargo publish --dry-run` passes — publish with `cargo publish` when ready |
|
|
291
|
+
| Redis HA | ✅ Sentinel, Cluster, and Upstash adapter patterns documented in [`docs/DISTRIBUTED_REPLAY.md`](./docs/DISTRIBUTED_REPLAY.md) |
|
|
292
|
+
|
|
293
|
+
---
|
|
294
|
+
|
|
295
|
+
## Docs
|
|
296
|
+
|
|
297
|
+
| Document | Contents |
|
|
298
|
+
|---|---|
|
|
299
|
+
| [`docs/THREAT_MODEL.md`](./docs/THREAT_MODEL.md) | Full threat coverage matrix |
|
|
300
|
+
| [`docs/MCP_WRAPPER.md`](./docs/MCP_WRAPPER.md) | MCP wrapper usage, transport examples, HMAC vs Ed25519 comparison |
|
|
301
|
+
| [`docs/DISTRIBUTED_REPLAY.md`](./docs/DISTRIBUTED_REPLAY.md) | Redis store setup, `errorBehavior` table, ops guidance |
|
|
302
|
+
| [`docs/KEY_REVOCATION.md`](./docs/KEY_REVOCATION.md) | Revocation store setup, cache TTL tuning |
|
|
303
|
+
| [`docs/KEY_MANAGEMENT_POLICY.md`](./docs/KEY_MANAGEMENT_POLICY.md) | Key lifecycle and rotation policy |
|
|
304
|
+
| [`docs/CLOCK_SKEW_POLICY.md`](./docs/CLOCK_SKEW_POLICY.md) | Clock sync requirements |
|
|
305
|
+
| [`docs/VERSIONING_POLICY.md`](./docs/VERSIONING_POLICY.md) | Wire freeze guarantees, semver policy |
|
|
306
|
+
| [`docs/MIGRATION_GUIDE.md`](./docs/MIGRATION_GUIDE.md) | Breaking-change upgrade paths |
|
|
307
|
+
| [`docs/OPERATORS.md`](./docs/OPERATORS.md) | Deployment and operations reference |
|
|
308
|
+
| [`docs/TELEMETRY.md`](./docs/TELEMETRY.md) | Telemetry hooks and observability |
|
|
309
|
+
| [`docs/SECURITY_REVIEW_2026-06-05.md`](./docs/SECURITY_REVIEW_2026-06-05.md) | AI-assisted internal security review — findings, fixes, positive findings |
|
|
310
|
+
| [`docs/PROJECT_EXAMINATION_2026-05-31.md`](./docs/PROJECT_EXAMINATION_2026-05-31.md) | Independent examination — verified vs asserted |
|
|
311
|
+
| [`CHANGELOG.md`](./CHANGELOG.md) | Full version history |
|
|
312
|
+
|
|
313
|
+
---
|
|
314
|
+
|
|
315
|
+
## Security
|
|
316
|
+
|
|
317
|
+
Report vulnerabilities via the coordinated disclosure process in [`SECURITY.md`](./SECURITY.md). **Do not open a public issue for security findings.** 48-hour acknowledgement SLA; 14-day critical patch SLA.
|
|
318
|
+
|
|
319
|
+
The cryptographic primitives are standard (WebCrypto Ed25519 / HMAC-SHA256). The envelope parsing, canonicalization, and replay-cache logic have not been formally audited. No independent security audit has been performed. Treat accordingly in high-stakes deployments.
|
|
320
|
+
|
|
321
|
+
---
|
|
322
|
+
|
|
323
|
+
## Contributing
|
|
324
|
+
|
|
325
|
+
See [`CONTRIBUTING.md`](./CONTRIBUTING.md) — test commands, wire-freeze policy, conformance fixture update requirement, and PR workflow.
|
|
326
|
+
|
|
327
|
+
## Governance
|
|
328
|
+
|
|
329
|
+
See [`GOVERNANCE.md`](./GOVERNANCE.md) — single-maintainer stage, decision process, co-maintainership path (LF Minimum Viable Governance style).
|
|
330
|
+
|
|
331
|
+
## License
|
|
332
|
+
|
|
333
|
+
MIT
|
package/SECURITY.md
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# Security Policy
|
|
2
|
+
|
|
3
|
+
## Reporting a Vulnerability
|
|
4
|
+
|
|
5
|
+
Please do not open a GitHub Issue for security findings. Use coordinated disclosure instead.
|
|
6
|
+
|
|
7
|
+
**Send private reports to:** tech@mysms.promo
|
|
8
|
+
**Subject line:** `[AIP Security] <brief description>`
|
|
9
|
+
|
|
10
|
+
### What to include
|
|
11
|
+
|
|
12
|
+
A useful report contains:
|
|
13
|
+
|
|
14
|
+
- A clear description of the vulnerability and which component it affects
|
|
15
|
+
- Steps to reproduce, ideally as a minimal test case or fixture
|
|
16
|
+
- Your assessment of the impact (confidentiality, integrity, availability, scope)
|
|
17
|
+
- The affected versions (check `package.json` version and the wire version `aip/0.1`)
|
|
18
|
+
- Any suggested fix or mitigation you have in mind (optional but appreciated)
|
|
19
|
+
|
|
20
|
+
Reports that include a conformance vector demonstrating the issue are especially
|
|
21
|
+
helpful and make the triage process faster.
|
|
22
|
+
|
|
23
|
+
## Response Timeline
|
|
24
|
+
|
|
25
|
+
| Event | Target |
|
|
26
|
+
|---|---|
|
|
27
|
+
| Acknowledgement | 48 hours |
|
|
28
|
+
| Triage and severity assignment | 5 business days |
|
|
29
|
+
| Patch for critical/high severity | 14 days from confirmation |
|
|
30
|
+
| Patch for medium/low severity | 60 days from confirmation |
|
|
31
|
+
| Public disclosure | After patch is released and verified |
|
|
32
|
+
|
|
33
|
+
We ask that reporters hold off on public disclosure until a patch is available.
|
|
34
|
+
If the 14-day critical window is going to slip, we will contact you to agree on
|
|
35
|
+
an extended timeline or coordinated partial disclosure.
|
|
36
|
+
|
|
37
|
+
## Scope
|
|
38
|
+
|
|
39
|
+
The following are in scope:
|
|
40
|
+
|
|
41
|
+
- Envelope signing and verification (`src/aip/`)
|
|
42
|
+
- Canonicalization logic and determinism guarantees
|
|
43
|
+
- Replay-safety (nonce and timestamp validation)
|
|
44
|
+
- Wire format parsing in all three runtimes (TypeScript, Python, Rust)
|
|
45
|
+
- Intent vocabulary validation
|
|
46
|
+
|
|
47
|
+
Out of scope: third-party dependencies (report those upstream), benchmark
|
|
48
|
+
scripts, and documentation typos.
|
|
49
|
+
|
|
50
|
+
## Audit Status
|
|
51
|
+
|
|
52
|
+
No independent third-party security audit has been performed on this codebase
|
|
53
|
+
as of the current release. The protocol design has been reviewed by the
|
|
54
|
+
maintainer against known attack classes for signed messaging systems, but that
|
|
55
|
+
is not a substitute for a formal audit. Reproductions of conformance vectors
|
|
56
|
+
that reveal edge-case signing or deserialization behavior are welcome and
|
|
57
|
+
treated as high-value contributions.
|
|
58
|
+
|
|
59
|
+
## Hall of Thanks
|
|
60
|
+
|
|
61
|
+
Researchers who report valid, confirmed vulnerabilities will be acknowledged
|
|
62
|
+
here (with their permission).
|
|
63
|
+
|
|
64
|
+
_No entries yet._
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
Maintainer: [@IceMasterT](https://github.com/IceMasterT)
|
|
69
|
+
Package: `@7h3/protocol`
|
|
70
|
+
License: MIT
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
{
|
|
2
|
+
"generatedAt": "2026-04-11T02:39:20.079Z",
|
|
3
|
+
"profile": "quick",
|
|
4
|
+
"iterations": 2000,
|
|
5
|
+
"payloadSizes": [
|
|
6
|
+
256,
|
|
7
|
+
1024,
|
|
8
|
+
4096,
|
|
9
|
+
16384
|
|
10
|
+
],
|
|
11
|
+
"results": [
|
|
12
|
+
{
|
|
13
|
+
"profile": "quick",
|
|
14
|
+
"payloadBytes": 256,
|
|
15
|
+
"algorithm": "HS256",
|
|
16
|
+
"signUsPerOp": 16.5,
|
|
17
|
+
"verifyUsPerOp": 14.176,
|
|
18
|
+
"signOpsPerSecond": 60606.367,
|
|
19
|
+
"verifyOpsPerSecond": 70539.362
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"profile": "quick",
|
|
23
|
+
"payloadBytes": 256,
|
|
24
|
+
"algorithm": "ED25519",
|
|
25
|
+
"signUsPerOp": 45.6,
|
|
26
|
+
"verifyUsPerOp": 119.231,
|
|
27
|
+
"signOpsPerSecond": 21929.753,
|
|
28
|
+
"verifyOpsPerSecond": 8387.068
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"profile": "quick",
|
|
32
|
+
"payloadBytes": 1024,
|
|
33
|
+
"algorithm": "HS256",
|
|
34
|
+
"signUsPerOp": 23.745,
|
|
35
|
+
"verifyUsPerOp": 18.396,
|
|
36
|
+
"signOpsPerSecond": 42113.324,
|
|
37
|
+
"verifyOpsPerSecond": 54360.747
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
"profile": "quick",
|
|
41
|
+
"payloadBytes": 1024,
|
|
42
|
+
"algorithm": "ED25519",
|
|
43
|
+
"signUsPerOp": 51.284,
|
|
44
|
+
"verifyUsPerOp": 106.092,
|
|
45
|
+
"signOpsPerSecond": 19499.138,
|
|
46
|
+
"verifyOpsPerSecond": 9425.777
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"profile": "quick",
|
|
50
|
+
"payloadBytes": 4096,
|
|
51
|
+
"algorithm": "HS256",
|
|
52
|
+
"signUsPerOp": 18.235,
|
|
53
|
+
"verifyUsPerOp": 20.365,
|
|
54
|
+
"signOpsPerSecond": 54839.636,
|
|
55
|
+
"verifyOpsPerSecond": 49103.017
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
"profile": "quick",
|
|
59
|
+
"payloadBytes": 4096,
|
|
60
|
+
"algorithm": "ED25519",
|
|
61
|
+
"signUsPerOp": 53.216,
|
|
62
|
+
"verifyUsPerOp": 101.756,
|
|
63
|
+
"signOpsPerSecond": 18791.24,
|
|
64
|
+
"verifyOpsPerSecond": 9827.469
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
"profile": "quick",
|
|
68
|
+
"payloadBytes": 16384,
|
|
69
|
+
"algorithm": "HS256",
|
|
70
|
+
"signUsPerOp": 33.59,
|
|
71
|
+
"verifyUsPerOp": 32.805,
|
|
72
|
+
"signOpsPerSecond": 29770.829,
|
|
73
|
+
"verifyOpsPerSecond": 30483.215
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
"profile": "quick",
|
|
77
|
+
"payloadBytes": 16384,
|
|
78
|
+
"algorithm": "ED25519",
|
|
79
|
+
"signUsPerOp": 96.924,
|
|
80
|
+
"verifyUsPerOp": 141.141,
|
|
81
|
+
"signOpsPerSecond": 10317.338,
|
|
82
|
+
"verifyOpsPerSecond": 7085.133
|
|
83
|
+
}
|
|
84
|
+
]
|
|
85
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
{
|
|
2
|
+
"generatedAt": "2026-04-12T08:45:39.716Z",
|
|
3
|
+
"profile": "quick",
|
|
4
|
+
"iterations": 2000,
|
|
5
|
+
"payloadSizes": [
|
|
6
|
+
256,
|
|
7
|
+
1024,
|
|
8
|
+
4096,
|
|
9
|
+
16384
|
|
10
|
+
],
|
|
11
|
+
"results": [
|
|
12
|
+
{
|
|
13
|
+
"profile": "quick",
|
|
14
|
+
"payloadBytes": 256,
|
|
15
|
+
"algorithm": "HS256",
|
|
16
|
+
"signUsPerOp": 17.09,
|
|
17
|
+
"verifyUsPerOp": 16.676,
|
|
18
|
+
"signOpsPerSecond": 58514.475,
|
|
19
|
+
"verifyOpsPerSecond": 59965.552
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"profile": "quick",
|
|
23
|
+
"payloadBytes": 256,
|
|
24
|
+
"algorithm": "ED25519",
|
|
25
|
+
"signUsPerOp": 48.942,
|
|
26
|
+
"verifyUsPerOp": 129.521,
|
|
27
|
+
"signOpsPerSecond": 20432.528,
|
|
28
|
+
"verifyOpsPerSecond": 7720.783
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"profile": "quick",
|
|
32
|
+
"payloadBytes": 1024,
|
|
33
|
+
"algorithm": "HS256",
|
|
34
|
+
"signUsPerOp": 16.402,
|
|
35
|
+
"verifyUsPerOp": 13.4,
|
|
36
|
+
"signOpsPerSecond": 60968.249,
|
|
37
|
+
"verifyOpsPerSecond": 74629.015
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
"profile": "quick",
|
|
41
|
+
"payloadBytes": 1024,
|
|
42
|
+
"algorithm": "ED25519",
|
|
43
|
+
"signUsPerOp": 41.484,
|
|
44
|
+
"verifyUsPerOp": 106.096,
|
|
45
|
+
"signOpsPerSecond": 24105.829,
|
|
46
|
+
"verifyOpsPerSecond": 9425.432
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"profile": "quick",
|
|
50
|
+
"payloadBytes": 4096,
|
|
51
|
+
"algorithm": "HS256",
|
|
52
|
+
"signUsPerOp": 41.471,
|
|
53
|
+
"verifyUsPerOp": 21.896,
|
|
54
|
+
"signOpsPerSecond": 24113.328,
|
|
55
|
+
"verifyOpsPerSecond": 45669.707
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
"profile": "quick",
|
|
59
|
+
"payloadBytes": 4096,
|
|
60
|
+
"algorithm": "ED25519",
|
|
61
|
+
"signUsPerOp": 53.73,
|
|
62
|
+
"verifyUsPerOp": 118.702,
|
|
63
|
+
"signOpsPerSecond": 18611.446,
|
|
64
|
+
"verifyOpsPerSecond": 8424.459
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
"profile": "quick",
|
|
68
|
+
"payloadBytes": 16384,
|
|
69
|
+
"algorithm": "HS256",
|
|
70
|
+
"signUsPerOp": 37.261,
|
|
71
|
+
"verifyUsPerOp": 39.437,
|
|
72
|
+
"signOpsPerSecond": 26837.366,
|
|
73
|
+
"verifyOpsPerSecond": 25356.841
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
"profile": "quick",
|
|
77
|
+
"payloadBytes": 16384,
|
|
78
|
+
"algorithm": "ED25519",
|
|
79
|
+
"signUsPerOp": 120.929,
|
|
80
|
+
"verifyUsPerOp": 163.363,
|
|
81
|
+
"signOpsPerSecond": 8269.337,
|
|
82
|
+
"verifyOpsPerSecond": 6121.336
|
|
83
|
+
}
|
|
84
|
+
]
|
|
85
|
+
}
|