Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions samples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ This directory contains runnable examples demonstrating how to build and interac
|---|---|---|
| `hello_world_agent.py` | **Server** | A2A agent server |
| `cli.py` | **Client** | Interactive terminal client |
| `agent_card_signing.py` | **Server + Client** | Signing and verifying an Agent Card |

The samples are designed to work together out of the box: the agent listens on `http://127.0.0.1:41241`, which is the default URL used by the client.
---
Expand Down Expand Up @@ -56,3 +57,30 @@ uv run python samples/cli.py --url http://192.168.1.10:41241 --transport GRPC
Then type a message like `hello` and press Enter.

Type `/quit` or `/exit` to stop, or press `Ctrl+C`.

---

## `agent_card_signing.py` — Agent Card Signing

An Agent Card is fetched before any trust has been established with the agent, so everything in it — transport URLs, security schemes, skills — is attacker-controlled until it is verified. This sample signs a card on the server and verifies it on the client.

Demonstrates:
- Signing the Agent Card with an ES256 key via `create_agent_card_signer`, wired into the card endpoint through `create_agent_card_routes(card_modifier=...)`
- Publishing the matching public key as a JWKS document at `/.well-known/jwks.json`, referenced by the signature's `jku` header
- Verifying the card with `create_signature_verifier`, passed to `A2ACardResolver.get_agent_card(signature_verifier=...)` (the same argument is accepted by `ClientFactory.create_from_url`)
- Pinning trust: the verifier accepts keys only from an allowlist of JWKS URLs and only signatures using an allowlisted algorithm

The default `demo` mode starts the server, verifies its card, and then shows the three failures a verifier exists to catch: 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.

**Run:**

```bash
# Server and client together (default):
uv run python samples/agent_card_signing.py

# Or run the two halves separately:
uv run python samples/agent_card_signing.py serve
uv run python samples/agent_card_signing.py verify --url http://127.0.0.1:41242
```

Requires the `signing`, `encryption` and `fastapi` extras (`pip install 'a2a-sdk[signing,encryption,fastapi]'`); they are already present when working from a `uv sync` of this repo.
Loading
Loading