OpenA2A /specs
did:opena2a0.1 (draft)Provisional, filed with W3C, pending review

Decentralized Identifier Method

A W3C DID method where did:opena2a:<type>:<id> resolves over HTTP to a signed DID Document, so any verifier can fetch an agent's public key and trust endpoints.

The question it answers

What is this agent called, and how do I look it up?

If you know one thing already

It’s like DNS + a certificate authority's directory.

Why it exists

Before you can trust an agent, you have to be able to name it , and look that name up. On the web, a domain name resolves through DNS to an address, and a certificate ties that name to a key. Agents need the same thing: a stable, globally-unique identifier that anyone can resolve to a public key and a set of trust endpoints.

did:opena2a is that identifier. It is a W3C Decentralized Identifier method. A DID like did:opena2a:agent:acme/billing resolves, over plain HTTP, to a DID Documentcontaining the subject's verification key and service endpoints for trust lookup, signed proofs, and badges.

The identifier, decoded

Every did:opena2a identifier has three parts after the method prefix: a resource type, a resource id, and an optional fragment pointing at a key or endpoint.

did-method-opena2a.md, syntaxabnf
opena2a-did   = "did:opena2a:" resource-type ":" resource-id [ "#" fragment ]
resource-type = lowercase letters and "_"      ; agent, mcp_server, authority, ...
resource-id   = unreserved chars + ":" + "/" + "@"   ; case-preserving
fragment      = "#key-1", "#trust-lookup", ...

# Real identifiers
did:opena2a:registry:opena2a.org
did:opena2a:authority:gov.uk
did:opena2a:agent:acme/billing-agent#key-1
did:opena2a:mcp_server:@modelcontextprotocol/server-filesystem
Note

Why the id is case-preserving

The resource id is never lowercased, because scoped package names like @modelcontextprotocol/server-filesystem are case-sensitive. The method prefix and type, however, are always lowercase.

Registered resource types

registry
An OpenA2A Registry instance, the trust root itself.
authority
A naming authority (usually a domain) recognized as a root or delegated trust anchor.
publisher
A vetted publisher of one or more catalogued resources.
agent
An autonomous agent (A2A or otherwise).
mcp_server
A Model Context Protocol server.
ai_tool / llm / skill
A catalogued AI tool, large language model, or reusable agent skill.

What resolution returns

Resolving a DID returns a JSON-LD DID Document conforming to W3C DID Core. The key fields: a verificationMethodholding the Registry's Ed25519 public key, and service endpoints for trust queries.

DID Document (abridged)json
{
  "@context": ["https://www.w3.org/ns/did/v1", ".../ed25519-2020/v1"],
  "id": "did:opena2a:mcp_server:@modelcontextprotocol/server-filesystem",
  "verificationMethod": [{
    "id": "...#registry-key",
    "type": "Ed25519VerificationKey2020",
    "controller": "did:opena2a:registry:opena2a.org",
    "publicKeyMultibase": "z<base64 Ed25519 public key>"
  }],
  "service": [
    { "type": "TrustLookup", "serviceEndpoint": "https://api.oa2a.org/api/v1/trust/query?..." },
    { "type": "TrustProof",  "serviceEndpoint": "https://api.oa2a.org/api/v1/trust/proof?..." },
    { "type": "TrustBadge",  "serviceEndpoint": "https://api.oa2a.org/badge/..." }
  ],
  "created": "2026-02-15T19:24:01Z",
  "updated": "2026-05-14T08:11:33Z"
}
Key idea

The controller is the Registry

Notice the controller is did:opena2a:registry:opena2a.org, not the subject. The Registry holds the key that signs statements about every resource it names. That single fact defines the trust model below.

How resolution works

Read (resolve) is a single HTTP GET against a Registry you choose to trust. For signature verification, a consumer also consults the Registry's /.well-known/opena2a document for the full set of currently-valid keys (so a rotated key still verifies).

Resolving did:opena2a:agent:acme/billing
Consumerverifier
Registryresolver you trust
GET /api/v1/did/did:opena2a:agent:acme/billing
look up resource by type + id
200 · DID Document (application/did+ld+json)

Cache-Control: max-age=300

GET /.well-known/opena2a (valid keys)
publicKeys[], verify signatures against any
request response local / internal step

The honest trust model

did:opena2a is deliberately registry-mediated, not fully decentralized like did:key or a ledger method. The spec states the trade plainly:

“A verifier trusts a did:opena2a DID exactly as much as it trusts the Registry resolver it was configured with.”

In return for that trust, resolution yields far more than a key: a live trust score, signed proofs, scan history and badge endpoints. The spec is candid about the cost, a single reference Registry is a point of failure, and lists the mitigations: 5-minute cache headers, a signed offline trust bundle, key rotation with overlap windows, and federation (multiple registries resolving the same method).

If you know DNS and CAs

The web
did:opena2a
Domain name
Resource idagent:acme/billing
DNS resolver
Registry resolverGET /api/v1/did/…
CA root key
Registry signing keycontrols every DID Document
Key rotation + overlap
/.well-known/opena2a publicKeys[]old + new both valid
A directory you query, signed by an authority you choose to trust.

How it applies to agents

  • It gives every agent, tool, MCP server and authority one canonical name the rest of the stack can point at.
  • It is the identifier substrate beneath AIP, ATX and ATP, they all name their subjects with did:opena2a.
  • Because the controller key is the Registry's, verifying any signature about a subject reduces to verifying a Registry signature, one key to reason about, rotated transparently.