diff --git a/.changeset/fix-cross-version-sig-verify.md b/.changeset/fix-cross-version-sig-verify.md new file mode 100644 index 0000000..9191af9 --- /dev/null +++ b/.changeset/fix-cross-version-sig-verify.md @@ -0,0 +1,5 @@ +--- +"@resciencelab/agent-world-sdk": patch +--- + +Fix cross-version HTTP signature verification: use sender's X-AgentWorld-Version header instead of local PROTOCOL_VERSION when reconstructing signing input, so gateway and peers running different SDK minor versions can still verify each other's signatures. diff --git a/packages/agent-world-sdk/src/crypto.ts b/packages/agent-world-sdk/src/crypto.ts index 8aed34e..164ed14 100644 --- a/packages/agent-world-sdk/src/crypto.ts +++ b/packages/agent-world-sdk/src/crypto.ts @@ -160,9 +160,10 @@ function buildRequestSigningInput(opts: { authority: string; path: string; contentDigest: string; + v?: string; }): Record { return { - v: PROTOCOL_VERSION, + v: opts.v ?? PROTOCOL_VERSION, from: opts.from, kid: opts.kid, ts: opts.ts, @@ -232,6 +233,7 @@ export function verifyHttpRequestHeaders( const kid = h["x-agentworld-keyid"] as string | undefined; const ts = h["x-agentworld-timestamp"] as string | undefined; const cd = h["content-digest"] as string | undefined; + const senderVersion = h["x-agentworld-version"] as string | undefined; if (!sig || !from || !kid || !ts || !cd) { return { ok: false, error: "Missing required AgentWorld headers" }; @@ -258,6 +260,7 @@ export function verifyHttpRequestHeaders( authority, path, contentDigest: cd, + v: senderVersion, }); const ok = verifyWithDomainSeparator( DOMAIN_SEPARATORS.HTTP_REQUEST, @@ -287,9 +290,10 @@ function buildResponseSigningInput(opts: { ts: string; status: number; contentDigest: string; + v?: string; }): Record { return { - v: PROTOCOL_VERSION, + v: opts.v ?? PROTOCOL_VERSION, from: opts.from, kid: opts.kid, ts: opts.ts, @@ -351,6 +355,7 @@ export function verifyHttpResponseHeaders( const kid = h["x-agentworld-keyid"]; const ts = h["x-agentworld-timestamp"]; const cd = h["content-digest"]; + const senderVersion = h["x-agentworld-version"]; if (!sig || !from || !kid || !ts || !cd) { return { ok: false, error: "Missing required AgentWorld response headers" }; @@ -375,6 +380,7 @@ export function verifyHttpResponseHeaders( ts, status, contentDigest: cd, + v: senderVersion ?? undefined, }); const ok = verifyWithDomainSeparator( DOMAIN_SEPARATORS.HTTP_RESPONSE,