docs(samples): add Agent Card signing sample - #1198
Open
orangecola wants to merge 1 commit into
Open
Conversation
There was no runnable example for `a2a.utils.signing`, so add one covering both halves of Agent Card signing: - Server: signs the card with an ES256 key via `create_agent_card_signer`, wired in through `create_agent_card_routes(card_modifier=...)`, and publishes the public key as a JWKS document referenced by the signature's `jku` header. - Client: verifies the fetched card with `create_signature_verifier` passed to `A2ACardResolver.get_agent_card`, resolving keys by `kid` from an allowlist of pinned JWKS URLs and an allowlist of algorithms. The default demo mode runs both, then shows the rejections a verifier exists for: a card whose transport URL was rewritten in transit, a card with its signature stripped, and a genuine card whose `jku` the client does not trust. Adds a smoke test for the sample and a README section. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Y9eQGQeMVdqZ1f1m8ijGm3
🧪 Code Coverage (vs
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
There was no runnable example for
a2a.utils.signing, so this adds onecovering both halves of Agent Card signing.
samples/agent_card_signing.py:create_agent_card_signer, serves it viacreate_agent_card_routes(card_modifier=...), and publishes the public keyas a JWKS document at
/.well-known/jwks.json— the URL the signature'sjkupoints to.create_signature_verifierpassed toA2ACardResolver.get_agent_card(signature_verifier=...), resolving keys bykidfrom an allowlist of pinned JWKS URLs, with algorithms pinned toES256.demo(default, runs both in-process),serve,verify --url.The default
demomode verifies the genuine card and then shows the threerejections a verifier exists for:
Two non-obvious details are called out in comments, since they bite anyone
copying the pattern:
with a sync HTTP client blocks the event loop (it deadlocks against an
in-process server and reports
No valid signature found). The key providerdoes pure in-memory lookups over JWKS prefetched asynchronously.
create_agent_card_signermutates the card it signs, so a per-requestcard_modifierwould accumulate signatures. The helper deep-copies first andthe card is signed once at startup.
The key provider also raises
PyJWKErrorrather than a plain exception, so theverifier treats one unusable signature as unverifiable and moves to the next
instead of aborting a card that also carries a good signature.
Also adds
tests/integration/test_agent_card_signing_smoke.py(runs the demoon a free port, asserts one acceptance and three rejections) and a
samples/README.mdsection.No library code changed — samples, tests and docs only.
Testing
uv run pytest tests/utils/test_signing.py tests/integration/test_agent_card_signing_smoke.py tests/client/test_card_resolver.py→ 55 passeduv run ruff format --checkanduv run ruff check→ cleanuv run ty check→ same 4 pre-existing diagnostics asmain(samples are outside[tool.ty.src])Checklist
CONTRIBUTINGGuide.bash scripts/format.shfrom the repository root to format)Fixes #1197 🦕