---
title: 'ADR 0010: A2A architecture'
description: Agent-to-agent invocation through the gateway, with a key registered out of band and a connection that is unusable until it verifies.
label: '0010 A2A architecture'
---

## Context

Your agent needs to invoke an agent in another organization, and theirs needs to
invoke yours. Two problems:

**Identification.** "I am `logistics-agent` from Partner Ltd" is not a
verifiable claim.

**Authorization.** A verified remote agent is still an external party, and
verifying who they are says nothing about what they should be allowed to do on
your side.

The obvious implementation is an API your service exposes for partners, with
some authentication in front of it. That is a second authorization path.

## Decision

**A registered connection, with the remote party's key, verified before use.**

```text
register    →  PENDING, with remote_public_key
verify      →  fetch their passport, check it against that key
invoke      →  through the gateway, full pipeline
block       →  immediate, including in-flight sessions
```

**The connection is unusable until its passport verifies.** Not a warning — it
does not work.

**Invocation goes through the gateway.** `POST /gateway/v1/a2a/invoke` runs the
same twelve-stage pipeline. `tool.kind` and `tool.protocol` are both `A2A`.

**`capabilities` on the connection is your side of the contract** — what you are
willing to invoke on them, or accept from them. Not what they claim to offer.

**Symmetric.** A remote agent invoking you must have a verified connection, a
registered capability, and your policy's permission. A remote caller gets no
shortcut.

**Blocking is immediate**, and reversible.

## Alternatives

**Expose a partner API directly from your service.** The conventional answer,
and it creates a second authorization path with its own authentication, its own
logging and its own policy — none of which is the Veefore pipeline.

Then "what is an agent allowed to do" has two answers depending on which door
it came through, and only one of them is in the audit trail.

**Trust a presented passport without registering a key.** Simpler onboarding: a
peer presents a passport, you verify the signature against the issuer's
published key, done.

This verifies the document is authentic. It does not verify that *this* party is
the party you intended to deal with — anyone with a valid passport from any
Veefore deployment would pass. Registering the expected key is what binds the
connection to a specific counterparty.

**Federated trust: trust any agent from an organization you trust.** Scales
better. It also means the counterparty's own provisioning decisions become your
authorization decisions, which is a larger grant than most relationships
warrant.

**Authorize from the remote passport's capability list.** It is signed and it
lists capabilities. Those are *their* capabilities in *their* system, which has
nothing to do with what you want them doing in yours. Your connection's
capability list is the relevant one.

**No A2A in the starting product.** Defensible — it is the least-used surface.
It is also the one where getting it wrong is most expensive, and the one most
likely to be built badly outside Veefore if Veefore does not provide it.

## Consequences

**Key exchange is a manual, out-of-band step**, and it is the step where a
shortcut undoes the mechanism.

:::danger Fetching the key from the endpoint you are about to trust proves nothing
Whoever controls that endpoint controls both halves. The key must come through
an independently authenticated channel: a signed email, an access-controlled
document, an existing mutual-TLS link, a phone call.
:::

**Re-verification is needed when they rotate.** A connection that silently
stopped verifying is a connection you are not using and have not noticed.
Scheduled re-verification is in [Operate it](/journey/operate).

**Passport verification does not establish standing.** Only the issuer knows
whether that agent is currently revoked, suspended or under investigation. This
is why trust evidence exists alongside it —
`ORGANIZATION_VERIFICATION` with an expiry turns "we checked them once" into
something policy can test and that lapses visibly.
[ADR 0007](/architecture/adr/0007-trust-evidence)

**Symmetry costs a round trip on inbound calls.** A remote agent invoking you
goes through the pipeline rather than hitting an endpoint directly. That is the
point: one pipeline, one audit trail, one place to look.

**Amount ceilings are worth applying even to small-value partners.** A bounded
ceiling limits what a compromise on their side can do on yours, and the bound
costs nothing when their legitimate traffic is well below it.

**A2A is the one place the passport is load-bearing**, and the only place a
signature verification is part of an authorization flow rather than an identity
claim. Worth knowing when reading
[ADR 0006](/architecture/adr/0006-passport-format), which is otherwise emphatic
that passports are never the decision — the passport establishes *who*, and
your connection and policy establish *whether*.

## Related

- [A2A](/build/a2a)
- [Agent Passport](/concepts/passport)
- [Trust evidence](/concepts/trust)
- [A2A API](/reference/api/a2a)
