Abstract

By late 2026 the IETF had published RFC 9881 for ML-DSA in X.509, RFC 9882 for the Cryptographic Message Syntax and RFC 9964 for JOSE and COSE, and approved a composite ML-DSA draft that is awaiting publication. This piece reads those documents for their decisions rather than their syntax. It explains the three private-key formats and why the seed must be retained, why the seed-only rule in JOSE and COSE matters for key portability, what a conforming ML-DSA certificate may and may not assert, how the new Algorithm Key Pair key type binds thumbprints to one algorithm, and what base64url encoding does to token sizes and HTTP header budgets. It then dissects the composite construction, including the domain-separating prefix and label and the draft's own statement that composites are not strongly unforgeable against quantum adversaries. It ends with a table of the decisions the standards leave to deployers, and how agent identity, tool-call tokens and model provenance should make them.

Standards documents for a new signature algorithm look like plumbing: object identifiers, encodings, a table of sizes. Most of their text is exactly that. But scattered through RFC 9881, RFC 9882, RFC 9964 and the composite draft are a handful of decisions that will govern how ML-DSA keys are backed up, how they move between vendors, how large an agent's access token becomes and whether a signature can still serve as a unique identifier. Those decisions are easy to miss because they sit in security considerations and appendices. This article collects them, explains the reasoning the documents give, and marks clearly what each one leaves for the deployer to decide.

What the documents settle, and when

Four documents matter. RFC 9881, published in October 2025, defines the algorithm identifiers and encodings for ML-DSA public keys, private keys and signatures in X.509 certificates and certificate revocation lists. RFC 9882, also October 2025, specifies ML-DSA in the Cryptographic Message Syntax, the format underneath many signed-artifact and signed-email systems. RFC 9964, published in May 2026, registers ML-DSA for JSON Object Signing and Encryption and CBOR Object Signing and Encryption, the formats behind JSON Web Tokens and their compact binary counterparts. And the composite ML-DSA draft from the same working group, which pairs ML-DSA with a classical signature, was in the RFC Editor's queue at revision 19 according to the IETF datatracker in October 2026, so its RFC number was not yet assigned.

All three published RFCs share several choices: they use only pure ML-DSA, never the pre-hash variant HashML-DSA; they fix the context string to the empty string; and they identify algorithms by parameter set alone, with no parameters in the algorithm identifier. RFC 9881 also notes, in one line that deserves emphasis for anyone with pilot deployments, that ML-DSA and the pre-standard Dilithium are not compatible, so keys and certificates made with draft implementations have to be reissued.

The size consequences of ML-DSA in certificate chains and handshakes are well documented elsewhere and are not the subject here: in short, a chain carries several signatures and public keys of a few kilobytes each instead of tens of bytes. This article concentrates on the decisions that sizes do not reveal.

Private keys: seed, expanded, or both

FIPS 204 generates every key pair from a 32-byte random seed. Key generation expands that seed into the full private key, which is 2,560, 4,032 or 4,896 bytes for the three parameter sets, and into the public key. RFC 9881 therefore defines three private-key formats inside the usual private-key container: the seed alone, the expanded key alone, or both together. It recommends the seed format because it is compact and both other values can be derived from it deterministically.

The RFC then makes a point that changes how key management should work. Expanding a seed into a private key is one-way: once a full key has been expanded and the seed discarded, the seed cannot be recreated from the expanded key. It is therefore recommended that implementations retain and export the seed even when they also export the expanded key. A module that stores only the expanded form has made a permanent decision that some consumers cannot undo. RFC 9964 shows why this matters: for JOSE and COSE the private key parameter must be the 32-byte seed, chosen so that every implementation uses a single, compact representation. A key that exists only in expanded form can never be expressed as a JOSE or COSE private key.

When a private key arrives in the both format, a recipient should check that the two agree by regenerating the expanded key from the seed and comparing bytes, and RFC 9881 includes examples of inconsistent pairs in an appendix. The reason is practical: one library may use the seed and another the expanded key, and if they disagree the same key file represents two different keys. FIPS 204 adds that the seed must be protected exactly like the private key, and RFC 9964 repeats that whoever obtains either can forge signatures. One more design detail helps here: the final standard bound the parameter set into seed expansion, so the same seed used with two parameter sets yields unrelated keys, a misuse-resistance change recorded in Appendix D.3.

For agent platforms the implication is about provisioning and recovery. If agent identity keys are generated in a module and must later move to another platform, or be expressed as a JSON Web Key for a token issuer, the seed is the portable form. Escrowing or backing up seeds is equivalent to escrowing the keys themselves, so backup policy has to treat 32 bytes as full signing authority.

