Skip to content

feat(sdk): harden A2A transport, codegen, and negotiation - #1071

Merged
bokelley merged 14 commits into
mainfrom
work-through-python-issues
Aug 24, 2026
Merged

feat(sdk): harden A2A transport, codegen, and negotiation#1071
bokelley merged 14 commits into
mainfrom
work-through-python-issues

Conversation

@bokelley

Copy link
Copy Markdown
Contributor

Summary

  • add custom A2A request-handler support and opt-in unauthenticated discovery skills
  • expose reusable SSRF enforcement seams, disable MCP redirects, and fail closed on invalid or ambiguous A2A credentials
  • preserve narrow allOf types, requiredness, constraints, and non-null intersections during regeneration
  • harden open-payload model selection and document required brand verification signatures
  • add buyer-side proposal-refinement preflight plus wire-faithful lineage, digest, constraint, alternative, and product-change verification

Issue coverage

Closes #1004
Closes #1007
Closes #1010
Closes #945
Advances #907
Advances #1023

Validation

  • three specialist review passes: security, protocol/schema, and general code review approved
  • affected suites: 398 passed
  • full suite: 7050 passed, 41 skipped, 9 deselected, 1 xfailed; one unrelated timing-budget test failed under aggregate load and passed twice in isolation
  • pre-commit formatting, lint, mypy, adopter type checks, and security checks passed on the final commits

Upstream canonicalization follow-up filed as adcontextprotocol/adcp#6813.

Comment thread src/adcp/signing/jwks.py
try:
validate_resolved_ip(ip, allow_private=allow_private)
except SSRFValidationError as exc:
last_rejection = str(exc)
Comment thread src/adcp/negotiation.py
Comment on lines +233 to +235
def _response_data(
response: TaskResult[Any] | BaseModel | Mapping[str, Any],
) -> tuple[dict[str, Any] | None, TaskStatus | str | None, bool]:

@aao-secretariat aao-secretariat Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ladon verdict: Approve

Approve — no blocking or medium findings.

The reviewer examined the load-bearing changes in this PR and found every trust-boundary change fails closed:

  • A2A transport/auth hardening: MCP redirects disabled unconditionally, duplicate/ambiguous credentials rejected, discovery skills gated through validate_discovery_set.
  • SSRF seam refactor: IPv4-mapped metadata addresses unwrapped before the block (references.py:815); pre-auth discovery buffering bounded by the size limiter in serve() layers outside auth (serve.py:1732/1742).
  • allOf-merge codegen fix: post_generate_fixes.py raises RuntimeError on an ambiguous narrow arm rather than silently widening.
  • New 708-line buyer-side negotiation verifier: digest checks refuse re-parsed models via a wire_data_required issue rather than passing silently; _response_data is exhaustive over its annotated union (only a Low, callers are type-constrained).
  • adagents.py / postal_area.py are ClassNameN reparenting regeneration churn, not a schema delta.
  • The brand signed_response diff is black reformatting of a pre-existing requirement; the CHANGELOG breaking note is doc catch-up, not a new unmarked semver break.

Decision-table walkthrough: no critical/high findings (row 1 no); gated_paths is false (row 2 no); high_risk is true but all reasons are (modified) with no medium finding attached, and there are no (deleted) entries (rows 3, 5 no); no medium findings at all (rows 4, 8 no); no prior escalation (row 6 no); no no-auto-approve team match (row 7 no). Falls through to row 9 → approve. The high_risk flag is heuristic only and, per the reasons block, reflects modifications to protocol/server/signing paths that the reviewer cleared with no medium-or-worse concern.

@bokelley
bokelley enabled auto-merge (squash) August 24, 2026 06:00
@bokelley
bokelley merged commit cd3b7a0 into main Aug 24, 2026
27 checks passed
@bokelley
bokelley deleted the work-through-python-issues branch August 24, 2026 06:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant