@7h3/protocol 0.6.1 → 0.6.3

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/auditLog.d.ts CHANGED
@@ -10,10 +10,23 @@ export interface AuditEntry {
10
10
  failReason?: string;
11
11
  upstream?: string;
12
12
  responseStatus?: number;
13
+ /**
14
+ * SHA-256 of the preceding entry, or 64 zeros for the first.
15
+ *
16
+ * Without this, entries are signed independently, which detects modification
17
+ * but NOT deletion: an attacker who can write to the log removes the entries
18
+ * covering their activity and every remaining entry still verifies. Chaining
19
+ * makes the log tamper-evident as a whole — see verifyAuditChain.
20
+ */
21
+ prevHash: string;
13
22
  entrySignature: string;
14
23
  }
24
+ /** Genesis value for `prevHash`, so entry 0 is chained like every other entry. */
25
+ export declare const AUDIT_GENESIS_HASH: string;
26
+ /** SHA-256 over a complete, signed entry — what the next entry chains to. */
27
+ export declare function auditEntryHash(entry: AuditEntry): Promise<string>;
15
28
  export interface AuditLogger {
16
- log(event: Omit<AuditEntry, 'id' | 'timestampMs' | 'entrySignature'>): Promise<void>;
29
+ log(event: Omit<AuditEntry, 'id' | 'timestampMs' | 'entrySignature' | 'prevHash'>): Promise<void>;
17
30
  query(opts?: {
18
31
  type?: AuditEventType;
19
32
  sender?: string;
@@ -24,10 +37,11 @@ export interface AuditLogger {
24
37
  }
25
38
  declare class InMemoryAuditLog implements AuditLogger {
26
39
  private entries;
40
+ private tip;
27
41
  private privateKey;
28
42
  private maxEntries;
29
43
  constructor(privateKey: string, maxEntries?: number);
30
- log(event: Omit<AuditEntry, 'id' | 'timestampMs' | 'entrySignature'>): Promise<void>;
44
+ log(event: Omit<AuditEntry, 'id' | 'timestampMs' | 'entrySignature' | 'prevHash'>): Promise<void>;
31
45
  query(opts?: {
32
46
  type?: AuditEventType;
33
47
  sender?: string;
@@ -38,7 +52,7 @@ declare class InMemoryAuditLog implements AuditLogger {
38
52
  size(): number;
39
53
  }
40
54
  declare class NoopAuditLog implements AuditLogger {
41
- log(_event: Omit<AuditEntry, 'id' | 'timestampMs' | 'entrySignature'>): Promise<void>;
55
+ log(_event: Omit<AuditEntry, 'id' | 'timestampMs' | 'entrySignature' | 'prevHash'>): Promise<void>;
42
56
  query(_opts?: {
43
57
  type?: AuditEventType;
44
58
  sender?: string;
@@ -48,6 +62,22 @@ declare class NoopAuditLog implements AuditLogger {
48
62
  verify(_entry: AuditEntry, _publicKey: string): Promise<boolean>;
49
63
  size(): number;
50
64
  }
65
+ export interface AuditChainVerification {
66
+ ok: boolean;
67
+ length: number;
68
+ /** Index of the first entry that failed, or null when the chain verifies. */
69
+ brokenAt: number | null;
70
+ reason?: string;
71
+ }
72
+ /**
73
+ * Verify an audit log end to end.
74
+ *
75
+ * Checks, for each entry in order, that `prevHash` matches the running hash of
76
+ * the previous entry and that the Ed25519 signature is valid. Verifying entries
77
+ * one at a time catches modification but not deletion — every surviving entry
78
+ * still verifies on its own — which is exactly what this closes.
79
+ */
80
+ export declare function verifyAuditChain(entries: AuditEntry[], publicKey: string): Promise<AuditChainVerification>;
51
81
  export declare function createAuditLog(privateKey: string, opts?: {
52
82
  maxEntries?: number;
53
83
  }): InMemoryAuditLog;
package/index.js CHANGED
@@ -2988,6 +2988,10 @@ var Cr = class {
2988
2988
  reason: t
2989
2989
  });
2990
2990
  }
2991
+ isEnvelopeRevoked(e) {
2992
+ let t = e?.header?.sender, n = e?.signature?.keyId;
2993
+ return t !== void 0 && this.isRevoked(t) || n !== void 0 && this.isRevoked(n);
2994
+ }
2991
2995
  isRevoked(e) {
2992
2996
  return this.revoked.has(e);
2993
2997
  }
@@ -3023,12 +3027,24 @@ var Cr = class {
3023
3027
  }
3024
3028
  consume(e, t, n = Date.now()) {
3025
3029
  let r = n - t.windowMs, i = (this.windows.get(e) ?? []).filter((e) => e > r), a = i.length < t.requests;
3026
- if (a && i.push(n), i.length > 0) for (this.windows.delete(e), this.windows.set(e, i); this.windows.size > this.maxKeys;) {
3027
- let e = this.windows.keys().next().value;
3028
- if (e === void 0) break;
3029
- this.windows.delete(e);
3030
- }
3031
- else this.windows.delete(e);
3030
+ if (a && i.push(n), i.length > 0) {
3031
+ if (this.windows.delete(e), this.windows.set(e, i), this.windows.size > this.maxKeys) {
3032
+ let r = n - t.windowMs;
3033
+ for (let [t, n] of this.windows) {
3034
+ if (this.windows.size <= this.maxKeys) break;
3035
+ t !== e && (n.length === 0 || n[n.length - 1] <= r) && this.windows.delete(t);
3036
+ }
3037
+ for (let [n, r] of this.windows) {
3038
+ if (this.windows.size <= this.maxKeys) break;
3039
+ n !== e && r.length < t.requests && this.windows.delete(n);
3040
+ }
3041
+ for (; this.windows.size > this.maxKeys;) {
3042
+ let e = this.windows.keys().next().value;
3043
+ if (e === void 0) break;
3044
+ this.windows.delete(e);
3045
+ }
3046
+ }
3047
+ } else this.windows.delete(e);
3032
3048
  return {
3033
3049
  allowed: a,
3034
3050
  remaining: Math.max(0, t.requests - i.length),
@@ -3642,16 +3658,25 @@ function ti(e) {
3642
3658
  }
3643
3659
  //#endregion
3644
3660
  //#region src/auditLog.ts
3645
- function ni(e) {
3661
+ var ni = "0".repeat(64);
3662
+ async function ri(e) {
3663
+ let t = await crypto.subtle.digest("SHA-256", new TextEncoder().encode(e));
3664
+ return [...new Uint8Array(t)].map((e) => e.toString(16).padStart(2, "0")).join("");
3665
+ }
3666
+ async function ii(e) {
3667
+ return ri(Q(e) + e.entrySignature);
3668
+ }
3669
+ function Q(e) {
3646
3670
  let t = [
3647
3671
  `"id":${JSON.stringify(e.id)}`,
3648
3672
  `"timestampMs":${e.timestampMs}`,
3649
3673
  `"type":${JSON.stringify(e.type)}`
3650
3674
  ];
3651
- return e.sender !== void 0 && t.push(`"sender":${JSON.stringify(e.sender)}`), e.path !== void 0 && t.push(`"path":${JSON.stringify(e.path)}`), e.method !== void 0 && t.push(`"method":${JSON.stringify(e.method)}`), e.envelopeId !== void 0 && t.push(`"envelopeId":${JSON.stringify(e.envelopeId)}`), e.failReason !== void 0 && t.push(`"failReason":${JSON.stringify(e.failReason)}`), e.upstream !== void 0 && t.push(`"upstream":${JSON.stringify(e.upstream)}`), e.responseStatus !== void 0 && t.push(`"responseStatus":${e.responseStatus}`), `{${t.join(",")}}`;
3675
+ return e.sender !== void 0 && t.push(`"sender":${JSON.stringify(e.sender)}`), e.path !== void 0 && t.push(`"path":${JSON.stringify(e.path)}`), e.method !== void 0 && t.push(`"method":${JSON.stringify(e.method)}`), e.envelopeId !== void 0 && t.push(`"envelopeId":${JSON.stringify(e.envelopeId)}`), e.failReason !== void 0 && t.push(`"failReason":${JSON.stringify(e.failReason)}`), e.upstream !== void 0 && t.push(`"upstream":${JSON.stringify(e.upstream)}`), e.responseStatus !== void 0 && t.push(`"responseStatus":${e.responseStatus}`), t.push(`"prevHash":${JSON.stringify(e.prevHash)}`), `{${t.join(",")}}`;
3652
3676
  }
3653
- var ri = class {
3677
+ var ai = class {
3654
3678
  entries = [];
3679
+ tip = ni;
3655
3680
  privateKey;
3656
3681
  maxEntries;
3657
3682
  constructor(e, t = 1e4) {
@@ -3661,19 +3686,20 @@ var ri = class {
3661
3686
  let t = {
3662
3687
  id: `audit-${Date.now()}-${y(5)}`,
3663
3688
  timestampMs: Date.now(),
3664
- ...e
3665
- }, n = await b(ni(t), this.privateKey), r = {
3689
+ ...e,
3690
+ prevHash: this.tip
3691
+ }, n = await b(Q(t), this.privateKey), r = {
3666
3692
  ...t,
3667
3693
  entrySignature: n
3668
3694
  };
3669
- this.entries.length >= this.maxEntries && this.entries.shift(), this.entries.push(r);
3695
+ this.entries.length >= this.maxEntries && this.entries.shift(), this.entries.push(r), this.tip = await ii(r);
3670
3696
  }
3671
3697
  async query(e) {
3672
3698
  let t = [...this.entries];
3673
3699
  return e?.type !== void 0 && (t = t.filter((t) => t.type === e.type)), e?.sender !== void 0 && (t = t.filter((t) => t.sender === e.sender)), e?.since !== void 0 && (t = t.filter((t) => t.timestampMs >= e.since)), e?.limit !== void 0 && (t = t.slice(-e.limit)), t;
3674
3700
  }
3675
3701
  async verify(e, t) {
3676
- return x(ni({
3702
+ return x(Q({
3677
3703
  id: e.id,
3678
3704
  timestampMs: e.timestampMs,
3679
3705
  type: e.type,
@@ -3683,13 +3709,14 @@ var ri = class {
3683
3709
  envelopeId: e.envelopeId,
3684
3710
  failReason: e.failReason,
3685
3711
  upstream: e.upstream,
3712
+ prevHash: e.prevHash,
3686
3713
  responseStatus: e.responseStatus
3687
3714
  }), e.entrySignature, t);
3688
3715
  }
3689
3716
  size() {
3690
3717
  return this.entries.length;
3691
3718
  }
3692
- }, ii = class {
3719
+ }, oi = class {
3693
3720
  async log(e) {}
3694
3721
  async query(e) {
3695
3722
  return [];
@@ -3701,25 +3728,50 @@ var ri = class {
3701
3728
  return 0;
3702
3729
  }
3703
3730
  };
3704
- function ai(e, t) {
3705
- return new ri(e, t?.maxEntries);
3731
+ async function si(e, t) {
3732
+ let n = ni;
3733
+ for (let r = 0; r < e.length; r++) {
3734
+ let i = e[r];
3735
+ if (i.prevHash !== n) return {
3736
+ ok: !1,
3737
+ length: e.length,
3738
+ brokenAt: r,
3739
+ reason: "prev-hash-mismatch"
3740
+ };
3741
+ let { entrySignature: a, ...o } = i;
3742
+ if (!await x(Q(o), a, t)) return {
3743
+ ok: !1,
3744
+ length: e.length,
3745
+ brokenAt: r,
3746
+ reason: "bad-signature"
3747
+ };
3748
+ n = await ii(i);
3749
+ }
3750
+ return {
3751
+ ok: !0,
3752
+ length: e.length,
3753
+ brokenAt: null
3754
+ };
3755
+ }
3756
+ function ci(e, t) {
3757
+ return new ai(e, t?.maxEntries);
3706
3758
  }
3707
3759
  //#endregion
3708
3760
  //#region src/otel.ts
3709
- var oi = null;
3710
- function si(e) {
3711
- oi = e;
3761
+ var li = null;
3762
+ function ui(e) {
3763
+ li = e;
3712
3764
  }
3713
- function ci() {
3714
- if (oi === null) return null;
3765
+ function di() {
3766
+ if (li === null) return null;
3715
3767
  try {
3716
- return oi.getTracer("7h3/protocol");
3768
+ return li.getTracer("7h3/protocol");
3717
3769
  } catch {
3718
3770
  return null;
3719
3771
  }
3720
3772
  }
3721
- async function li(e, t) {
3722
- let n = ci();
3773
+ async function fi(e, t) {
3774
+ let n = di();
3723
3775
  if (n === null) return e(null);
3724
3776
  let r = n.startSpan("7h3.verify", t);
3725
3777
  try {
@@ -3730,8 +3782,8 @@ async function li(e, t) {
3730
3782
  r.end();
3731
3783
  }
3732
3784
  }
3733
- async function ui(e) {
3734
- let t = ci();
3785
+ async function pi(e) {
3786
+ let t = di();
3735
3787
  if (t === null) return e(null);
3736
3788
  let n = t.startSpan("7h3.audit.write");
3737
3789
  try {
@@ -3744,63 +3796,63 @@ async function ui(e) {
3744
3796
  }
3745
3797
  //#endregion
3746
3798
  //#region src/encryption.ts
3747
- function Q(e) {
3799
+ function mi(e) {
3748
3800
  return Buffer.from(e).toString("base64url");
3749
3801
  }
3750
3802
  function $(e) {
3751
3803
  return Buffer.from(e, "base64url");
3752
3804
  }
3753
- var di = Buffer.from("302e020100300506032b656e04220420", "hex"), fi = Buffer.from("302a300506032b656e032100", "hex");
3754
- function pi(e) {
3805
+ var hi = Buffer.from("302e020100300506032b656e04220420", "hex"), gi = Buffer.from("302a300506032b656e032100", "hex");
3806
+ function _i(e) {
3755
3807
  let t = $(e);
3756
3808
  return r({
3757
- key: Buffer.concat([di, t]),
3809
+ key: Buffer.concat([hi, t]),
3758
3810
  format: "der",
3759
3811
  type: "pkcs8"
3760
3812
  });
3761
3813
  }
3762
- function mi(e) {
3814
+ function vi(e) {
3763
3815
  let t = $(e);
3764
3816
  return i({
3765
- key: Buffer.concat([fi, t]),
3817
+ key: Buffer.concat([gi, t]),
3766
3818
  format: "der",
3767
3819
  type: "spki"
3768
3820
  });
3769
3821
  }
3770
- function hi() {
3822
+ function yi() {
3771
3823
  let { privateKey: e, publicKey: t } = o("x25519"), n = e.export({ format: "jwk" });
3772
3824
  return {
3773
3825
  publicKey: t.export({ format: "jwk" }).x,
3774
3826
  privateKey: n.d
3775
3827
  };
3776
3828
  }
3777
- function gi(e, t, n) {
3829
+ function bi(e, t, n) {
3778
3830
  let r = s("sha256", a({
3779
- privateKey: pi(e),
3780
- publicKey: mi(t)
3831
+ privateKey: _i(e),
3832
+ publicKey: vi(t)
3781
3833
  }), $(n), Buffer.from("7h3-enc/1", "utf8"), 32);
3782
3834
  return Buffer.from(r);
3783
3835
  }
3784
- function _i(e, n) {
3785
- let r = hi(), i = c(12), a = Q(i), o = gi(r.privateKey, n, a), s = Buffer.from(JSON.stringify(e), "utf8"), l = t("chacha20-poly1305", o, i, { authTagLength: 16 }), u = Buffer.concat([l.update(s), l.final()]), d = l.getAuthTag(), f = {
3836
+ function xi(e, n) {
3837
+ let r = yi(), i = c(12), a = mi(i), o = bi(r.privateKey, n, a), s = Buffer.from(JSON.stringify(e), "utf8"), l = t("chacha20-poly1305", o, i, { authTagLength: 16 }), u = Buffer.concat([l.update(s), l.final()]), d = l.getAuthTag(), f = {
3786
3838
  ephemeralPublic: r.publicKey,
3787
3839
  nonce: a,
3788
- ciphertext: Q(u),
3789
- tag: Q(d)
3840
+ ciphertext: mi(u),
3841
+ tag: mi(d)
3790
3842
  };
3791
3843
  return {
3792
- encryptedContent: Q(Buffer.from(JSON.stringify(f), "utf8")),
3844
+ encryptedContent: mi(Buffer.from(JSON.stringify(f), "utf8")),
3793
3845
  ephemeralPublic: r.publicKey
3794
3846
  };
3795
3847
  }
3796
- function vi(e, t) {
3797
- let r = $(e).toString("utf8"), { ephemeralPublic: i, nonce: a, ciphertext: o, tag: s } = JSON.parse(r), c = gi(t, i, a), l = $(a), u = $(o), d = $(s), f = n("chacha20-poly1305", c, l, { authTagLength: 16 });
3848
+ function Si(e, t) {
3849
+ let r = $(e).toString("utf8"), { ephemeralPublic: i, nonce: a, ciphertext: o, tag: s } = JSON.parse(r), c = bi(t, i, a), l = $(a), u = $(o), d = $(s), f = n("chacha20-poly1305", c, l, { authTagLength: 16 });
3798
3850
  f.setAuthTag(d);
3799
3851
  let p = Buffer.concat([f.update(u), f.final()]);
3800
3852
  return JSON.parse(p.toString("utf8"));
3801
3853
  }
3802
- async function yi(e, t) {
3803
- let { encryptedContent: n } = _i(e.body, t.recipientX25519PublicKey);
3854
+ async function Ci(e, t) {
3855
+ let { encryptedContent: n } = xi(e.body, t.recipientX25519PublicKey);
3804
3856
  return w({
3805
3857
  header: e.header,
3806
3858
  body: {
@@ -3811,12 +3863,12 @@ async function yi(e, t) {
3811
3863
  }
3812
3864
  }, t.senderEd25519PrivateKey);
3813
3865
  }
3814
- async function bi(e, t) {
3866
+ async function wi(e, t) {
3815
3867
  if (!await T(e, t.senderEd25519PublicKey)) throw Error("7h3/encryption: Ed25519 signature verification failed");
3816
3868
  return {
3817
3869
  envelope: e,
3818
- body: vi(e.body.content, t.recipientX25519PrivateKey)
3870
+ body: Si(e.body.content, t.recipientX25519PrivateKey)
3819
3871
  };
3820
3872
  }
3821
3873
  //#endregion
3822
- export { at as AgentSession, ot as AipAgentAdapter, zr as CAP_HEADER, Tn as CBOR_CONTENT_TYPE, Sn as CborDecoder, bn as CborEncoder, Rt as ClusterRedisReplayStore, An as DEFAULT_HEADER, xe as DEFAULT_MAX_BINARY_ENVELOPE_BYTES, Re as DistributedReplayCache, hr as GRPC_METADATA_KEY, ri as InMemoryAuditLog, It as InMemoryRedisLikeClient, A as InMemoryReplayCache, Ut as InMemoryRevocationStore, ze as InMemoryVerificationMaterialCache, Rn as InMemoryWebhookReplayCache, Cr as KeyRotationManager, xn as MAX_CBOR_DEPTH, _e as MAX_CLOCK_SKEW_MS, ge as MAX_TTL_MS, ii as NoopAuditLog, $r as Protocol7h3Gateway, Ir as Protocol7h3Metrics, Ar as RESPONSE_HEADER, Lt as RedisReplayStore, wr as RevocationRegistry, rt as RollingKeyring, Mt as RuntimePolicyManager, qn as STREAM_HEADER, Ye as SessionTransport, ar as SignedStreamReader, ir as SignedStreamWriter, Y as SimpleCounter, Fr as SimpleHistogram, Tr as SlidingWindowRateLimiter, Ln as WEBHOOK_DEFAULT_TTL_MS, R as WEBHOOK_SIG_HEADER, z as WEBHOOK_TS_HEADER, N as bootstrapRuntimePolicyEnforcer, Z as canonicalizeCapabilityToken, _ as canonicalizeEnvelope, Un as consumeWebhook, st as createAipAgentAdapter, $e as createAipCapabilities, At as createAipMcpGatewayRuntime, jt as createAipMcpGatewayRuntimeWithPolicy, ai as createAuditLog, an as createCachingKeyRegistry, Vt as createClusterReplayStore, rn as createCompositeKeyRegistry, D as createEnvelope, ei as createGateway, Sr as createHttpKeyRegistry, tn as createHttpMcpClient, en as createHttpMcpHandler, Pn as createHttpMiddleware, it as createKeyringSignatureResolver, Yt as createMcpClientCodec, Rr as createMetricsMiddleware, Ct as createPolicyEnforcer, ti as createProductionGateway, pt as createRawTaskFromJsonRpc, ct as createRawTaskFromLangChain, ut as createRawTaskFromLlamaIndex, zt as createRedisReplayStore, Wt as createRedisRevocationStore, In as createSignedFetchRequest, Xe as createSignedMessage, or as createSignedStream, pr as createSignedWebSocketStream, nn as createStaticKeyRegistry, $t as createStdioMcpClient, sr as createStreamVerifier, wn as decodeCbor, Ge as decodeEnvelope, qe as decodeEnvelopeBatch, Ie as decodeEnvelopeBinary, kn as decodeEnvelopeCbor, dr as decodeStreamChunk, vi as decryptBody, Kr as delegateCapabilityToken, gi as deriveEncryptionKey, et as encodeAipCapabilities, Cn as encodeCbor, j as encodeEnvelope, Ke as encodeEnvelopeBatch, Fe as encodeEnvelopeBinary, En as encodeEnvelopeCbor, ur as encodeStreamChunk, _i as encryptBody, xr as fetchWellKnownKeys, pe as generateEd25519KeypairBase64Url, hi as generateX25519KeyPair, ci as getOtelTracer, Pt as getRuntimeTuningPreset, Er as globalRateLimiter, kr as isAllowedSender, wt as isRuntimeMode, Vr as issueCapabilityToken, bt as loadRuntimePolicy, Dr as matchGlob, Or as matchPolicy, X as metrics, nt as negotiateAipCapabilities, Qr as normalizeGatewayPath, bi as openEnvelope, tt as parseAipCapabilities, Zr as parseCapabilityChain, vt as parseRuntimePolicyJson, br as parseWellKnownKeys, y as randomHex, M as receiveEnvelope, Je as receiveEnvelopeBatch, mr as receiveSignedWebSocketStream, Ft as recommendPolicyAdjustments, Lr as renderPrometheusText, yi as sealEnvelope, Xr as serializeCapabilityChain, Qt as serveMcpOverStdio, yr as serveWellKnownKeys, si as setOtelProvider, b as signCanonicalPayloadEd25519, de as signCanonicalPayloadHmac, w as signEnvelopeEd25519, S as signEnvelopeHmac, Fn as signFetchRequest, gr as signGrpcCall, Mn as signHttpRequest, Nn as signHttpRequestHmac, Wn as signQueueMessage, jr as signResponse, cr as signStream, zn as signWebhook, Bn as signWebhookHmac, mt as toJsonRpcResponse, lt as toLangChainMessage, dt as toLlamaIndexMessage, Yr as tokenMatchesScope, E as validateEnvelope, _t as validateRuntimePolicy, x as verifyCanonicalPayloadEd25519, fe as verifyCanonicalPayloadHmac, he as verifyCanonicalPayloadSignature, Jr as verifyCapabilityChain, qr as verifyCapabilityToken, T as verifyEnvelopeEd25519, C as verifyEnvelopeHmac, me as verifyEnvelopeSignature, _r as verifyGrpcCall, jn as verifyHttpEnvelope, Kn as verifyQueueBatch, Gn as verifyQueueMessage, Mr as verifyResponse, lr as verifyStream, Vn as verifyWebhook, Hn as verifyWebhookHmac, ui as withAuditSpan, vr as withGrpcVerification, Gt as withRevocationCheck, li as withVerificationSpan, Xt as wrapMcpClient, Jt as wrapMcpServer, fr as wrapWebSocket };
3874
+ export { ni as AUDIT_GENESIS_HASH, at as AgentSession, ot as AipAgentAdapter, zr as CAP_HEADER, Tn as CBOR_CONTENT_TYPE, Sn as CborDecoder, bn as CborEncoder, Rt as ClusterRedisReplayStore, An as DEFAULT_HEADER, xe as DEFAULT_MAX_BINARY_ENVELOPE_BYTES, Re as DistributedReplayCache, hr as GRPC_METADATA_KEY, ai as InMemoryAuditLog, It as InMemoryRedisLikeClient, A as InMemoryReplayCache, Ut as InMemoryRevocationStore, ze as InMemoryVerificationMaterialCache, Rn as InMemoryWebhookReplayCache, Cr as KeyRotationManager, xn as MAX_CBOR_DEPTH, _e as MAX_CLOCK_SKEW_MS, ge as MAX_TTL_MS, oi as NoopAuditLog, $r as Protocol7h3Gateway, Ir as Protocol7h3Metrics, Ar as RESPONSE_HEADER, Lt as RedisReplayStore, wr as RevocationRegistry, rt as RollingKeyring, Mt as RuntimePolicyManager, qn as STREAM_HEADER, Ye as SessionTransport, ar as SignedStreamReader, ir as SignedStreamWriter, Y as SimpleCounter, Fr as SimpleHistogram, Tr as SlidingWindowRateLimiter, Ln as WEBHOOK_DEFAULT_TTL_MS, R as WEBHOOK_SIG_HEADER, z as WEBHOOK_TS_HEADER, ii as auditEntryHash, N as bootstrapRuntimePolicyEnforcer, Z as canonicalizeCapabilityToken, _ as canonicalizeEnvelope, Un as consumeWebhook, st as createAipAgentAdapter, $e as createAipCapabilities, At as createAipMcpGatewayRuntime, jt as createAipMcpGatewayRuntimeWithPolicy, ci as createAuditLog, an as createCachingKeyRegistry, Vt as createClusterReplayStore, rn as createCompositeKeyRegistry, D as createEnvelope, ei as createGateway, Sr as createHttpKeyRegistry, tn as createHttpMcpClient, en as createHttpMcpHandler, Pn as createHttpMiddleware, it as createKeyringSignatureResolver, Yt as createMcpClientCodec, Rr as createMetricsMiddleware, Ct as createPolicyEnforcer, ti as createProductionGateway, pt as createRawTaskFromJsonRpc, ct as createRawTaskFromLangChain, ut as createRawTaskFromLlamaIndex, zt as createRedisReplayStore, Wt as createRedisRevocationStore, In as createSignedFetchRequest, Xe as createSignedMessage, or as createSignedStream, pr as createSignedWebSocketStream, nn as createStaticKeyRegistry, $t as createStdioMcpClient, sr as createStreamVerifier, wn as decodeCbor, Ge as decodeEnvelope, qe as decodeEnvelopeBatch, Ie as decodeEnvelopeBinary, kn as decodeEnvelopeCbor, dr as decodeStreamChunk, Si as decryptBody, Kr as delegateCapabilityToken, bi as deriveEncryptionKey, et as encodeAipCapabilities, Cn as encodeCbor, j as encodeEnvelope, Ke as encodeEnvelopeBatch, Fe as encodeEnvelopeBinary, En as encodeEnvelopeCbor, ur as encodeStreamChunk, xi as encryptBody, xr as fetchWellKnownKeys, pe as generateEd25519KeypairBase64Url, yi as generateX25519KeyPair, di as getOtelTracer, Pt as getRuntimeTuningPreset, Er as globalRateLimiter, kr as isAllowedSender, wt as isRuntimeMode, Vr as issueCapabilityToken, bt as loadRuntimePolicy, Dr as matchGlob, Or as matchPolicy, X as metrics, nt as negotiateAipCapabilities, Qr as normalizeGatewayPath, wi as openEnvelope, tt as parseAipCapabilities, Zr as parseCapabilityChain, vt as parseRuntimePolicyJson, br as parseWellKnownKeys, y as randomHex, M as receiveEnvelope, Je as receiveEnvelopeBatch, mr as receiveSignedWebSocketStream, Ft as recommendPolicyAdjustments, Lr as renderPrometheusText, Ci as sealEnvelope, Xr as serializeCapabilityChain, Qt as serveMcpOverStdio, yr as serveWellKnownKeys, ui as setOtelProvider, b as signCanonicalPayloadEd25519, de as signCanonicalPayloadHmac, w as signEnvelopeEd25519, S as signEnvelopeHmac, Fn as signFetchRequest, gr as signGrpcCall, Mn as signHttpRequest, Nn as signHttpRequestHmac, Wn as signQueueMessage, jr as signResponse, cr as signStream, zn as signWebhook, Bn as signWebhookHmac, mt as toJsonRpcResponse, lt as toLangChainMessage, dt as toLlamaIndexMessage, Yr as tokenMatchesScope, E as validateEnvelope, _t as validateRuntimePolicy, si as verifyAuditChain, x as verifyCanonicalPayloadEd25519, fe as verifyCanonicalPayloadHmac, he as verifyCanonicalPayloadSignature, Jr as verifyCapabilityChain, qr as verifyCapabilityToken, T as verifyEnvelopeEd25519, C as verifyEnvelopeHmac, me as verifyEnvelopeSignature, _r as verifyGrpcCall, jn as verifyHttpEnvelope, Kn as verifyQueueBatch, Gn as verifyQueueMessage, Mr as verifyResponse, lr as verifyStream, Vn as verifyWebhook, Hn as verifyWebhookHmac, pi as withAuditSpan, vr as withGrpcVerification, Gt as withRevocationCheck, fi as withVerificationSpan, Xt as wrapMcpClient, Jt as wrapMcpServer, fr as wrapWebSocket };
package/keyInfra.d.ts CHANGED
@@ -56,7 +56,37 @@ export interface RevocationList {
56
56
  }
57
57
  export declare class RevocationRegistry {
58
58
  private revoked;
59
- revoke(keyId: string, reason?: string): void;
59
+ /**
60
+ * Revoke an identifier — either a sender identity or a keyId.
61
+ *
62
+ * Which one you pass matters, and the difference used to be silent. A
63
+ * registry lookup is keyed by *sender*, so `wrapRegistry().getPublicKey()`
64
+ * can only ever compare against a sender id. Revoking a bare keyId therefore
65
+ * blocked the HMAC path (which receives both identifiers) while leaving the
66
+ * Ed25519 path fully open — a revoked, compromised key kept authenticating.
67
+ *
68
+ * Use {@link isEnvelopeRevoked} on the verification path to enforce a keyId
69
+ * revocation for Ed25519, or revoke the sender identity as well. For
70
+ * fleet-wide `(sender, keyId)` revocation, use `RevocationStore` from
71
+ * `./revocation` instead.
72
+ */
73
+ revoke(senderOrKeyId: string, reason?: string): void;
74
+ /**
75
+ * True if either the envelope's sender or the keyId it was signed under has
76
+ * been revoked.
77
+ *
78
+ * This is the check that actually enforces a keyId revocation for Ed25519,
79
+ * because unlike a registry lookup it can see `signature.keyId`. Call it on
80
+ * the verification path alongside signature checking.
81
+ */
82
+ isEnvelopeRevoked(envelope: {
83
+ header?: {
84
+ sender?: string;
85
+ };
86
+ signature?: {
87
+ keyId?: string;
88
+ };
89
+ }): boolean;
60
90
  isRevoked(keyId: string): boolean;
61
91
  getList(): RevocationList;
62
92
  importList(list: RevocationList): void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@7h3/protocol",
3
- "version": "0.6.1",
3
+ "version": "0.6.3",
4
4
  "description": "7h3 Protocol: deterministic, signed, replay-safe AI-to-AI message envelopes (wire 7h3/0.1).",
5
5
  "type": "module",
6
6
  "main": "./index.js",