Private-key formats as specified in RFC 9881 and RFC 9964; sizes from FIPS 204 for ML-DSA-44, -65 and -87.
FormatSizeWhere allowedConsequence
Seed32 bytes for every parameter setRFC 9881 (recommended); the only form in RFC 9964Portable everywhere; derive both keys on load
Expanded key2,560 / 4,032 / 4,896 bytesRFC 9881 onlySeed unrecoverable; cannot become a JWK or COSE key
BothSeed plus expanded keyRFC 9881 onlyCheck consistency or risk two different keys in one file

Certificates and signed messages

In a certificate, the ML-DSA signature is computed over the DER encoding of the to-be-signed certificate with the empty context. Section 5 of RFC 9881 restricts what an ML-DSA public key may be used for: if the key-usage extension is present, it must assert at least one of digital signature, non-repudiation, certificate signing or revocation-list signing, and must not assert key encipherment, data encipherment, key agreement or the related bits, because ML-DSA keys cannot establish keys or encrypt. For agent workload identities, which authenticate and sign but do not issue certificates, digital signature alone is the natural assertion; for issuing authorities, certificate and revocation-list signing.

The security considerations of RFC 9881 carry information that rarely reaches certificate policies. They state that ML-DSA is strongly unforgeable, that security-strength estimates assume an attacker has signatures on no more than two to the 64th chosen messages, that randomized signing is easier to harden against fault and hardware side-channel attacks, that side-channel leakage from the bit-unpacking function has been demonstrated with key recovery over a large sample of signatures, and that ML-DSA has the beyond-unforgeability properties exclusive ownership, message binding and non-resignability, based on the collision resistance of SHAKE256. A certificate policy for agent identities can cite those lines directly instead of paraphrasing vendor claims.

RFC 9882 brings the same algorithm into the Cryptographic Message Syntax, which matters for model provenance bundles and signed releases. It prefers signing over signed attributes that contain the content digest, requires support for SHA-512, recommends SHAKE256, and constrains the digest to match the parameter set's strength. The signature itself is pure ML-DSA with the empty context, so the same key and the same verification code serve certificates and signed artifacts.

JOSE and COSE: a new key type and a bigger token

RFC 9964 does not add ML-DSA to an existing key type. It defines a new one, the Algorithm Key Pair, abbreviated AKP, whose members are the algorithm, a public value and, for private keys, a private value; the algorithm member is required. ML-DSA-44, ML-DSA-65 and ML-DSA-87 are registered as JOSE algorithm names and as COSE algorithms with values minus 48, minus 49 and minus 50, and the context must be the empty string. The RFC also specifies thumbprints for AKP keys and lists the algorithm among the members a thumbprint covers. A consequence worth noting is that a thumbprint names a key for one algorithm, so the same public value presented with a different algorithm has a different thumbprint; key identifiers derived from thumbprints therefore cannot drift between algorithms by accident.

Two security considerations in RFC 9964 deserve attention from token issuers. Key validation is mandatory when an algorithm requires it, including a check that the seed is exactly 32 bytes. And mismatched public and private parameters, whether tampered with or merely confused, can have consequences ranging from failed operations to private-key compromise, which argues for deriving the public value from the seed on load rather than trusting a stored pair.

Size is where tokens feel ML-DSA most. RFC 9964's table gives public keys of 1,312, 1,952 and 2,592 bytes and signatures of 2,420, 3,309 and 4,627 bytes, and notes that JSON Web Signatures base64url-encode the signature, which grows it. Base64url turns every three bytes into four characters, so an ML-DSA-65 signature becomes 4,412 characters and an ML-DSA-87 signature 6,170, against 86 characters for the 64-byte signature of a typical elliptic-curve token today. HTTP itself, as RFC 9110 Section 5.4 explains, sets no predefined limit on header fields, but implementations impose their own limits, and a server receiving a field larger than it wishes to process must reject the request with a client-error status. A bearer token in an authorization header that grows by several kilobytes can therefore fail in proxies and servers that handled classical tokens without complaint. RFC 9964 points to thumbprints as a way to avoid repeating public keys; COSE's binary encoding avoids the base64 expansion altogether.

