Architecture
How ohwow implements the A2A protocol as both a server and client.
System Overview#
ohwow operates in two modes simultaneously. As a server, it accepts incoming A2A requests from external agents. As a client, it makes outbound requests to external A2A agents.
System architecture
┌─────────────────────────────────────────────────────────┐
│ ohwow Platform │
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌────────────┐ │
│ │ A2A Server │ │ Agent Core │ │ A2A Client │ │
│ │ │───▶│ │──▶│ │ │
│ │ /api/a2a │ │ Execution │ │ Outbound │ │
│ │ Agent Card │ │ Engine │ │ Requests │ │
│ └──────┬───────┘ └──────────────┘ └─────┬──────┘ │
│ │ │ │
│ Auth │ Scopes Discovery │
│ Rate │ Limit & Tasks │
│ │ │ │
└─────────┼─────────────────────────────────────┼─────────┘
│ │
▼ ▼
┌──────────────┐ ┌──────────────┐
│ External │ │ External │
│ Agents │ │ A2A Agents │
│ (inbound) │ │ (outbound) │
└──────────────┘ └──────────────┘ohwow as Server#
When an external agent calls your ohwow instance, the request flows through several layers:
Inbound request flow
External Agent
│
▼
┌─────────┐ ┌─────────┐ ┌──────────┐ ┌──────────┐
│ Auth │───▶│ Scope │───▶│ Rate │───▶│ Agent │
│ Check │ │ Check │ │ Limit │ │ Execute │
│ │ │ │ │ │ │ │
│ Bearer │ │ Verify │ │ Sliding │ │ Run the │
│ Token │ │ scopes │ │ window │ │ task │
└─────────┘ └─────────┘ └──────────┘ └────┬─────┘
│
▼
┌──────────┐
│ Sanitize │
│ Response │
│ │
│ Strip │
│ metadata │
└──────────┘- Authentication: Bearer token with
ohw_a2a_prefix is validated against hashed keys in the database. - Scope check: The requested method is checked against the key's allowed scopes. For example,
tasks.createis required formessage/send. - Rate limiting: Sliding window rate limiter enforces per-minute and per-hour limits per API key.
- Execution: The matched agent processes the task using the standard execution engine.
- Sanitization: Internal metadata (workspace IDs, costs, model config) is stripped before the response is returned.
ohwow as Client#
When your agents need to call external A2A agents, the outbound flow handles discovery, authentication, and result storage:
Outbound request flow
Your ohwow Agent
│
▼
┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
│ Discover │───▶│ Auth │───▶│ Send │───▶│ Store │
│ │ │ │ │ Task │ │ Result │
│ Fetch │ │ Use the │ │ │ │ │
│ Agent │ │ saved │ │ JSON-RPC │ │ Summary │
│ Card │ │ creds │ │ request │ │ only │
└──────────┘ └──────────┘ └──────────┘ └──────────┘- Discovery: Fetch and cache the remote agent's Agent Card to understand its capabilities.
- Authentication: Use the credentials configured in the connection (API key, OAuth, bearer token, or mTLS).
- Task send: Dispatch the JSON-RPC request and wait for the result.
- Result storage: By default, only a summary (max 500 characters) is stored. Raw results are not persisted unless
store_resultsis enabled.
ohwow-connect Relay#
For agents running on private networks (behind firewalls, on localhost), the ohwow-connect relay acts as a bridge. It runs locally and creates a secure tunnel to the ohwow platform.
Note
See the full ohwow-connect setup guide for Docker and npm installation instructions.