This specification defines did:atp, a Decentralized Identifier (DID) method for AI agents that adds quantum-safe identity on top of an existing, web-native agent identity model. A did:atp identifier carries two cryptographic bindings: a classical Ed25519 binding, identical to the one defined by did:wba [[DID-WBA]], and a post-quantum ML-DSA-65 binding [[ML-DSA]] expressed using the finalized JOSE/COSE serialization for ML-DSA [[RFC9964]].

did:atp does not invent a new resolution or authentication model. It adopts, by normative reference, the resolution, DID Document processing, classical integrity-proof, and HTTP Message Signature mechanisms defined by did:wba, and adds exactly one capability: a post-quantum binding key and a post-quantum signature path. Stripping the post-quantum segment from a did:atp identifier yields a syntactically valid did:wba identifier.

The hybrid construction defined here has been demonstrated end-to-end with real cryptography (FIPS 204 ML-DSA-65 + Ed25519), including dual-binding resolution, defense-in-depth against a forged classical signature, and a method-agnostic trust credential. See Proof of Concept.

This document is a draft work product of the Agent Trust Protocol (ATP) Community Group. It is not a W3C Standard nor on the W3C Recommendation track. Publication as a Community Group Report does not imply endorsement by W3C or its Membership.

The ATP Community Group coordinates with the W3C AI Agent Protocol Community Group [[AI-AGENT-PROTOCOL]] and accepts that group's invitation to collaborate. This specification is designed to be a compatible extension of that group's did:wba work, not an alternative to it. See Relationship to did:wba.

The classical portion of this method rests on stable W3C Recommendations. The post-quantum portion is deliberately scoped to rest only on finalized standards: FIPS 204 [[ML-DSA]] and RFC 9964 [[RFC9964]]. It intentionally does not depend on a W3C Data Integrity cryptosuite for the post-quantum proof: the finalized W3C Quantum-Safe Cryptosuites CG Report [[DI-QUANTUM-SAFE]] defines usable ML-DSA cryptosuites only at ML-DSA-44 (security category 2), whereas did:atp targets ML-DSA-65 (category 3). See Why JOSE/COSE for the post-quantum path and Re-Elevation Triggers.

As well as sections marked as non-normative, all authoring guidelines, diagrams, examples, and notes in this specification are non-normative. Everything else is normative.

The key words MUST, MUST NOT, SHOULD, and MAY are to be interpreted as described in BCP 14 [[RFC2119]] [[RFC8174]] when, and only when, they appear in all capitals.

Relationship to did:wba

This specification is defined as a delta over the did:wba method [[DID-WBA]]. The following mechanisms are adopted unchanged by normative reference:

This specification adds one capability absent from did:wba: a post-quantum binding key and a post-quantum signature path, so that an agent's identity remains verifiable against an adversary able to break elliptic-curve cryptography.

did:web → did:wba (adds agent path binding + Ed25519 e1_) → did:atp (adds hybrid post-quantum binding). Each layer preserves the prior layer's machinery and adds exactly one concern.

Should the AI Agent Protocol CG adopt a post-quantum binding profile directly into did:wba, or should a W3C Data Integrity ML-DSA-65 cryptosuite reach maturity, the ATP CG intends to align this specification with that work. See Re-Elevation Triggers.

Method Name

The method name that identifies this DID method is atp. DIDs using this method MUST begin with the prefix did:atp:. Per DID Core [[DID-CORE]], this string MUST be lowercase.

Method-Specific Identifier Syntax

The method-specific identifier follows did:wba syntax with one addition: a path-type did:atp identifier carries two trailing binding-key fingerprint segments — the classical e1_ segment defined by did:wba, followed by a post-quantum pq1_ segment defined here.

base64url-char  = ALPHA / DIGIT / "-" / "_"
path-segment    = 1*(ALPHA / DIGIT / "-" / "_" / ".")
e1-fingerprint  = "e1_" 43base64url-char        ; Ed25519, per did:wba
pq1-fingerprint = "pq1_" 43base64url-char       ; ML-DSA-65, this spec

atp-root-did = "did:atp:" domain-name
atp-path-did = "did:atp:" domain-name 1*(":" path-segment)
                 ":" e1-fingerprint ":" pq1-fingerprint
atp-did      = atp-root-did / atp-path-did
      

Example (from the proof-of-concept, abbreviated):

did:atp:agents.example.com:billing:e1_vW7u8CVMklXkz...:pq1_-MT7q-QasC380...
      

The e1_ segment is byte-identical to a did:wba e1_ segment and is independently verifiable. Two separate segments (rather than one composite hash) are used precisely to preserve that independent verifiability and the did:wba lineage.

