Skip to main content
Version: Latest (1.9.x dev)

A2A Governance

Enterprise only

Not included in DVARA Open Source.

The Agents section of the sidebar carries the Agent-to-Agent (A2A) surfaces alongside the MCP ones. Where Agents & MCP governs the tools your agents call, these pages govern the other agents your agents call — every agent-to-agent hop through the A2A plane.

The A2A plane is served by the gateway under /a2a, with its own governance engines and its own tamper-evident audit chain, fully separate from the MCP plane's. Its Platform-wide pages therefore live beside — not inside — the MCP pages.

Roles

The A2A Platform-wide pages are platform-scoped: owner and policy-admin can view and manage them. The approval queue is cross-workspace. See the role-access matrix.

When the A2A catalog is on, an owner also sees Agents → Catalog: where each source was last read, and Sync now. See the A2A catalog.

A2A agents​

Open Agents → A2A Agents in the sidebar. This is the registry of peer agents your workspaces are allowed to reach — a hop can only target an agent that is registered here.

Agent list​

Lists every registered peer agent with its agent ID, workspace, endpoint URL, auth scheme, status pill, and actions. Use the Workspace dropdown to narrow the list; workspace-role callers see only their own workspace's agents.

From 1.8.5 an active agent whose endpoint is http:// carries a Not HTTPS badge. A2A requires HTTPS, so the gateway sends that agent nothing. Edit the endpoint to https://, or disable the agent. Flightdeck also names each such agent in a warning at startup.

From 1.9.0 each agent in the list shows whether Flightdeck could reach it at the last check, so you do not have to open agents one by one. Workspace viewers, who cannot open the agent page, see it too. The badge says one of:

  • Reachable — Flightdeck read the peer's Agent Card. Reachable, card changed means the card it read is not the one stored; open the agent and click Refresh card.
  • Card unreadable — the peer answered, but not with a usable Agent Card.
  • Unreachable — the peer did not answer.
  • Address not allowed — the egress rules refused the peer's address, so nothing was sent.
  • No supported binding — the agent was saved with Save anyway and its card offers no binding DVARA supports, so calls to it are refused.
  • Not checked yet — Flightdeck has not checked the agent.

Each badge shows when the check ran, and the reason when you hover over it. Screen readers read the reason too. The list shows the last stored result and contacts no peer when it opens. Flightdeck checks every agent every 15 minutes by default, and Check now on the agent page checks one straight away. The result is what Flightdeck's network sees; a gateway can see a different result.

Create / edit agent​

Click New Agent to register a peer with:

  • Agent ID — human-readable slug, unique per workspace (e.g. billing-agent, research-agent).

  • Workspace ID — the workspace this agent belongs to (required on create).

  • Endpoint URL — the peer agent's base URL (required). Validated at save — private, loopback, link-local, and cloud-metadata addresses are rejected (SSRF protection), the same as MCP servers. From 1.8.5 an active agent's endpoint must be https://; anything else is refused with A2A_ENDPOINT_NOT_HTTPS. A disabled or suspended agent may keep an http:// endpoint.

  • Auth scheme — how DVARA authenticates to the peer: From the Agent Card (from 1.8.4, the default for a new agent), API_KEY, HTTP (bearer), OAUTH2, OPENID_CONNECT, or MUTUAL_TLS. From the Agent Card reads the peer's card and takes the one kind of scheme it declares; if the card cannot be read, declares none, or declares more than one kind, the save is refused and you choose. A scheme you choose is compared with the card, and a mismatch is shown as a warning on the form and as a Card mismatch badge in the list. It never blocks the save or the hop. See how DVARA authenticates to the peer.

  • Credential Ref — the name of a credential stored in this agent's workspace. It cannot name a vault path, a platform credential, or another workspace's credential.

  • Auth mode — STORED (DVARA resolves the agent's own credential) or DELEGATED (on-behalf-of — DVARA forwards the caller's X-DVARA-Delegated-Authorization token so the peer enforces that end user's permissions; a DELEGATED agent called without the token is rejected with A2A_DELEGATED_TOKEN_REQUIRED).

  • Agent Card — optional JSON Agent Card cached for discovery.

  • Skills allow-list — the per-workspace list of skills that Agent Card discovery advertises for this agent. Empty = advertise all skills the peer publishes.

  • Status — ACTIVE, SUSPENDED, or DISABLED (edit only). A hop to a non-ACTIVE agent is rejected with A2A_AGENT_UNAVAILABLE.

  • Save anyway if the peer's Agent Card offers no binding DVARA supports — from 1.9.0. DVARA calls peers over JSON-RPC (A2A 0.3 or 1.0) or HTTP+JSON (A2A 1.0), and does not support gRPC. When the card read on save offers neither, the save is refused and the message lists what the card offers. Tick this box only for a special case: the agent is saved, the choice is recorded in the audit log, and calls to the agent are still refused until its card offers a supported binding. If the card cannot be read, the save goes ahead without it. Refresh card does not store a card that offers no supported binding unless this box is ticked on the agent. Workspace admins and developers see the same box on their agent page. See bindings DVARA supports.

  • Fetch the card's key set (jku) — from 1.9.0, off by default. Lets DVARA fetch the key set a signature on the peer's Agent Card points to, when no key is pinned. DVARA fetches it only from the agent's registered address and through the same address checks as a call. A card checked with a key from it shows as Self-signed, never Verified. Each change is recorded in the audit log. Workspace admins and developers see the same box on their agent page.

An agent ID the workspace already uses, on create or on a rename, is refused with A2A_AGENT_DUPLICATE, naming the ID. From 1.8.4 the refusal shows on the form and the values you entered stay; before, it showed as an unexpected error. From 1.8.4 a new agent ID that contains :: is refused with A2A_AGENT_ID_INVALID; an existing agent keeps its ID.

Register the endpoint and authentication first, then fetch the Agent Card and review its advertised skills and trust result before sending a governed hop. After the first call, use the hop list to confirm policy, identity, approval, and delegation outcomes. This sequence distinguishes a discovery or trust problem from a runtime message failure.

A2A card signing​

From 1.9.0, an owner opens Agents → Card Signing to make the key DVARA signs the Agent Cards it serves with. There is one key for the whole install.

  • Create signing key makes the first key. Gateways sign cards with it once they receive the next configuration, within seconds.
  • Rotate key makes a new key. The old key stops signing, and stays published for 30 days so cards signed with it still check.
  • The page shows each key's id, state and dates. It never shows a private key.

The key is stored encrypted with the encryption master password (DVARA_ENCRYPTION_MASTER_PASSWORD). Set the same value on Flightdeck and on every gateway before you make a key: Flightdeck cannot make one without it, and a gateway with a different value serves cards unsigned and records A2A_CARD_SIGNING_FAILED in the audit log. Making and rotating a key are recorded too.

A2A policies​

A2A policies decide which hops are allowed — which caller may reach which target agent or requested skill. They are a separate engine and a separate store from the LLM/MCP policies, authored in the A2A policy DSL with the same lifecycle you already know: Draft → Active → Archived, versioned, with rollback and a dry-run validator.

A2A policies have no dedicated page — manage them through Flightdeck GitOps export/import, where they appear under the a2a_policies section of the exported document. A malformed DSL is rejected at import with INVALID_A2A_POLICY_DSL; a denied hop returns A2A_POLICY_DENIED (403). Policy changes hot-reload across the fleet within one config-poll interval — no restart.

Hop audit​

Open Audit in the sidebar and select the A2A plane in the plane selector. The A2A plane writes to its own tamper-evident audit chain (separate from the shared LLM/MCP chain), so its events appear under their own tab.

Each row is one hop event — A2A_HOP_INTENT, A2A_HOP_RESULT, A2A_HOP_DENIED, A2A_DELEGATION_RECORDED, A2A_PII_DETECTED, A2A_LOOP_DETECTED, A2A_APPROVAL_* — carrying its caller, target agent, requested skill, policy decision, and workspace. Click a row to expand its signed envelope and confirm the chain is intact — any gap or altered payload breaks the tamper-evident chain and is visible here.

A2A Traffic​

Open A2A Traffic to list the hops themselves, with each hop's chain and depth. From 1.9.0 the Protocol column and the hop detail show the A2A version and binding DVARA used for the peer, such as 1.0 · JSONRPC; a hop refused before it was sent shows none. Filter by workspace, agent and skill. From 1.8.5 a hop that the delegation guard let through in observe mode, but would have refused, shows "would refuse: " and the reason (cycle, depth_exceeded or chain_required). The mark also shows on the hop detail and on the session and conversation timelines. Tick Would refuse only to list just those hops. A hop refused in enforce mode shows as refused, as before. From 1.9.0 a hop whose signed delegation chain was refused shows a red "chain refused: " mark with the group (expired, scope widened or invalid), and the hop detail's Verified delegation row names the error code. From 1.9.0 a hop that ran on a verified chain shows a green "chain verified" mark with the chain's depth, and the hop detail shows whose authority it was (the agent that started the chain and the agent that used it), the skills it was narrowed to, the agents it could be shown to, and a short digest that names the chain. DVARA keeps only these facts on the hop, never the signed chain itself. A hop with no chain, or with a refused chain, shows none. The session and conversation timelines show the same mark, and the JSON export includes it. The workspace's A2A audit page shows verified and refused chains too, and from 1.9.0 also names the starting agent and the acting agent.

Because the A2A chain uses the same signing secret and algorithm as the shared chain, the same integrity verification applies, and A2A events flow into the SIEM exporters and the compliance reports alongside the rest.

Open an A2A session or conversation to follow its chronological hop timeline. Both detail pages provide a JSON export containing the workspace, identifier, and recorded hops. A2A → Analytics breaks activity down by error code, policy decision, authentication mode, and approval outcome. Pair that JSON with the matching audit export when an incident needs a portable evidence bundle.

Withdraw a signed delegation chain​

From 1.9.0, open Agents → Revocations to stop a signed delegation chain (X-Dvara-Delegated-Authorization: DvaraDeleg …) before it expires. Owners and policy admins can use it for any workspace.

From 1.9.0 a workspace admin can do the same for their own workspace, on Agents → A2A Revocations. They see and change only their workspace's revocations, with the same rules and audit events. Developers and viewers in the workspace can see the list but cannot change it.

  • One block. Enter the workspace (owners and policy admins) and the block's jti. You find it in the block_ids of the hop's A2A_DELEGATION_VERIFIED audit event. Other chains from the same agents keep working.
  • One issuer. Enter the agent exactly as the chain names it, by its registry id or its workload identity; both are matched. Every chain with a step that agent signed is refused. On a hop that ran on a verified chain, the hop detail has a Revoke issuer link that fills it in.

Every Gateway refuses such a chain within about 5 seconds, with 403 a2a_delegation_invalid and the reason revoked, even while the configuration bundle is out of date. A block revocation lasts 25 hours unless you choose a length (a step of a chain lives at most a day). An issuer revocation lasts until you lift it. Each revocation and each lift is in the audit log (A2A_DELEGATION_REVOKED, A2A_DELEGATION_REVOCATION_LIFTED).

Approval queue​

Open Approvals and select the A2A plane. Hops that match a workspace's approval rules (by requested skill or by target agent) pause on a durable, cross-pod gate until a reviewer decides — the A2A analogue of the MCP approval queue.

Pending tab​

Lists every A2A hop currently awaiting a decision, with caller, target agent, requested skill, workspace, and the time it was raised. Approve releases the paused hop; Deny rejects it with A2A_APPROVAL_DENIED (403). The decision is written to a durable, cross-pod store, so it releases the hop on whichever DVARA Gateway pod is holding it, within one poll interval — even if another pod serves Flightdeck.

History tab​

The decision log — every resolved A2A approval with its action, reviewer, and timestamp. Resolving emits A2A_APPROVAL_RESOLVED on the A2A own-chain, capturing the human actor.

The sidebar's Approvals entry carries a live count of pending A2A approvals so reviewers see new requests without polling the page.

A hop matching a rule that is not resolved before its timeout applies the workspace's default action (deny, safe by default). A resolve targeting an approval that already expired or was decided returns A2A_APPROVAL_NOT_FOUND (404). Workspace users resolve their own workspace's A2A approvals from the workspace approvals.

Where to go next​