Google ADK as the Master Agent, Calling Amazon Bedrock over A2A A developer's cross-cloud benchmark revealed that reversing the master-worker roles between Google ADK and Amazon Bedrock exposed six interoperability defects, five of which local tests could not catch. The defects included an A2A protocol version mismatch, a missing server dependency, and an AWS IAM condition key mapping error that caused silent authentication failures. The fixes involved pinning the a2a-sdk version, adding the http-server extra, and using the correct OIDC condition key. This is the third run of the same cross-cloud currency benchmark, and the first with the arrow pointing the other way. A Google ADK master on Cloud Run Gemini 2.5 Flash, us-central1 owns the benchmark policy. It calls an Amazon Bedrock AgentCore worker Strands Agents on Nova Micro, us-east-1 over A2A v1.0 , and cross-checks the answer against an MCP exchange-rate tool. The previous run had Bedrock as the master and ADK as the worker. Reversing it was supposed to be a deployment change — the domain core is framework-independent, so the comparison logic never moved. What actually happened is that reversal exposed six interoperability defects, five of which no local test could have caught . That is the interesting part, so this article Most A2A demos stop at "the HTTP 200 came back." That is a smoke test, not an interoperability benchmark. The benchmark runs three modes so the cost of remote verification is separable from the cost of the work: | Mode | What runs | Purpose | |---|---|---| mcp only | ADK master calls the rate tool over MCP stdio | Baseline | a2a only | ADK master delegates to the AgentCore worker | Remote-agent cost | verified | Both, concurrently, then compared deterministically | Accuracy/overhead | Comparison is arithmetic, not a model judgement. Amounts and rates are Decimal . A model is never asked whether two numbers agree. This one was caught before deploying, and it dictated the whole worker design. strands-agents a2a pins a2a-sdk<0.4 — the A2A v0.3 wire methods message/send . google-adk a2a ==2.5.0 uses a2a-sdk 1.x — v1.0 SendMessage . A v1.0 client cannot call a v0.3 server, and the agent card carries no version negotiation. This is the same split that forced the A2UI extension out of the ADK agent in the first run of this project. It reappeared from the opposite side. The fix: use strands-agents for the agent loop only, and build the A2A v1.0 server surface from a2a-sdk directly. app/CurrencyWorker/main.py -- NOT strands.multiagent.a2a.A2AServer from a2a.server.request handlers import DefaultRequestHandler from a2a.server.routes import create agent card routes, create jsonrpc routes app = Starlette routes= create agent card routes AGENT CARD , create jsonrpc routes request handler, rpc url="/" , A test asserts the lockfile keeps a2a-sdk on 1.x, so a dependency bump cannot quietly reintroduce the mismatch. google-adk a2a does not install its own server dependency The Cloud Run container built fine, passed every local test, and then died on startup: ModuleNotFoundError: No module named 'sse starlette' File ".../google/adk/a2a/ compat.py", line 769, in attach a2a routes to app ADK's to a2a imports a2a.server.routes , which needs sse starlette , which arrives only with the a2a-sdk http-server extra. Neither google-adk a2a nor bare a2a-sdk pulls it in. Cost: one failed rollout. Both halves now declare a2a-sdk http-server . The coordinator holds no AWS keys. It federates: Cloud Run's metadata server mints a Google OIDC token, STS AssumeRoleWithWebIdentity exchanges it for temporary credentials, and requests are SigV4-signed. The trust policy looked obviously correct and was silently impossible: "Condition": { "StringEquals": { "accounts.google.com:aud": "currencybench-agentcore-worker", "accounts.google.com:sub": "1019138736740282766.." }} AWS does not map those condition keys to the claims their names suggest: | Condition key | Actual Google claim | |---|---| accounts.google.com:oaud | the token's aud | accounts.google.com:aud | the token's numeric client id azp | accounts.google.com:sub | the token's sub | The audience string was being compared against a number . Pin the audience with oaud , not aud . The natural next step — register accounts.google.com as an IAM OIDC identity provider — is wrong. AWS federates with Google natively. Creating an explicit provider switched STS to validating against that provider's thumbprint, and every exchange failed: