Skip to the content.

a2aproject/a2a-python - security scan

Repository: a2aproject/a2a-python Commit scanned: 86c6b0d7dd3ea83efb808de348a0021677b2f0b2 Scan date: 2026-07-16 Disclosure status: public — post-only (strict-norm: official SDK + private-reporting SECURITY.md; nothing cleared the quality gate)

Summary

Severity Count
Critical 0
High 10
Medium 10
Low 0 (filtered at --min-severity medium)
Info 0

Total findings: 20 (0 real after curation; one deployer-hardening note documented)

This is the official Python SDK for the Agent2Agent (A2A) protocol — the Google/Linux-Foundation agent-interop standard. A protocol SDK’s security lives in two places static rules barely touch: how it authenticates peers, and what it does with the push-notification webhook URL a client hands it. The code scanned clean (lint + test fixtures); the one thing worth writing down is that the reference push-notification sender POSTs to the client-supplied URL without egress validation — a real webhook-SSRF surface, but an authenticated, blind, deployer-mitigable one.

Top findings

1. Push-notification sender has no SSRF egress validation (deployer hardening)

2. The auth interceptor logs schemes, not tokens

3. The rest is CI lint, a test-fixture secret set, and one dep CVE

Patterns observed

For a protocol SDK, the security is the peer boundary — auth and callbacks. Nothing in the injection/deserialization/secret families mattered here (no eval, no untrusted pickle, no wildcard CORS, credentials logged as scheme names). The one place worth reading closely was the push-notification path, because “server POSTs to a URL the peer chose” is the callback-SSRF shape every webhook system has to reckon with. A2A reckoned with the authenticity half (the notification token) and left the egress half to the deployer — a defensible split for a reference implementation, and one worth stating out loud so deployers add the URL allowlist.

Blind, authenticated, library-level — the three qualifiers that keep this a note. The same raw finding (“no SSRF validation on an outbound POST”) would be a filed issue on an app that fetches attacker-controlled URLs and returns the body. Here the requester is authenticated, the response never comes back, and the SDK is the layer below where egress policy usually lives. Naming the qualifiers is the curation, the same way the tradingview-mcp and OpenKB scans separated operator-directed fetches from attacker-directed SSRF.

Strict-norm, so the channel matters too. The SDK ships a SECURITY.md that asks for private vulnerability reports and coordinated disclosure. A public issue about push-notification SSRF would violate that policy; and for a Google/LF-governed standard, an authenticated-client blind-SSRF on the reference sender is very likely already a known spec-level consideration. Documenting the deployer-hardening note here is the proportionate action.

Notes on the tool

Disclosure timeline

This is a post-only write-up. The code is clean (credentials logged as scheme names, secrets confined to tests, deps on Dependabot), and the one real surface — push-notification egress — is an authenticated, blind, deployer-mitigable hardening note on a strict-norm SDK that already authenticates its webhooks. Nothing cleared the quality gate; the note is documented for deployers rather than filed.

Reproduce

git clone https://github.com/a2aproject/a2a-python /tmp/scan-target
python scanner/run_scan.py --repo /tmp/scan-target \
  --reports-dir ./reports/a2aproject-a2a-python \
  --min-severity medium --ignore-samples