The pq1_ Post-Quantum Binding Fingerprint

The pq1_ segment binds the path-type DID to an ML-DSA-65 [[ML-DSA]] public key. The key is represented as a JSON Web Key using the AKP (Algorithm Key Pair) key type defined for ML-DSA by RFC 9964 [[RFC9964]]:

{
  "kty": "AKP",
  "alg": "ML-DSA-65",
  "pub": "<base64url of the 1952-byte ML-DSA-65 public key>"
}
      

The fingerprint is generated as follows:

  1. Construct the AKP JWK above for the ML-DSA-65 binding key.
  2. Compute the RFC 7638 [[RFC7638]] JWK thumbprint over that JWK (lexicographically sorted member names, no whitespace, UTF-8), producing a 32-byte SHA-256 digest.
  3. Base64url-encode the digest without padding (43 characters).
  4. Prepend the pq1_ profile prefix.

The binding key MUST be authorized by the authentication relationship of the DID Document, and the RFC 7638 thumbprint of its AKP JWK MUST equal the pq1_ segment of the DID path.

Why JOSE/COSE for the post-quantum path

did:wba secures its DID Document with a W3C Data Integrity proof (eddsa-jcs-2022). The natural symmetry would be a Data Integrity ML-DSA cryptosuite. The W3C Quantum-Safe Cryptosuites CG Report [[DI-QUANTUM-SAFE]], finalized 22 April 2026, defines such cryptosuites — but only at ML-DSA-44 (mldsa44-rdfc-2024 / mldsa44-jcs-2024), explicitly capping support at security category 2. It tabulates the ML-DSA-65 and ML-DSA-87 parameters for reference but defines no usable cryptosuite for them.

did:atp targets ML-DSA-65 (category 3) for a stronger post-quantum security margin. Using the W3C Data Integrity path would therefore require downgrading to ML-DSA-44. Instead, did:atp takes the post-quantum signature path through the finalized JOSE/COSE serialization for ML-DSA-65 [[RFC9964]] (published 2026). This means:

This is a deliberately hybrid, two-mechanism architecture. It is the trade that lets did:atp be specified against entirely finalized standards today, at the cost of using two proof formats rather than one. Re-Elevation Triggers defines when the post-quantum path SHOULD migrate to a Data Integrity cryptosuite.

DID Document Requirements

A did:atp path-type DID Document MUST contain, in addition to all did:wba e1_ requirements:

Example verification method (post-quantum), as validated in the proof-of-concept:

{
  "id": "did:atp:agents.example.com:billing:e1_...:pq1_...#key-mldsa65",
  "type": "JsonWebKey",
  "controller": "did:atp:agents.example.com:billing:e1_...:pq1_...",
  "publicKeyJwk": { "kty": "AKP", "alg": "ML-DSA-65", "pub": "..." }
}
      

Method Operations

Pairwise (Per-Peer, Unlinkable) Identifiers

An agent MAY present a different did:atp identifier to each peer (relying party) so that its interactions cannot be correlated across peers by the identifiers alone. Such a pairwise identifier is an ordinary path-type did:atp whose single path segment is a pseudonym rather than a human-meaningful label, and whose e1_ / pq1_ bindings are a per-peer hybrid keypair. No new identifier syntax, resolution rule, or proof mechanism is introduced: a pairwise DID is created, parsed, resolved, and control-proved exactly as any other path-type did:atp.

A conforming pairwise identifier MUST be derived such that, without the agent's master secret, no two pairwise identifiers of the same agent (nor a pairwise identifier and the agent's canonical DID) are correlatable — i.e. the pseudonym segment, the e1_ fingerprint, and the pq1_ fingerprint MUST each be independent across peers. Because both binding fingerprints are part of the path, distinct per-peer keypairs already yield distinct e1_ and pq1_ segments; the pseudonym segment MUST likewise be a per-peer value and MUST NOT be a plain function of the peer identifier alone (which would be linkable by any party that learns the peer identifier).

The p_ Pseudonym Path Segment

A pairwise identifier uses a single path segment of the form p_ followed by a lowercase-hex pseudonym. It is a well-formed path-segment under the syntax above; the p_ prefix is a profile convention that distinguishes the pseudonym from the trailing e1_ / pq1_ binding segments and from human-meaningful labels.

pairwise-segment = "p_" 32HEXDIG-lower      ; 16-byte pseudonym, lowercase hex
        

Example pairwise identifier (one path segment, both bindings):

did:atp:agents.example.com:p_fad4fe7b41096f53e62fc34133eab6e7:e1_lmymt0Be…:pq1_YQm0BqWx…
        