Base64url adds a third to each signature; an ML-DSA-65 token signature is about fifty times longer than a 64-byte elliptic-curve one.Characters a signature adds to a compact JSON tokenES256 (64 bytes)86 charsML-DSA-44 (2,420 bytes)3,227 charsML-DSA-65 (3,309 bytes)4,412 charsML-DSA-87 (4,627 bytes)6,170 charsbase64url: every 3 bytes become 4 characters; header and payload come on top
Base64url adds a third to each signature; an ML-DSA-65 token signature is about fifty times longer than a 64-byte elliptic-curve one.

Composite ML-DSA: the construction and its stated limits

Composite ML-DSA, as specified in the approved draft, pairs ML-DSA with RSA, ECDSA, Ed25519 or Ed448 under a single algorithm identifier, so that a certificate carries one combined key and one combined signature. The signer first builds a message representative: a fixed prefix, which is the ASCII string CompositeAlgorithmSignatures2025, followed by a label specific to the algorithm combination, the length of the application context, the context, and a hash of the message with a hash function fixed for that combination. Both component algorithms sign that representative, and the label is also passed to ML-DSA as its own context string. The prefix and label bind each component signature to the composite construction and to one specific pairing.

The draft is explicit about what this achieves. It says the composite is existentially unforgeable if at least one component is, provided the message hash is collision resistant, and spells out what that means if one side fails: if the classical component is broken, the composite remains unforgeable against quantum adversaries; if ML-DSA is broken, it remains unforgeable only against classical adversaries. It also claims weak non-separability, meaning an adversary cannot simply remove one component signature and present the other as a standalone signature without leaving evidence, which the prefix and label make possible. And it forbids reusing component keys between composite and non-composite keys or across composite keys.

The draft is equally explicit about what composites do not achieve. It states that composite ML-DSA is not strongly unforgeable against quantum adversaries, gives two reasons, and draws the conclusion. First, a malleable classical component such as ECDSA passes its malleability through to the composite. Second, even if both components are strongly unforgeable, an attacker holding two composite signatures on the same message can combine the ML-DSA half of one with the classical half of the other to make a third valid signature. The draft therefore calls replacing an ML-DSA signature with a composite a reduction in security for applications sensitive to the difference, says composites should not be used where strong unforgeability is critical, and marks them not recommended where it has not been shown that the weaker property is acceptable.

Both components sign one representative built from a fixed prefix, an algorithm label, the context and a message hash; the label is also ML-DSA's context.How a composite ML-DSA signature is assembledMessagehashed with fixed functionRepresentativeprefix, label, context, hashML-DSAcontext = labelClassical signatureRSA, ECDSA or EdDSAComposite signatureboth halves, one identifierverifies only if both halves verify; not strongly unforgeable against quantum adversaries
Both components sign one representative built from a fixed prefix, an algorithm label, the context and a message hash; the label is also ML-DSA's context.
⚠️
Composites trade uniqueness for a hedge. Use composite ML-DSA where relying on either component is the goal, never where a signature must be the only valid one for its message.

Moving keys between modules, issuers and formats

The format rules combine into a migration problem that is easy to create and impossible to fix afterwards. Suppose an organization generates agent identity keys in a hardware module that exports only the expanded private key, and later wants the same agents to present JSON Web Tokens signed by a token issuer that stores keys as JSON Web Keys. RFC 9964 requires the private value to be the 32-byte seed, and RFC 9881 explains that the seed cannot be recovered from the expanded key. The keys cannot make the move. The only remedy is to generate new keys and re-register every agent, which, at agent-platform scale, is an incident rather than a maintenance task. The decision that prevents it is made once, at key generation: keep the seed.

The opposite direction has its own trap. A system that receives a key in the both format and simply trusts one half may end up signing with a different key from the one another system derived from the other half. RFC 9881 recommends the consistency check precisely so that a single key file cannot silently represent two keys. RFC 9964 adds the equivalent warning for public and private members of an AKP key that have been tampered with or confused, noting consequences up to private-key compromise. Both point to the same discipline: treat the seed as the source of truth, derive everything else from it on load, and reject inputs whose derived values disagree with what was supplied.

Finally, a seed is bound to its parameter set. FIPS 204 added domain separation to key generation so that the same seed expanded for ML-DSA-44 and for ML-DSA-87 produces unrelated keys, a change Appendix D.3 describes as misuse resistance. That protects against an accidental cross-use, but it also means a key record must store the parameter set alongside the seed; a seed alone does not say which key it is. Key inventories built for agent fleets should therefore record seed, parameter set and format as a unit, and migrations should carry all three.

Choosing parameter sets by role

