Skip to content

feat: A2A protocol plugin#10486

Open
benclarkeio wants to merge 5 commits intoopenclaw:mainfrom
benclarkeio:feat/a2a-plugin
Open

feat: A2A protocol plugin#10486
benclarkeio wants to merge 5 commits intoopenclaw:mainfrom
benclarkeio:feat/a2a-plugin

Conversation

@benclarkeio
Copy link

@benclarkeio benclarkeio commented Feb 6, 2026

Summary

Depends on #9999 (Docker fixes) — merge that first.

  • Adds A2A (Agent-to-Agent) protocol plugin under extensions/a2a/
  • Exposes the gateway as an A2A-compatible agent with inbound API key auth (secure by default)
  • Provides send_message_to_agent and get_agent_card tools for calling remote A2A agents
  • Supports outbound auth with per-URL header/credential config
  • Includes key management commands (a2a generate-key, a2a list-keys, a2a revoke-key)
  • Adds comprehensive docs at docs/plugins/a2a.md covering setup, authentication, and Tailscale Funnel for public access

Test plan

  • Enable plugin in config and verify agent card at /.well-known/agent-card.json
  • Send A2A message/send via curl with API key and confirm response
  • Test outbound send_message_to_agent tool against a remote A2A agent
  • Verify inbound auth rejects unauthenticated requests
  • Run pnpm vitest run extensions/a2a for unit tests
  • Test Tailscale Funnel public access end-to-end

🤖 Generated with Claude Code

Greptile Overview

Greptile Summary

  • Adds a new extensions/a2a/ plugin that exposes the gateway as an A2A agent (agent card endpoint + /a2a JSON-RPC), including inbound API key auth and outbound per-URL auth headers.
  • Implements an A2A→OpenClaw bridge via OpenClawAgentExecutor, plus tools for calling remote A2A agents (send_message_to_agent, get_agent_card).
  • Adds CLI commands for inbound key management and updates Docker/dev setup docs/scripts to support workspace-based extension installs.

Confidence Score: 3/5

  • This PR is close to mergeable but has a few concrete runtime/logging issues to fix first.
  • Core functionality and auth model look coherent, but the extension currently contains production console.log debug dumping gateway payloads/frames (noise + potential data exposure) and uses crypto.randomUUID() without importing node:crypto, which can cause runtime failures depending on the Node/bundling environment.
  • extensions/a2a/src/executor.ts, extensions/a2a/src/gateway-call.ts, extensions/a2a/src/tool.ts

(3/5) Reply to the agent's comments like "Can you suggest a fix for this @greptileai?" or ask follow-up questions!

benclarkeio and others added 4 commits February 6, 2026 00:26
The Docker setup scripts generated a gateway token and passed it via the
OPENCLAW_GATEWAY_TOKEN env-var, but the gateway reads the config file
token first and silently ignores the env-var.  This caused a token
mismatch on first run (interactive onboard may store a different token)
and on re-runs (new random token generated, config not updated).

Additionally, Docker routes requests through the bridge network so the
gateway does not recognise the Control UI as a local client, causing a
device-pairing chicken-and-egg on first connect.

Fix both scripts (docker-setup.sh, docker-setup.dev.sh) to reconcile
the config file after onboard: patch gateway.auth.token, gateway.bind,
and gateway.controlUi.allowInsecureAuth so the printed dashboard URL
works immediately.

Also adds:
- Dockerfile: ensure node user exists on Docker Desktop for Mac
- docker-setup.dev.sh: dev workflow that builds from local source
- docker-compose.dev.yml: dev overlay with source bind-mount
- docs: tokenized dashboard URL, dev mode section, bind explanation

Co-Authored-By: Claude Opus 4.6 <[email protected]>
@openclaw-barnacle openclaw-barnacle bot added docs Improvements or additions to documentation docker Docker and sandbox tooling labels Feb 6, 2026
Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

2 files reviewed, 3 comments

Edit Code Review Agent Settings | Greptile

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Feb 6, 2026

Additional Comments (3)

extensions/a2a/src/executor.ts
Debug logging leaks data

These console.log(...) calls will execute in production and dump gateway payloads/response text to stdout (e.g. result.data, payloads, responseText). That’s both very noisy and can leak sensitive content depending on what the agent returns. Please remove these logs or route them through the plugin logger at an appropriate level with redaction.

Prompt To Fix With AI
This is a comment left during a code review.
Path: extensions/a2a/src/executor.ts
Line: 243:246

Comment:
**Debug logging leaks data**

These `console.log(...)` calls will execute in production and dump gateway payloads/response text to stdout (e.g. `result.data`, `payloads`, `responseText`). That’s both very noisy and can leak sensitive content depending on what the agent returns. Please remove these logs or route them through the plugin logger at an appropriate level with redaction.

How can I resolve this? If you propose a fix, please make it concise.

extensions/a2a/src/gateway-call.ts
Verbose frame logging

callGateway logs raw gateway frames/payloads via console.log (including errors and response payloads). In normal operation this will spam logs, and the payloads may contain secrets / user content. Please remove these logs or replace with structured debug logging + redaction behind a disabled-by-default flag.