Recommended Derivation

To make pairwise identifiers reproducible (so the agent can recompute a peer's keypair on demand rather than storing one per peer) while keeping them unlinkable, an implementation SHOULD derive all per-peer material from a single high-entropy master secret using HKDF-SHA256 [[RFC5869]] with domain-separated info labels. The master secret MUST be at least 32 bytes and MUST NOT be shared with any peer.

For a master secret MS, a peer identifier peerId, and an OPTIONAL salt, derive three independent outputs:

info(label)   = "atp-pairwise:v1:" label ":" peerId
ed25519_seed  = HKDF-SHA256(IKM = MS, salt, info("ed25519"),   L = 32)
mldsa65_seed  = HKDF-SHA256(IKM = MS, salt, info("ml-dsa-65"), L = 32)
pseudonym     = HKDF-SHA256(IKM = MS, salt, info("path"),      L = 16)
pairwise-seg  = "p_" lowerhex(pseudonym)
        

The Ed25519 binding key is generated from ed25519_seed and the ML-DSA-65 binding key from mldsa65_seed; both algorithms are deterministic functions of a 32-byte seed, so the same (MS, peerId, salt) always yields the same keypair and the same identifier. The e1_ and pq1_ segments are then computed from those public keys exactly as in the binding-fingerprint rules. No new cryptographic primitive is introduced; the construction composes HKDF, Ed25519, and ML-DSA-65 only.

The domain-separating labels (ed25519, ml-dsa-65, path) make the three outputs mutually independent for a given peer, and binding peerId into info makes outputs independent across peers. The OPTIONAL salt permits rotating an agent's entire set of pairwise identifiers without changing the master secret.

Privacy Properties and Limits

Pairwise identifiers remove identifier-level correlation: the DID string, both binding keys, and the pseudonym segment differ per peer and are not correlatable without the master secret. They do not by themselves defeat correlation through other channels — network metadata, timing, the domain-name component (which is shared across an agent's pairwise DIDs at the same domain), or application-layer content. Agents requiring stronger unlinkability SHOULD additionally vary or proxy those channels.

Control of a pairwise identifier is proved exactly as for any path-type did:atp: the agent signs a challenge with the per-peer hybrid keypair whose e1_ / pq1_ fingerprints are bound into the DID. A keypair derived for one peer cannot satisfy another peer's bindings, so pairwise identifiers are unforgeable across peers as well as unlinkable.

Security and Privacy Considerations

All did:wba security and privacy considerations apply. Additionally, the hybrid construction provides defense in depth: an identity remains authentic so long as the post-quantum binding holds, protecting against a future adversary who can forge Ed25519 signatures. Implementers MUST verify both bindings and MUST NOT treat a valid classical proof as sufficient on its own for a did:atp identifier. This property is demonstrated by the forged-classical- signature test in the Proof of Concept.

For agents that must avoid cross-peer correlation of their identifiers, Pairwise Identifiers defines per-peer, unlinkable did:atp values and states the privacy properties they do and do not provide.

Proof of Concept

A runnable reference proof accompanies this specification (see the /proof directory of the repository). Using FIPS 204 ML-DSA-65 and Ed25519, it demonstrates, with all checks passing:

The proof is a self-contained TypeScript program (npx tsx proof/index.ts) that uses the audited @noble/post-quantum ML-DSA-65 and @noble/ed25519 libraries and reuses the production ATP SDK for the identifier syntax, DID-Document construction, dual proofs, and resolution — so it validates the protocol design against real standards and against the production implementation. Every check is asserted; the program exits non-zero on any failure.

Re-Elevation Triggers

The post-quantum path SHOULD migrate from the JOSE/COSE proof to a W3C Data Integrity proof (restoring single-mechanism symmetry with did:wba) when both of the following hold:

  1. The W3C Quantum-Safe Cryptosuites work [[DI-QUANTUM-SAFE]] defines a usable Data Integrity cryptosuite at ML-DSA-65 (category 3) — e.g. an mldsa65-jcs-* / mldsa65-rdfc-* identifier. As of its 22 April 2026 Final Report, the defined ML-DSA cryptosuites stop at ML-DSA-44 (category 2); and
  2. A corresponding ML-DSA-65 Multikey / multicodec prefix is registered (the Final Report's Multikey table lists only ML-DSA-44 at 0x1210).

Until both hold, the JOSE/COSE post-quantum path defined here is the normative mechanism for did:atp. Downgrading to ML-DSA-44 solely to use the existing Data Integrity cryptosuite is NOT an acceptable substitute, as it lowers the post-quantum security category.

Open Items