Repository navigation
Conversation
…#387 review, PR-B) Addresses the two blocking findings from the PR awslabs#387 review on the bundled A2A transport, on a branch stacked on the PR head (f40933d). Auth bypass (blocking): - a2a/rpc.py: authenticate + authorize per method before dispatch. Missing/ invalid bearer -> 401 UNAUTHENTICATED; valid token without the required scope -> 403 PERMISSION_DENIED. task.send/task.cancel require cao:write, task.get requires cao:read (cao:admin satisfies any; write implies read). Errors are JSON-RPC bodies with the matching HTTP status (not tunnelled through 200). Truthful docstring replacing the false 'enforced via JWKS'. - a2a/stream.py: SSE + REST reads gated by Depends(require_any_scope(read...)). - api/main.py: _should_mount_a2a() fail-closed guard — the transport is not mounted on a non-loopback bind while auth is disabled (Agent Card discovery still publishes). Loopback + no-auth stays allowed for local dev. Unbounded-store DoS (blocking): - a2a/store.py: InMemoryTaskStore is now bounded (CAO_A2A_MAX_TASKS, default 1000) and TTL-evicting (CAO_A2A_TASK_TTL, default 3600s). Lazy sweep under the lock; evict oldest terminal first; a full store of live tasks refuses task.send with RESOURCE_EXHAUSTED (429) instead of growing without limit. - a2a/types.py: add PERMISSION_DENIED (5) + RESOURCE_EXHAUSTED (6). Tests (test-first): test/a2a/test_auth.py (28) — per-method matrix (send/get/cancel x {no token, malformed, cao:read, cao:write} -> 401/403/200), stream/REST route auth, parametrized mount-guard decision, bounded-store evict/reject/TTL, and send-when-full -> 429. test/e2e/test_a2a_roundtrip.py: authenticated roundtrip variant (e2e; tmux-gated in this sandbox, runs in CI). Docs: CHANGELOG A2A bullet updated; docs/auth.md 'A2A transport authorization' section + 401->token->200 curl walkthrough. Default-off unchanged: with the auth layer off no token is required and the existing 92 A2A/agent-card tests pass. Gates: black/isort clean, mypy Success (142 files), 3596 passed / 21 skipped. Note: authlib/python-multipart are NOT imported by src (signing uses cryptography via pyjwt[crypto]); no [a2a] runtime extra was invented. Dep hygiene rides the AG-UI core branch. Fork-only review branch; base feat/agentic-protocols-generative-ui. Co-authored-by: Kiro Agent <244629292+kiro-agent@users.noreply.github.com>
This was referenced Jul 6, 2026
Owner
Author
|
Closing as superseded in-fork by #25. This was the earliest A2A draft and has no agent_card/ package at all, so it cannot carry the signed Agent Card the hardened line is named for. Its six symbols absent from #25 are all private helpers reimplemented in #25's reconciled design, and all 21 cases from its test/a2a/test_auth.py were carried into #25's test/a2a/test_store_bounds.py and test/api/test_a2a_mount_guard.py under clearer names. Its docs/auth.md — the largest of the fork's five variants — has been archived to disk. Branch preserved. |
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.
This pull request was created by @kiro-agent on behalf of @plauzy 👻
Comment with /kiro fix to address specific feedback or /kiro all to address everything.
Learn about Kiro Web
Fork-internal review artifact. Base is
feat/agentic-protocols-generative-ui(the PR awslabs#387 head), so this diff reads as "what the A2A remediation changed." Kiro's counterpart toclaude/pr387-a2a-hardenedfor the head-to-head comparison. Please mark Draft in the UI (the tooling couldn't set it).What this addresses
The two blocking findings from review #pullrequestreview-4632216702, both on the bundled A2A transport.
1. Auth bypass → per-method scope enforcement
a2a/rpc.py— authenticate + authorize per method before dispatch. Missing/invalid bearer → 401UNAUTHENTICATED; valid token lacking scope → 403PERMISSION_DENIED.task.send/task.cancelrequirecao:write,task.getrequirescao:read(cao:adminsatisfies any; write implies read). JSON-RPC error bodies with the matching HTTP status — not tunnelled through 200. Truthful docstring replacing the false "enforced via JWKS".a2a/stream.py— SSE + REST reads gated byDepends(require_any_scope(read/write/admin)).api/main.py—_should_mount_a2a()fail-closed guard: the transport is not mounted on a non-loopback bind while auth is disabled (the read-only Agent Card doc still publishes). Loopback + no-auth stays allowed for local dev.2. Unbounded-store DoS → bounded task store
a2a/store.py—InMemoryTaskStoreis now capped (CAO_A2A_MAX_TASKS, default 1000) and TTL-evicting (CAO_A2A_TASK_TTL, default 3600s). Lazy sweep under the lock; evict oldest terminal first; a full store of live tasks refusestask.sendwithRESOURCE_EXHAUSTED(429) rather than growing without limit.a2a/types.py— addPERMISSION_DENIED (5)+RESOURCE_EXHAUSTED (6).Tests (test-first)
test/a2a/test_auth.py— 28 tests: per-method matrix (send/get/cancel × {no token, malformed,cao:read,cao:write} → 401/403/200), stream+REST route auth, parametrized mount-guard decision, bounded-store evict/reject/TTL, and send-when-full → 429.test/e2e/test_a2a_roundtrip.py: authenticated roundtrip variant (e2e;tmux-gated in the sandbox, runs in CI). The identical auth code path is fully exercised bytest_auth.pyviaTestClient.Gates (local)
black --checkclean ·isortclean ·mypy src/Success (142 files)pytest -m 'not e2e': 3596 passed / 21 skipped (incl. the 28 new + 92 existing A2A/agent-card). One unrelatedfifo_readerthread-timing test flakes underxdistand passes in isolation.Scope note
authlib/python-multipartare not imported bysrc/(the Agent Card signer usescryptographyviapyjwt[crypto]), so no[a2a]runtime extra was invented — that would be a false claim. Dependency hygiene (authlib→dev, drop multipart) rides the AG-UI core branch. (For contrast,claude/pr387-a2a-hardenedfolds that dep hygiene into this branch — a legitimate difference to weigh in the comparison.)