Prompt To Fix With AI
This is a comment left during a code review.
Path: extensions/a2a/src/gateway-call.ts
Line: 2430:2433

Comment:
**Verbose frame logging**

`callGateway` logs raw gateway frames/payloads via `console.log` (including errors and response payloads). In normal operation this will spam logs, and the payloads may contain secrets / user content. Please remove these logs or replace with structured debug logging + redaction behind a disabled-by-default flag.

How can I resolve this? If you propose a fix, please make it concise.

extensions/a2a/src/executor.ts
crypto may be undefined

This uses crypto.randomUUID() without importing from node:crypto or otherwise guaranteeing globalThis.crypto exists. In many Node/bundled environments this throws ReferenceError: crypto is not defined, which would break A2A execution. Please import randomUUID from node:crypto (as you already do in extensions/a2a/src/gateway-call.ts) or otherwise ensure a safe UUID generator is available.

Also appears in: extensions/a2a/src/tool.ts (messageId generation).

Prompt To Fix With AI
This is a comment left during a code review.
Path: extensions/a2a/src/executor.ts
Line: 2160:2162

Comment:
**`crypto` may be undefined**

This uses `crypto.randomUUID()` without importing from `node:crypto` or otherwise guaranteeing `globalThis.crypto` exists. In many Node/bundled environments this throws `ReferenceError: crypto is not defined`, which would break A2A execution. Please import `randomUUID` from `node:crypto` (as you already do in `extensions/a2a/src/gateway-call.ts`) or otherwise ensure a safe UUID generator is available.

Also appears in: `extensions/a2a/src/tool.ts` (messageId generation).

How can I resolve this? If you propose a fix, please make it concise.

@Zephyr-Blessed
Copy link

Hey @benclarkeio 👋

Really cool to see this — we've been working on A2A support independently and just discovered your PR. Rather than duplicate effort, wanted to share some ideas we've been exploring that might complement what you've built here.

Per-contact trust tiers

One thing we spent a lot of time on is the security model for who gets to do what when they message your agent. The core insight: trust should be per-relationship, not global.

We designed a tiered system:

Trust Level What they get Example
blocked Rejected Spammers
open Chat only, no tools Unknown agents
skilled Specific skills + tools A platform like AI Truism
friend Real tool access (calendar, messaging) Your friend's agent booking a meeting

Each contact gets explicit tool grants:

{
  "contacts": {
    "https://alice.openclaw.ai": {
      "name": "Alice's Agent",
      "trust": "friend",
      "tools": ["calendar", "web_search", "message"],
      "skills": ["*"]
    },
    "https://ai-truism.vercel.app": {
      "trust": "skilled",
      "tools": ["web_search"],
      "skills": ["volunteering"]
    }
  }
}

The big use case: your agent talks to your friend's agent to arrange a meeting. Both agents need real tool access (calendars), but a random agent on the internet shouldn't get the same permissions.

Approval flow

When defaultTrust is "approval" and an unknown agent contacts you, the request gets queued and the owner gets notified. They can approve with specific grants:

openclaw a2a approve https://new-agent.com --trust friend --tools calendar,message

Rate limiting

We also built a sliding-window rate limiter for the plugin runtime — both per-IP and per-sender-URL, so agents can't hammer each other's tokens.

Our design doc

Full writeup here if you're interested: https://github.com/Zephyr-Blessed/openclaw-a2a/blob/main/DESIGN.md

Happy to help implement any of this on your PR if you think it's a useful direction. No point building the same thing twice! 🌿

@Zephyr-Blessed
Copy link

Also, we opened a draft PR for adding sessions.spawn() and rateLimit to the plugin runtime: #16558 — which would let any plugin (including yours) spawn isolated sessions with restricted tool policies. Might be useful for the executor side of things if you want per-contact tool restrictions enforced at runtime rather than just via system prompt.

mdlmarkham pushed a commit to mdlmarkham/openclaw that referenced this pull request Feb 14, 2026
Extends inputProvenance to support agent-to-agent tool invocations:
- Add 'tool_invocation' to InputProvenanceKind enum
- Add skill and mode fields to InputProvenance type
- Update normalizeInputProvenance to handle new fields
- Add isToolInvocationProvenance and isCrossSessionProvenance helpers
- Update agent_call and debate_call tools to use tool_invocation kind

This enables agents to receive structured provenance when called via
agent_call/debate_call, allowing skill routing and mode tracking.

Related: openclaw#15154, openclaw#10486, openclaw#7516
mdlmarkham pushed a commit to mdlmarkham/openclaw that referenced this pull request Feb 16, 2026
Extends inputProvenance to support agent-to-agent tool invocations:
- Add 'tool_invocation' to InputProvenanceKind enum
- Add skill and mode fields to InputProvenance type
- Update normalizeInputProvenance to handle new fields
- Add isToolInvocationProvenance and isCrossSessionProvenance helpers
- Update agent_call and debate_call tools to use tool_invocation kind

This enables agents to receive structured provenance when called via
agent_call/debate_call, allowing skill routing and mode tracking.

Related: openclaw#15154, openclaw#10486, openclaw#7516
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docker Docker and sandbox tooling docs Improvements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

Comments