You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
* feat(auth): serve(auth=BearerTokenAuth(...)) — A2A sibling + cross-transport shortcut
Closes#558. BearerTokenAuthMiddleware only protected the MCP leg.
serve(auth=BearerTokenAuth(...)) wires both transports from one config.
Adds: BearerTokenAuth dataclass, A2ABearerAuthMiddleware (path-exempts
agent-card per A2A spec 4.1, returns HTTP 401, stashes scope['user']),
and the serve(auth=) kwarg.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(auth): expert-review fixes for #566 (RFC 6750, async-validator boot reject, OPTIONS, telemetry)
Address findings from code-reviewer / security-reviewer / ad-tech-protocol-expert
review:
- WWW-Authenticate header on every 401 (RFC 7235 §3.1, RFC 6750 §3).
Browsers and HTTP libraries that follow the spec now surface the
bearer challenge instead of treating the 401 as opaque.
- 401 body uses RFC 6750 §3.1 error codes ("invalid_token",
"error_description") instead of free-form "unauthenticated".
- OPTIONS preflight bypasses auth so CORS works for browser-origin
buyers — without this the preflight 401s and the buyer never gets
the chance to retry with a token.
- Async validator now rejected at boot in _wrap_a2a_with_auth via
inspect.iscoroutinefunction. Production deployments fail at
serve() time instead of on first traffic.
- Auth-rejection telemetry: each rejection branch logs a coarse
reason (missing_header / wrong_scheme / invalid_token / etc.) so
SOC dashboards can detect scanning. Validator exceptions still log
exception() for the operator stack.
- mcp_inner = _wrap_mcp_with_auth(mcp_inner, auth) — assign back so
a future refactor switching to fresh-callable wrappers doesn't
silently drop auth.
- serve(auth: BearerTokenAuth | None = None) typed instead of Any.
- Tests added: WWW-Authenticate header, RFC 6750 body shape, OPTIONS
bypass, async-validator boot rejection, sync validator passes
boot, validator-exception 401 through full ASGI stack.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(auth): drift-guard _A2A_DISCOVERY_PATHS against a2a-sdk route renames
Reviewer flagged that the hardcoded /.well-known/agent-card.json
literal could silently leak auth on a renamed route if a2a-sdk's
canonical path moves. Two changes:
1. Reference a2a.utils.constants.AGENT_CARD_WELL_KNOWN_PATH directly
so the 1.0 path tracks a2a-sdk automatically. Legacy 0.3 alias
/.well-known/agent.json stays as a literal (no constant for it).
2. New test_discovery_paths_match_a2a_sdk_routes inspects every path
that create_agent_card_routes registers and asserts each is in
_A2A_DISCOVERY_PATHS. If a future a2a-sdk version adds a new
well-known route (extensions, capability descriptor, etc.), this
test fails first — adopters update the frozenset rather than
silently 401'ing on the renamed/added route.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
0 commit comments