FIPS 204 assigns ML-DSA-44, ML-DSA-65 and ML-DSA-87 to NIST security categories two, three and five, and the profiles let each be used anywhere. Neither the standard nor the RFCs say which role should use which set, so the choice is a deployment decision, and this article proposes reasoning rather than a rule. Three factors dominate: how long a signature must remain trustworthy after it is made, how many relying parties will process the signature and the public key, and whether the key-generation environment meets the generator strength the parameter set requires.

Long-lived anchors, such as root and issuing authorities and model-release provenance that must verify for many years, are signed rarely and verified widely, so their size cost is small relative to the value of margin; the largest parameter set is a natural fit, and RFC 9882's digest table then calls for 512-bit digests in their signed attributes. Agent workload identities and certificates that live for days or weeks sit comfortably in the middle category, which balances margin against the size every relying party must process. High-volume, very short-lived tokens are where the smallest set is most tempting because every signature travels in every request; FIPS 204 notes, though, that ML-DSA-44 reaches category two only when keys are generated with a generator of at least 192 bits of security strength and falls to category one with a weaker one, so the environment that generates those keys has to be checked, not assumed.

Whatever mapping a platform chooses, it should be written down per role and enforced at issuance, not chosen per team. Mixed parameter sets inside one trust chain are allowed, and a chain is as strong as its weakest signature, so the policy question is less which set is best and more which set is the floor for each role.

Agent identities, tool-call tokens and provenance

Agents touch all three formats. An agent's workload identity is usually a certificate or a key registered with an identity provider; the tokens it presents to tools are usually JSON Web Tokens or their binary counterparts; and the models and artifacts it uses carry provenance signatures in CMS or similar envelopes. Each format's ML-DSA profile has a consequence for agent design.

Identity first. Generate agent keys from seeds in a module, retain the seed as the backed-up form, and record in the agent's registration which parameter set and format are in use. Assert only the key usages an agent needs, which is almost always digital signature alone. Because ML-DSA is strongly unforgeable and composites are not, prefer pure ML-DSA certificates for agent identities wherever relying parties can verify ML-DSA, and reserve composites for the transitional cases where relying parties are mixed and the system has confirmed that it never treats signatures as unique identifiers.

Tokens next. An ML-DSA-signed bearer token is several kilobytes long, so short-lived tokens should travel where size limits are known and generous, keys should be identified by thumbprint rather than embedded, and high-volume tool calls may be better served by a binary encoding or by signing a compact request digest than by sending a full token per call. Provenance last. Model releases and their attestations fit naturally into CMS with signed attributes, using a parameter set and digest whose strength matches how long the evidence must remain trustworthy.

What the RFCs leave to you

The documents are careful to standardize encodings and leave policy to deployers. That is the right division, but it means several decisions with security consequences will be made by default if nobody makes them on purpose. The table below lists them with the standards' position and the decision that remains. Taken together they form a checklist for any team adopting ML-DSA for certificates, signed artifacts or tokens, and especially for agent platforms, where keys, tokens and signatures are created at a volume that turns small defaults into large exposures.

Decisions the ML-DSA profiles settle and those they leave open; the right-hand column is this article's synthesis.
DecisionWhat the standards sayWhat remains yours
Private-key storageSeed recommended; JOSE/COSE seed only; retain seedMake seeds the backup and escrow form; check consistency on import
Pre-hash modeHashML-DSA excluded from all three profilesUse external mu or signed attributes for large content
Context stringEmpty in X.509, CMS and JOSE/COSESeparate purposes in the payload and with separate keys
Key usageSignature-type bits onlyAssert the minimum each agent role needs
Token sizeSizes tabulated; thumbprints suggestedChoose transport, encoding and key identification for multi-kilobyte tokens
CompositesNot SUF against quantum adversaries; not for SUF-critical useDecide where uniqueness matters before adopting them
Pilot keysDilithium and ML-DSA incompatibleInventory and reissue pre-standard keys and certificates

Key takeaways

  • RFC 9881 (X.509), RFC 9882 (CMS) and RFC 9964 (JOSE/COSE) all use pure ML-DSA with an empty context; the composite draft awaited publication in October 2026.
  • Expanding a seed is one-way and JOSE/COSE accept only the 32-byte seed, so retain seeds as the portable, backed-up form and check seed-expanded consistency on import.
  • ML-DSA certificates may assert only signature-type key usages; agent workload identities usually need digital signature alone.
  • The AKP key type binds thumbprints to one algorithm; base64url makes an ML-DSA-65 token signature 4,412 characters, enough to trip header limits that classical tokens never reached.
  • Composite ML-DSA uses a prefix and label for domain separation and weak non-separability, but its draft states it is not strongly unforgeable against quantum adversaries.
  • Agent platforms should make the left-open decisions explicitly: seed custody, pre-hash path, purpose separation, token transport, and where composites are acceptable.

