a2aproject / a2aproject/a2a-js

[Bug]: canonicalizeAgentCard drops REQUIRED fields with default values, contradicting the §8.4.1 worked example

オープン
#627 コメント 1 件 リアクション 0 件 担当者 0 名 GitHub で見る
主要言語
TypeScript
スター
613
フォーク
169
平均マージ
1日 6時間
マージ済み PR(30日)
21

説明

**What happened?**

`canonicalizeAgentCard` in `src/signature.ts` runs `cleanEmpty` before `jcsStringify`, and `cleanEmpty` deletes empty strings, empty arrays and empty objects unconditionally. Spec §8.4.1 rule 1 says the opposite for one class of field: "Required fields: Fields marked with `REQUIRED` MUST always be present, even if the field value matches the default." The section then prints a worked example that turns on exactly this, deriving `description: ""` include and `skills: []` include, and shows the canonical result.

Running the section's own fragment through this SDK gives `{"capabilities":{"pushNotifications":false,"streaming":false},"name":"Example Agent"}` where the specification says `{"capabilities":{"pushNotifications":false,"streaming":false},"description":"","name":"Example Agent","skills":[]}`. `a2a-python` produces byte-identical output to this SDK here, so the two agree with each other and both differ from the text. That agreement is why the divergence is invisible: no cross-implementation test can see it, and it will surface the first time somebody writes a third canonicalizer from the specification rather than from one of these two. `a2aproject/a2a-go#141` is open to do precisely that.

I want to be clear that I do not think this is straightforwardly this SDK's fault, and I have filed the substance against the specification at a2aproject/A2A#2122. `description` is a proto3 singular string with no presence carrying only a `google.api.field_behavior = REQUIRED` annotation, and ADR-001 makes ProtoJSON normative. ProtoJSON does not read `field_behavior`, so `AgentCard.toJSON` cannot distinguish "REQUIRED and defaulted" from "unset" and no stock encoder can produce the bytes §8.4.1 prints. Whichever way the specification resolves that, this SDK will need a change: either `cleanEmpty` grows a list of REQUIRED field paths that it never strips, or the specification's rule 1 and worked example change to match what a ProtoJSON encoder emits and this code is already correct. I would rather not send a patch until that is decided, but I wanted the divergence recorded here so it is not rediscovered by whoever writes the third implementation.

Separately and unrelated to the above, I checked this SDK's canonicalization against two independent RFC 8785 implementations, `rfc8785.py` and `gowebpki/jcs` v1.0.1, across non-ASCII string content, non-BMP object keys and ECMAScript number serialization. This SDK is conformant on all three, and the divergence I found in the cross-SDK direction is on the Python side, which I have reported there. `jcsStringify` is doing the right thing.

One question rather than a bug: `verifyAgentCardSignature` rejects any signature whose protected header lacks `typ`, `kid` or `alg`. §8.4.2 lists `typ` under "The protected header MUST include:" but the bullet itself says `typ` "SHOULD be set to \"JOSE\" for JWS", so it is not obvious from the text whether absence of `typ` is a verification failure. In practice cards signed by `a2a-python` always carry a `typ` because PyJWT stamps one, but the value is `"JWT"` rather than `"JOSE"` unless the caller sets it explicitly, so this SDK currently accepts a header the specification arguably discourages while rejecting one it arguably permits. I have asked on a2aproject/A2A#2122 and will follow whatever the answer is.

コントリビューションガイド

コントリビューションガイドを開く

調査の方向性

The issue is in src/signature.ts, specifically the canonicalizeAgentCard function and its use of cleanEmpty before jcsStringify. First, understand the spec §8.4.1 and the open questions about REQUIRED fields with defaults. Check the linked spec issue a2aproject/A2A#2122 for resolution. The fix may involve modifying cleanEmpty to preserve certain fields or adjusting the canonicalization logic. Test changes against the worked example in the spec and cross-check with other SDKs.

索引モデルが issue の本文から書いたものです。

評価

技術スタック
javascript, typescript
領域
backend-api-design, security
issue の種類
バグ
難易度
4/5
見積もり時間
3〜5日
活発さ
静か
明瞭さ
明確に書かれている
初心者へのやさしさ
45/100

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。