google / google/adk-python

RemoteA2aAgent enforces HTTPS for agent cards, blocking plaintext A2A inside a service mesh (mTLS)

Aperta
#7,139 2 commenti 0 reazioni 1 assegnatario Rivendicata da @surajksharma07 Vedi su GitHub
request clarification
Lingua principale
Python
Stelle
21.5k
Fork
4k
Merge medio
1g 14h
PR unite (30g)
37

Descrizione

### What happened

`RemoteA2aAgent` enforces that an agent card's URL — and every RPC target URL inside the resolved card — must be `https`, unless the host is loopback. This is enforced client-side in `src/google/adk/agents/remote_a2a_agent.py` (ADK `2.9.1`):

- `_resolve_agent_card()` rejects a non-loopback `http://` **card source URL** with:
> `Agent card URL must use https, or http on a loopback host: `
- `_validate_card_rpc_targets()` rejects a resolved card whose **RPC target URLs** are non-loopback `http://` with:
> `Agent card RPC URL must use https, or http on a loopback host: `

(`_is_loopback_host()` only permits `localhost`, `*.localhost`, and loopback IPs.) There doesn't appear to be an opt-out (flag, config field, or env var).

### Why this is a problem: A2A inside a service mesh (mTLS)

A very common production topology for multi-agent A2A is Kubernetes + a service mesh (Istio / Cloud Service Mesh, Linkerd) with **STRICT mTLS**. In that model:

- The application speaks **plaintext `http://`** to the peer's in-cluster DNS name (e.g. `http://research.agents.svc.cluster.local/a2a/app/...`).
- The **sidecar proxy transparently upgrades every hop to mTLS**, and authorization is enforced by mesh identity (SPIFFE) + `AuthorizationPolicy`.

This is the mesh's entire design: apps stay plaintext, the mesh provides confidentiality + peer authentication. But ADK's client-side gate refuses plaintext to non-loopback hosts, so the **first delegation fails at card resolution** with `AgentCardResolutionError`. The security property the `https` requirement stands in for (no plaintext MITM) is already guaranteed by the mesh — so the gate is redundant here, yet there's no way to say so.

### Minimal repro

```python
from google.adk.agents.remote_a2a_agent import RemoteA2aAgent

# Non-loopback http card URL — realistic in-cluster A2A address behind a mesh.
agent = RemoteA2aAgent(
name="research",
agent_card="http://research.agents.svc.cluster.local/a2a/app/.well-known/agent-card.json",
)
# On first use -> AgentCardResolutionError:
# "Agent card URL must use https, or http on a loopback host: ..."
```

The underlying transport is fine with `http` — only this ADK-level check blocks it.

### Current workaround (and why it's not great)

Passing a **pre-constructed `AgentCard` object** (rather than a URL/file source) skips both checks — `_validate_card_rpc_targets()` returns early when there is no `http(s)` source, and `_resolve_agent_card()` is never called — so the plaintext POST then flows and the mesh wraps it in mTLS. But this forces callers to give up ADK's lazy live-card fetch and hand-build/hard-code the card + RPC URL, which is exactly the discovery ADK otherwise does for you.

### What we'd like to discuss

Would the maintainers be open to an **opt-in** escape hatch so operators who know they're inside a trusted transport (a mesh) can allow non-loopback `http`? A few shapes, from least to most granular:

1. A per-instance flag, e.g. `RemoteA2aAgent(..., allow_insecure_http=True)` (or on `A2aRemoteAgentConfig`), applied to both the card fetch and the RPC-target validation.
2. An env / global toggle (e.g. `ADK_A2A_ALLOW_INSECURE_HTTP=1`) for cluster-wide deployments.
3. A configurable trusted-host / CIDR allowlist that widens the loopback carve-out.

Opt-in (default stays https-only) keeps the secure-by-default behavior while unblocking the mesh use case. Happy to send a PR if you can point me at the preferred shape.

### Environment

- `google-adk` 2.9.1
- Deployment: GKE + Cloud Service Mesh (managed Istio), namespace-wide STRICT `PeerAuthentication`
- A2A over `RemoteA2aAgent` with in-cluster DNS peer URLs

Guida per i contributori

Apri la guida per i contributori

Valutazione

Questa issue non è ancora stata valutata.

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.