Practitioner Toolkit

Copy-paste, strictly defensive artifacts you can use today. Nothing here attacks a real system.

✅ML-DSA profile review for certificates and tokenschecklist

Run before issuing the first ML-DSA certificate or token in production.

  • Keys are generated from seeds and the seed is the retained, backed-up form.
  • Imported keys in both format pass a seed-to-expanded consistency check.
  • Public values are derived from seeds on load rather than trusted from storage.
  • Certificates assert only signature-type key usages; agent identities use digital signature only.
  • No HashML-DSA identifiers appear in certificates, CMS or JOSE/COSE objects.
  • Context strings are empty where the profile requires it; purpose is separated in payloads and keys.
  • Token transport has been tested end to end with multi-kilobyte ML-DSA signatures.
  • Keys are identified by AKP thumbprints that include the algorithm.
  • Composite signatures are used only where no component treats signatures as unique identifiers.
  • Pre-standard Dilithium keys and certificates have been inventoried and reissued.
🔒Agent identity and token profilepolicy

Illustrative profile for agent workload identities using ML-DSA.

agent_identity_profile:
  algorithm: ML-DSA-65
  private_key:
    stored_form: seed            # 32 bytes, protected like the key itself
    backup: seed_only_escrow
    on_import_both_format: consistency_check_required
  certificate:
    key_usage: [digitalSignature]
    composite: not_used          # signatures may serve as identifiers downstream
  tokens:
    format: JWS_compact_or_COSE
    alg: ML-DSA-65
    kid: akp_jwk_thumbprint      # covers kty, alg, pub
    ctx: empty                   # required by RFC 9964
    max_lifetime: short
    transport_tested_size: true  # several kilobytes per token
  provenance:
    envelope: CMS_signed_attributes
    digest: SHA-512
Illustrative documentation template, not a product configuration.
🚀First steps for an ML-DSA PKI pilotquickstart

Ordered actions for a team starting with ML-DSA certificates and tokens.

  • Inventory and retire any pre-standard Dilithium keys.
  • Choose the seed as the stored and backed-up private-key form.
  • Issue ML-DSA leaf certificates with digital signature usage only.
  • Measure real token sizes through every proxy and gateway in the path.
  • Decide, in writing, where composite certificates are and are not acceptable.

Glossary

Seed (ML-DSA)
The 32-byte random value from which FIPS 204 key generation deterministically derives both the private and public keys.
Expanded private key
The full encoded ML-DSA private key derived from the seed, 2,560 to 4,896 bytes depending on parameter set.
AKP (Algorithm Key Pair)
The JOSE and COSE key type defined in RFC 9964 with algorithm, public and private members, used for ML-DSA keys.
JWK thumbprint
A hash over a key's required members that serves as a stable key identifier; for AKP keys it covers the algorithm and public value.
Base64url
A text encoding that maps every three bytes to four URL-safe characters, used for signatures in JSON Web Signatures.
Composite ML-DSA
A hybrid signature algorithm that combines ML-DSA with a classical signature under one identifier, verifying only if both components verify.
Weak non-separability
The property that one component of a hybrid signature cannot be removed and presented alone without leaving evidence of the removal.
keyUsage extension
An X.509 certificate extension that restricts the purposes for which the certified public key may be used.

References

  1. RFC 9881, Algorithm Identifiers for the Module-Lattice-Based Digital Signature Algorithm (ML-DSA) in the Internet X.509 PKI (2025)
  2. RFC 9882, Use of the ML-DSA Signature Algorithm in the Cryptographic Message Syntax (2025)
  3. RFC 9964, ML-DSA for JSON Object Signing and Encryption (JOSE) and CBOR Object Signing and Encryption (COSE) (2026)
  4. Ounsworth et al., Composite ML-DSA for use in X.509 Public Key Infrastructure, draft-ietf-lamps-pq-composite-sigs
  5. NIST FIPS 204, Module-Lattice-Based Digital Signature Standard (2024), Sections 3.6.3 and Appendix D.3
  6. RFC 9110, HTTP Semantics, Section 5.4 Field Limits
  7. RFC 7638, JSON Web Key (JWK) Thumbprint
  8. RFC 5280, Internet X.509 Public Key Infrastructure Certificate and CRL Profile