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.
This specification is defined as a delta over the did:wba
method [[DID-WBA]]. The following mechanisms are adopted
unchanged by normative reference:
did.json retrieval).e1_) and its RFC 7638 [[RFC7638]] thumbprint.eddsa-jcs-2022).
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.
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.
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.
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:
AKP JWK above for the ML-DSA-65 binding key.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.
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.
A did:atp path-type DID Document MUST contain, in addition
to all did:wba e1_ requirements:
AKP JWK [[RFC9964]], whose RFC 7638 thumbprint equals the
pq1_ segment of the DID path, authorized by
authentication.
eddsa-jcs-2022 Data Integrity proof required by
did:wba.
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": "..." }
}
did.json.
did:wba verification
steps for the e1_ segment (including the
eddsa-jcs-2022 proof), then additionally (a) recompute the
pq1_ thumbprint from the AKP JWK and confirm
it matches the path, and (b) verify the ML-DSA-65 [[RFC9964]] signature
over the document. Resolution MUST fail if either the
classical or the post-quantum binding fails to verify.
did:wba.
Rotating either binding key changes the DID, since both
fingerprints are part of the path.
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).
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…
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.
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.
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.
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:
did:atp identifier whose classical view is a valid did:wba identifier.did:atp subject and a did:web subject, with tampering detected.
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.
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:
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
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.