AID v2 Explained Draft
Annotated draft preview of the proposed AID v2 specification
Agent Identity & Discovery (AID) v2 - Explained Draft
Annotated preview for review and discussion
Date: 23 May 2026 Editor: Agent Community Status: Draft preview, not the current normative specification
This page is a shareable review artifact. It does not replace the current AID v1.2 specification. The purpose is to show the proposed v2 shape, explain why each major change exists, and make review easier than reading a raw line-by-line diff.
How To Read This Page
This page has two layers:
- Draft specification text uses normal normative language such as MUST, SHOULD, and MAY.
- Explainer notes explain the reason for a design choice and how it differs from v1.2.
The proposal is intentionally narrow:
AID is the first-contact endpoint-and-key anchor: DNS publishes the current endpoint and the current Ed25519 public key; rotation, attestation, request provenance, workload identity, and authorization compose above it.
What Changes From v1.2
| Area | v1.2 | v2 draft | Why |
|---|---|---|---|
| Record version | v=aid1 | v=aid2 | Clear wire-format break. |
| PKA key encoding | k=z... multibase/base58btc | k=<base64url> | Uses the same value as the Ed25519 JWK x member. |
| DNS key id | i=<kid> required with k | no i / no kid | The key id is derived from the key itself. |
HTTP signature keyid | compared to DNS i | RFC 7638 JWK thumbprint derived from k | Prevents a label from drifting away from the key. |
| PKA freshness | created plus local freshness check | mandatory created and expires | Makes replay window explicit. |
| Challenge binding | AID-specific AID-Challenge header | RFC 9421 nonce parameter | Closer to Web Bot Auth style and avoids custom covered header machinery. |
HTTP Date | previously considered for signing | not signed | created, expires, and nonce carry freshness with less proxy fragility. |
| PKA caching | not explicit enough | response Cache-Control: no-store | Nonce-bound proofs must not be replayed by intermediaries. |
| Rotation | kid looked rotation-related | no DNS rotation mechanism in core | DNS publishes the current key; real rotation belongs in a future key directory/profile. |
.well-known fallback | fallback metadata | explicit trustSource=well-known-tls | Avoids confusing TLS-hosted metadata with DNS-rooted trust. |
Reader Shortcut
The largest conceptual change is that v2 removes the appearance of rotation support from DNS. The DNS record says "this is the current endpoint and key." If the key changes, the key changed. Clients with previous state apply local warning or failure policy. Managed overlap can be designed later in an HTTP key directory profile.
0. Glossary
| Term | Meaning |
|---|---|
| AID Client | Software that performs discovery according to this specification. |
| Provider | Entity that controls a domain and publishes the AID record. |
_agent subdomain | The DNS name _agent.<domain> where the AID TXT record is published. |
| PKA | Public Key for Agent: an optional Ed25519 endpoint-proof key in the AID record. |
JWK x | The base64url-encoded public key member for an Ed25519 OKP JWK. |
| JWK thumbprint | RFC 7638 hash of a canonical JWK representation. Used as the v2 HTTP signature keyid. |
| Trust source | The source from which the selected AID record was obtained: dns or well-known-tls. |
The key words MUST, MUST NOT, REQUIRED, SHALL, SHALL NOT, SHOULD, SHOULD NOT, RECOMMENDED, NOT RECOMMENDED, MAY, and OPTIONAL are to be interpreted as described in RFC 2119 and RFC 8174.
1. Design Goals
AID v2 keeps the v1 design goals and sharpens the boundary.
- Zero-configuration discovery: Given a domain, a client can discover the agent endpoint and protocol.
- DNS-first deployment: Discovery remains deployable through DNS TXT records.
- Protocol agnostic: AID discovers endpoints for MCP, A2A, OpenAPI, gRPC, GraphQL, WebSocket, local agents, and future protocols.
- Endpoint proof: When
kis present, the endpoint proves possession of the matching private key. - Scope honesty: AID does not issue credentials, grant authorization, prove human approval, define SPIFFE/WIMSE federation, or publish DID-like metadata.
Explainer: v2 is not trying to make AID a full identity stack. It makes AID a cleaner first-contact anchor that other identity and authorization systems can safely build on.
2. TXT Record Specification
A provider advertises its agent service by publishing a DNS TXT record at _agent.<domain>.
2.1 Format
The record is a single semicolon-delimited string of key=value pairs. Clients SHOULD trim leading and trailing whitespace from keys and values. Clients MUST ignore unknown keys unless the key has a known legacy meaning that is explicitly invalid in v2.
Clients MUST recognize single-letter lowercase aliases. A record MUST NOT include both a full key and its alias. Key comparisons are case-insensitive.
Providers SHOULD emit the short-key form for compact DNS deployment.
| Key | Alias | Requirement | Description | Example |
|---|---|---|---|---|
version | v | Required | The specification version. For v2 it MUST be aid2. | v=aid2 |
uri | u | Required | Absolute https:// URL for a remote agent, or a package/locator for local agents. | u=https://api.example.com/mcp |
proto | p | Required | Protocol token from the protocol registry. | p=mcp |
auth | a | Recommended | Authentication hint token from the auth registry. | a=oauth2_code |
desc | s | Optional | Short human-readable display text. | s=Primary AI Gateway |
docs | d | Optional | Absolute https:// URL to human-readable documentation. | d=https://docs.example.com/agent |
dep | e | Optional | ISO 8601 UTC deprecation timestamp. | e=2027-01-01T00:00:00Z |
pka | k | Optional | Unpadded base64url Ed25519 public key. The value is exactly the RFC 8037 JWK x member. | k=JrQLj5P_89iXES9-vFgrIy29clF9CC_oPPsw3c5D0bs |
AID v2 records MUST NOT use kid or i for endpoint proof. A v2 record containing recognized kid or i is invalid.
Explainer: why keep
kinstead of renaming it tox? JWK usesx, but AID's DNS field is not a JWK object. Keepingkmakes the TXT record readable and avoids confusion with earlier rejectedxrotation-chain ideas. The important alignment is the value:kis exactly the JWKxvalue.
Explainer: why reject
kid/iinstead of ignoring it? In v1,ihad a known meaning. Silently accepting it in v2 would let stale examples appear to work while the verifier actually uses a different key identity model.
2.2 Examples
Remote MCP agent:
_agent.example.com. 300 IN TXT "v=aid2;u=https://api.example.com/mcp;p=mcp;a=pat;s=Example AI Tools"
Remote MCP with PKA:
_agent.example.com. 300 IN TXT "v=aid2;p=mcp;u=https://api.example.com/mcp;k=JrQLj5P_89iXES9-vFgrIy29clF9CC_oPPsw3c5D0bs;a=oauth2_code;s=Secure AI Gateway"
Local agent via Docker:
_agent.grafana.com. 300 IN TXT "v=aid2;u=docker:grafana/mcp:latest;p=local;a=pat;s=Run Grafana agent locally"
Same key during v1 to v2 migration:
_agent.example.com. 300 IN TXT "v=aid1;p=mcp;u=https://api.example.com/mcp;k=<same-key-as-v1-multibase>;i=g1"
_agent.example.com. 300 IN TXT "v=aid2;p=mcp;u=https://api.example.com/mcp;k=<same-key-as-v2-base64url>"
Explainer: A same-key migration is not a key rotation. The raw 32-byte Ed25519 public key stays the same; only its DNS encoding changes.
2.3 Client Discovery Algorithm
When given a domain, an AID client performs these steps:
- Normalize the domain. If the domain contains non-ASCII characters, convert it to its Punycode A-label representation.
- Query TXT records for
_agent.<exact-host-user-entered>. Clients MUST NOT walk up to parent domains. - Parse returned TXT answers as semicolon-delimited
key=valuerecords. - Partition valid records by AID major version.
- Select the highest supported valid version allowed by local policy, normally
aid2beforeaid1. - Within the selected version, if exactly one valid record exists, use it. If more than one valid record exists, fail with ambiguity.
- Process optional metadata: display
docs, warn or fail ondepaccording to policy. - If
kis present, perform PKA endpoint proof using Appendix D. - Return the discovered endpoint, protocol, metadata, PKA state, and trust source.
Malformed answers do not matter when there is exactly one valid record in the selected version. Clients MUST NOT choose among multiple valid same-version records by DNS answer order.
Returning clients that previously selected aid2 SHOULD treat an aid1-only result as a version downgrade.
Explainer: The v2 migration needs version partitioning. Publishing
aid1andaid2side by side should not trigger the same ambiguity rule as two competingaid2records.
2.4 Exact-Host Semantics And Delegation
Discovery remains exact-host by default. If the application asks for app.team.example.com, the base query is _agent.app.team.example.com.
Clients MUST NOT implicitly retry parent hosts such as _agent.team.example.com or _agent.example.com.
If an operator wants child hosts to inherit a shared record, that inheritance MUST be expressed in DNS for the exact queried name, for example with a CNAME.
_agent.app.team.example.com. 300 IN CNAME _agent.shared.team.example.com.
_agent.shared.team.example.com. 300 IN TXT "v=aid2;p=mcp;u=https://gateway.team.example.com/mcp;k=<current-key>"
2.5 Multiple Protocols
The canonical location remains _agent.<domain>. Providers MAY additionally publish protocol-specific names such as _agent._mcp.<domain> or _agent._a2a.<domain> when an application explicitly requests a protocol.
3. Security Rules
- DNSSEC: Providers SHOULD sign DNS records with DNSSEC. Clients SHOULD validate DNSSEC when available.
- HTTPS: Remote agent URIs MUST use
https://. Clients MUST perform standard TLS certificate and hostname validation. - No secrets: TXT records are public and MUST NOT contain secrets.
- Endpoint proof: When the selected v2 record contains
k, clients MUST verify endpoint proof using the PKA profile in Appendix D. - Local execution safeguards: Clients that support
proto=localMUST require explicit user consent, integrity checks, no shell interpretation of discovered arguments, no nested discovery execution, and SHOULD use sandboxing.
3.1 What PKA Proves
PKA proves exactly this:
The endpoint reached at the discovered URI controls the Ed25519 private key corresponding to the public key currently published in the domain's selected AID record.
PKA does not prove:
- that a user authorized a specific action;
- that an OAuth token is valid;
- that a SPIFFE SVID belongs to a trust domain;
- that an internal policy engine approved a request;
- that a key change is cryptographically continuous with a previous key.
Explainer: This narrow trust claim is the core of v2. AID can help other systems decide where to begin trust establishment, but AID is not the whole trust establishment system.
3.2 Threat Model
Mitigations provided by AID v2:
- DNS spoofing or cache poisoning: DNSSEC validation, when available.
- Endpoint impersonation: PKA endpoint proof with Ed25519 HTTP Message Signatures.
- PKA removal or key replacement: Returning clients can detect changes when they retain previous security state.
- Version downgrade: Returning clients can detect
aid2toaid1downgrade when they retain previous version state. - Command injection in local agents: Local execution safeguards.
- Cross-origin redirects: PKA redirects are rejected.
Explicitly out of scope:
- compromised authoritative DNS servers;
- active attackers after TLS validation fails;
- authorization, delegation, user consent, reputation, or workload federation;
- managed cryptographic rotation in the core DNS record.
3.3 Enterprise Policy Modes
Clients that expose enterprise controls SHOULD provide simple policy knobs:
- PKA policy:
if-present | require - DNSSEC policy:
off | prefer | require - Well-known policy:
auto | disable - Downgrade policy:
off | warn | fail
Policy semantics:
pka=require: discovery fails if the selected record has nok.dnssec=require: discovery fails when DNSSEC validation is unavailable or unsuccessful for the selected DNS answer.well-known=disable: clients do not use/.well-known/agent.downgrade=warn|fail: applies to PKA removal, key replacement, andaid2toaid1downgrade when previous state exists.
If discovery succeeds only through .well-known, the result cannot satisfy dnssec=require.
4. DNS And Caching
Providers SHOULD set a DNS TTL of 300 to 900 seconds on _agent.<domain> TXT records.
Clients MUST respect the TTL of DNS records and MUST NOT cache DNS records longer than the received TTL.
PKA responses are separate from DNS records. A nonce-bound PKA response MUST include:
Cache-Control: no-store
Clients SHOULD also send Cache-Control: no-store on PKA requests.
Explainer: DNS records can be cached according to DNS TTL. PKA responses are per-request proof artifacts bound to a nonce. Those must not be cached or replayed.
5. Rotation Stance
AID v2 core does not define DNS-level cryptographic key rotation.
The core record says:
_agent.acme.com TXT "v=aid2;p=mcp;u=https://agent.acme.com/mcp;k=<current-key>"
That means:
- DNS currently publishes this endpoint and this key.
- The endpoint can prove possession of the corresponding private key.
- Verifiers can derive stable key identity from
k.
It does not mean:
- the new key is authorized by the old key;
- multiple keys are active through DNS;
- DNS provides validity windows;
- AID core provides request provenance or delegated signing infrastructure.
If the key changes, the key changed. Clients with previous state decide whether to warn, fail, or accept according to local policy.
Why No Multi-Key RRset In Core
The rejected-for-core shape is:
_agent.acme.com. 300 IN TXT "v=aid2;p=mcp;u=https://agent.acme.com/mcp;k=<old-key>"
_agent.acme.com. 300 IN TXT "v=aid2;p=mcp;u=https://agent.acme.com/mcp;k=<new-key>"
This is deferred because it changes the model from:
domain -> one selected endpoint record -> optional proof key
to:
domain -> one selected endpoint descriptor -> active key set -> response keyid selects key
That requires rules for normalized non-key field equivalence, duplicate handling, partial DNS propagation, key-set pinning, downgrade policy, SDK return types, and conformance fixtures. It also does not solve lost-key or compromised-key recovery.
Future Rotation Profile
If AID later needs managed rotation for pinned clients or provenance profiles, it should be a separate HTTP key-directory profile, likely using JWKS/WBA-style overlap:
{
"keys": [
{
"kty": "OKP",
"crv": "Ed25519",
"kid": "<jwk-thumbprint>",
"x": "<public-key>",
"use": "sig",
"nbf": 1712793600,
"exp": 1715385600
}
]
}
If such a directory chains to DNS k, that chaining is the defining property of an AID-anchored key directory. If it does not chain to DNS k, it is a normal external WBA/JWKS-style directory outside AID core.
6. IANA And Label Strategy
The v2 draft keeps _agent.<domain> as the discovery label.
The earlier RFC 8552 _agent registration request was rejected on procedural grounds in April 2026. That label-governance question is decoupled from the v2 PKA cleanup. A later working group or BoF process may revisit the label, but this draft does not make a label change part of the key-format work.
Explainer: Renaming the label while also changing key semantics would make review harder. v2 can clarify PKA without forcing the namespace question into the same decision.
7. Registries
The auth and protocol registries remain compatible with v1.2 unless changed through the normal extension process.
Auth Tokens
nonepatapikeybasicoauth2_deviceoauth2_codemtlscustom
Protocol Tokens
| Token | Meaning | Allowed URI schemes |
|---|---|---|
mcp | Model Context Protocol | https:// |
a2a | Agent-to-Agent Protocol | https:// |
openapi | OpenAPI document | https:// |
grpc | gRPC over HTTP/2 or HTTP/3 | https:// |
graphql | GraphQL over HTTP | https:// |
websocket | WebSocket transport | wss:// |
local | Local client-run agent | docker:, npx:, pip: |
zeroconf | mDNS/DNS-SD service discovery | zeroconf:<service_type> |
ucp | Universal Commerce Protocol | https:// |
Explainer: v2 does not add an auth.md-specific auth token. A service that supports OAuth/auth.md can still advertise
a=oauth2_code; the detailed agent registration flow is discovered at the OAuth/auth.md layer.
Appendix A: Client Error Codes
Clients SHOULD continue using the existing error code family.
| Code | Name | Meaning |
|---|---|---|
1000 | ERR_NO_RECORD | No AID DNS record was found. |
1001 | ERR_INVALID_TXT | A record was malformed, invalid, or ambiguous. |
1002 | ERR_UNSUPPORTED_PROTO | The protocol token is unsupported. |
1003 | ERR_SECURITY | Discovery failed due to security policy or failed endpoint proof. |
1004 | ERR_DNS_LOOKUP_FAILED | DNS lookup failed for network-related reasons. |
1005 | ERR_FALLBACK_FAILED | The .well-known fallback failed or returned invalid data. |
Appendix B: PKA Handshake
When k is present, clients MUST verify endpoint proof using HTTP Message Signatures with Ed25519.
B.1 Key Decoding
For v2, k MUST be unpadded base64url. Decoding MUST produce exactly 32 octets. Legacy z... multibase keys MUST NOT be accepted in v=aid2.
The corresponding JWK is:
{ "kty": "OKP", "crv": "Ed25519", "x": "<k>" }
B.2 Derived keyid
The expected HTTP Message Signature keyid is the RFC 7638 JWK thumbprint using SHA-256 over this exact UTF-8 JSON serialization, with no extra spaces:
{"crv":"Ed25519","kty":"OKP","x":"<k>"}
The SHA-256 digest is encoded as unpadded base64url. Implementations MUST NOT hash the raw public key bytes directly for keyid.
B.3 Request And Response Shape
Current preferred shape, pending exact Structured Fields validation for Accept-Signature:
Accept-Signature: aid-pka=("@method";req "@target-uri";req "@authority";req "@status");created;expires;keyid="<jwk-thumbprint>";alg="ed25519";nonce="<client-challenge>";tag="aid-pka-v2"
Signature-Input: aid-pka=("@method";req "@target-uri";req "@authority";req "@status");created=<unix>;expires=<unix>;keyid="<jwk-thumbprint>";alg="ed25519";nonce="<client-challenge>";tag="aid-pka-v2"
Signature: aid-pka=:<base64-signature>:
Cache-Control: no-store
The signature MUST NOT cover HTTP Date.
The client challenge MUST contain at least 32 bytes of entropy and SHOULD be transported as unpadded base64url in the RFC 9421 nonce signature parameter. The verifier MUST compare the received nonce exactly to the challenge it sent.
Servers are not required to store nonce state in v2 core because the verifier supplies the one-shot nonce and the signed response is not cacheable.
created and expires are mandatory. expires MUST be greater than created. expires - created MUST NOT exceed 300 seconds and SHOULD be 60 seconds or less. Verifiers MAY allow a small clock-skew tolerance when evaluating created and expires.
Signers MUST emit alg="ed25519" lowercase. Verifiers MUST compare the semantic algorithm value case-insensitively and MUST reconstruct @signature-params from the received Structured Field value.
B.4 Covered Components
The v2 PKA response signature covers:
"@method";req"@target-uri";req"@authority";req"@status"
@method, @target-uri, and @authority are request-derived components and therefore use ;req. @status is response-derived and does not use ;req.
@status signs the status actually returned. PKA does not require status 200. A signed 401 can still prove endpoint authenticity before the OAuth/auth.md handoff continues.
B.5 URI, Authority, And Redirects
Clients MUST NOT follow redirects during PKA verification. The request context is the discovered endpoint URI after fragment removal. Query strings are preserved.
@authority uses the externally visible request authority:
- lowercase hostname;
- omit default port;
- retain non-default port.
Servers behind reverse proxies must sign the externally visible request context, not internal hop-local scheme, host, or port values.
B.6 Verifier Summary
A verifier accepts a v2 PKA response only when:
- the selected AID record contains valid v2
k; - the response contains a valid
Signature-InputandSignature; - the covered components and
tag="aid-pka-v2"match this profile; keyidequals the RFC 7638 thumbprint derived from DNSk;alghas semantic valueed25519;nonceexactly equals the verifier-generated challenge;createdandexpirespass freshness checks;- the response includes
Cache-Control: no-store; - Ed25519 verification succeeds over the reconstructed RFC 9421 signature base.
Explainer: This is a v2 wire-format break from the current SDK PKA handshake. That is intentional. The v1 text left too much RFC 9421 behavior implicit for independent implementations.
Appendix C: .well-known Fallback
AID remains DNS-first. The .well-known fallback is a convenience for environments where DNS TXT record creation is restricted.
- Path:
GET https://<domain>/.well-known/agent - Format: JSON mirroring v2 record keys.
- Trust source:
well-known-tls - Security: relies on TLS certificate validation. PKA may still apply, but it proves consistency with TLS-hosted metadata, not DNS-published external trust.
DNS-discovered records have trustSource=dns. Fallback-discovered records have trustSource=well-known-tls.
Explainer: This distinction matters. If a policy requires DNSSEC-backed trust,
.well-knowncannot satisfy it.
Appendix D: Composition Notes
These notes are non-normative.
D.1 Web Bot Auth
AID v2 follows Web Bot Auth where the layers match: Ed25519, RFC 9421 HTTP Message Signatures, RFC 7638 JWK thumbprints, created, expires, nonce, and tag.
AID does not become Web Bot Auth. WBA signs automated client requests to origins. AID PKA proves endpoint control for a DNS-discovered agent endpoint.
Operators may reuse key material across AID and WBA if their threat model allows it, but AID does not recommend reuse. Reuse shares blast radius between endpoint proof and request-signing.
D.2 auth.md And OAuth
AID can support auth.md without adding auth.md-specific fields to core:
- AID resolves a domain to
uandp. - If
kis present, PKA verifies the endpoint. - The client follows the endpoint/protocol/OAuth layer, including RFC 9728 Protected Resource Metadata, RFC 8414 Authorization Server Metadata, and auth.md
agent_authflows where present.
AID does not specify ID-JAG aud, provider trust lists, registration payloads, scopes, credential types, revocation, or auth.md metadata registries.
D.3 SPIFFE And WIMSE
AID may be used by future SPIFFE or WIMSE profiles as a public first-contact anchor.
AID v2 core does not define:
- SPIFFE trust-domain mapping;
- SPIFFE bundle federation;
- WIMSE hop re-binding;
- OAuth client registration;
- workload authorization.
D.4 Pkarr
AID v2 remains compatible with the Pkarr-inspired idea of compact Ed25519 key material, but it does not adopt Pkarr's identity model.
Pkarr makes the public key the address and signs DNS packets under that key. AID remains DNS-authority-rooted: the DNS owner publishes the current endpoint and current endpoint-proof key inside a TXT payload.
Reviewer-facing language should say "DNS-current endpoint/key" and should not imply Pkarr-style self-certifying names, key-addressed identity, or cryptographic continuity across key changes.
Appendix E: Migration Notes
Provider Migration
- Inventory current
aid1records. - For PKA records, decode the v1 multibase/base58btc
kto the 32-byte Ed25519 public key. - Encode those bytes as unpadded base64url. This is the v2
k. - Publish
v=aid2with the same endpoint, protocol, and v2k, withouti. - Keep
aid1during the compatibility window. - Remove
aid1after old-client support is no longer needed.
Client Migration
- Support both
aid1andaid2parsing. - Partition records by version before ambiguity checks.
- Prefer
aid2when both versions are valid and policy allows it. - Keep v1 PKA only for
aid1records. - Store previous security state using derived JWK thumbprints so same-key v1 to v2 migration does not look like key replacement.
Appendix F: Remaining Checks Before Spec PR
These are the remaining checks before turning this preview into the actual replacement spec text:
- Validate exact RFC 9421
Accept-SignatureStructured Fields syntax for requesting a response signature withnonce,created,expires,keyid,alg, andtag. - Create one canonical v2 PKA vector and verify it with at least one independent RFC 9421 / Structured Fields implementation before SDK implementation.
- Tighten the final non-normative auth.md wording without specifying ID-JAG audience, provider trust lists, registration payloads, or auth.md metadata registry details.
Reviewer Questions
- Is the no-date RFC 9421
aid-pkaresponse signature shape correct and implementable? - Is the
Accept-Signatureserialization valid with existing Structured Fields libraries? - Are the covered components sufficient to bind request target, response status, and nonce challenge?
- Are the nonce, expiry, clock-skew, redirect, cache, and authority rules practical for real deployments?
- Is signed non-
200response support, especially signed401, the right way to support OAuth/auth.md handoff? - Is side-by-side
aid1/aid2publication with version partitioning acceptable for migration? - Is the
_agentlabel note sufficient while the IETF label decision remains decoupled from PKA cleanup? - Is the future key-directory boundary clear enough?
- Does the SPIFFE/WIMSE/OAuth/auth.md composition guardrail avoid overclaiming?
- Is the Pkarr boundary clear enough?