A2a ProtocolCAUTION
A framework for building agentic apps
Overview
A framework for building agentic apps
5977febf67f1OBSERVED · 2026-10-14What it tells the agent
The instruction file, verbatim from the audited commit — this is the text the model reads, and the surface the audit's instruction layer examines. Quoted here so you can judge it without cloning anything.
---
name: a2a-protocol
description: >-
How agent-native apps discover, authenticate with, and call each other over
A2A. Use when connecting one app to another, debugging a remote agent that
won't authenticate, exposing skills to peers, or calling agents from scripts.
scope: dev
metadata:
internal: true
---
# A2A Protocol (Agent-to-Agent)
## Rule
Agents call other agents over A2A, a JSON-RPC protocol for discovery and
delegation. Use it when work belongs to a different agent entirely — not the
local agent chat.
**No workarounds when A2A feels flaky.** The strong default is `ask_app` (or
`call-agent`) working reliably, full stop — not apps reaching around it. Do
not have app A generate and execute raw SQL against app B's database, and do
not expose B's internal tools directly to A as a substitute for delegation.
The receiving agent has context, skills, and guardrails the caller doesn't;
bypassing it to work around a flaky A2A call reintroduces exactly the bugs A2A
exists to prevent, and makes the real reliability problem invisible instead of
fixing it. If A2A delegation is unreliable, fix A2A — file it as a bug in the
delegation path (timeout handling, retries, typed terminal states), don't
route around it app by app.
Connecting app A to an Agent-Native app B is two independent things, and both
must be true:
1. **B is registered on A** as a `remote-agents/<id>.json` resource.
2. **A and B share a secret**, so A's signed JWT verifies on B.
Neither is a code change, and neither is symmetric. Registering B on A does not
let B call A. A hosted peer uses provider-specific endpoint and credential
metadata in place of the shared Agent-Native secret, but it still does not make
the provider's model or SDK an A2A endpoint.
## A2A is already mounted
`createAgentChatPlugin` calls `mountA2A` for every app, so a generated app
already serves:
- `GET /.well-known/agent-card.json` — public discovery, with a larger
authenticated capability view for verified sibling callers
- `POST /_agent-native/a2a` — JSON-RPC, authenticated
Do not add a `mountA2A` server plugin to enable A2A; it is on. Hand-mounting is
only for a bespoke card or a custom handler (see **Custom mount** below).
The client falls back to `POST /a2a` for external peers that only expose that
path. New agent-native apps should call `/_agent-native/a2a`.
## Registering a remote agent
A remote agent is **a row in the resources table, not a file on disk**. Path
`remote-agents/<id>.json`, owner `SHARED_OWNER`, content:
```json
{
"id": "analytics",
"name": "Analytics",
"description": "Queries analytics data across providers",
"url": "https://analytics.example.com",
"color": "#6B7280",
"cardUrl": "https://analytics.example.com/.well-known/agent-card.json",
"auth": {
"type": "bearer",
"credentialRef": "ANALYTICS_A2A_TOKEN"
}
}
```
`url` is the only required endpoint field. `cardUrl` is the optional discovery
URL for providers that do not serve `/.well-known/agent-card.json`. The client
reads the protocol version from the agent card. Pass `protocolVersion` directly
to `A2AClient` when a provider's card omits it. The optional `auth` descriptor is
non-secret connection metadata. Use
`{ "type": "bearer", "credentialRef": "..." }` for a vault-backed bearer
credential, or `{ "type": "oauth-client-credentials", "tokenUrl": "...",
"clientId": "...", "clientSecretRef": "...", "scope": "..." }` when the
peer issues OAuth client-credentials tokens. `credentialRef` and
`clientSecretRef` are references, never secret values.
Do not add `apiKey`, `env`, `skills`, or `token` values to a manifest. Resolve
credentials server-side from the workspace connection or vault. A direct
`A2AClient` call can pass `cardUrl` and `protocolVersion` while a provider
adapter is being used, but browser code must never receive the credential.
Four ways to create it, all writing the same row:
| Surface | Where |
| --- | --- |
| Settings → Agent → Sub-agents → Connect agent (owners and admins) | any app with the Settings shell |
| Agent page → Connections | apps mounting `AgentTabsPage` |
| Dispatch → Agents → Add external agent | workspace dispatch |
| The agent itself | `resources` tool, `action: "write"`, `--scope shared` |
The last one matters for template apps with no Code tab: "connect me to
https://analytics.example.com" is a complete instruction. `remote-agents/` is
whitelisted as a durable control path, so the write is workspace-scoped, and it
takes effect on the next `discoverAgents()` call with no restart.
First-party templates are seeded automatically and overlaid on top of manifests,
so `Mail`, `Calendar`, and friends appear without registration. In dev they
resolve to `http://localhost:<devPort>`; a manifest pointing at localhost is
ignored in production.
`call-agent` also accepts a raw URL, which skips registration entirely — useful
for one-off calls, useless for @-mentions.
### Checking a peer
`GET /_agent-native/agents/probe?url=<base>` reads the peer's card and makes one
authenticated no-op call, returning `reachable` and `authorized` as independent
fields. Omit `url` to probe every registered peer. Reachable-but-unauthorized is
the failure worth looking for: local dev runs the receiver unauthenticated, so a
mismatched secret only surfaces after deploy. The Connected Agents settings
section calls this on add and on open.
## Authentication
A2A authenticates with a **short-lived JWT the caller signs**, not a stored
bearer key. `Authorization: Bearer <jwt>`; HS256; 15-minute default TTL.
There is no per-peer API key anywhere in the system, which is why the manifest
has no field for one. A user identity assertion carries the authenticated
caller's email and is signed only with the deployment `A2A_SECRET`. Mint it
from authenticated request context; never accept an email from message params
or metadata as identity.
`verifyA2AToken` rejects MCP connect and OAuth tokens even though they can be
signed with the same secretTrust audit
CAUTIONgrade B · trust 89/100 Install with care. The audit found things worth knowing before you trust its output.
| Layer | What it checks | Result |
|---|---|---|
| L0 | Provenance & inventory | WARN |
| L1 | Static analysis of the code | NA |
| L2 | Instruction surface (what it tells the agent) | PASS |
| L3 | Class-specific surface | PASS |
| L4 | Behavioural (sandbox) | SKIPPED |
What the source does
- Filesystem
- none-observed
- Network
- none-observed
- Shell
- none-observed
- Dependencies
- pinned
- Secrets in source
- none-found
Findings (5)
.agents/skills/an
.agents/skills/content-product-development
.agents/skills/design-exploration
.agents/skills/turn-into-app
.agents/skills/visual-edit
Gates applied: no_behavioural_pass.
5977febf67f1full audit observations/trust-audit/skill/builderio__a2a-protocol.json · Report an issue / request a re-scanAudit history
Every audit this skill has had.
| Date | Source | Verdict | Grade | Score | Change |
|---|---|---|---|---|---|
| 2026-10-14 | 5977febf67f1 | CAUTION | B | 89 | first audit |
Questions
What does the A2a Protocol skill do?
A framework for building agentic apps
Is A2a Protocol safe to install?
With care. The audit graded it B (89/100) and found 5 things worth knowing before you trust this skill, listed below with the exact line each was found on.
What can A2a Protocol access on my machine?
The audit observed no filesystem, network or shell use at all in its source.
How current is this page?
The grade is for one exact copy of the source (5977febf67f1), read on 2026-10-14. The repository is watched, and a new audit runs when it changes — this is the first audit.
Add this badge to your README
Shows this page's audit result and links back to it. It updates when the audit does.
[](https://modelsatlas.com/skills/builderio/a2a-protocol/)
Not your listing, or something out of date? Claim or update your listing.