Network Working Group R. Burls Internet-Draft Aelethion OU Intended status: Standards Track 21 July 2026 Expires: 22 January 2027 Merkle Tree Agent Certificates (MTAC): Batch-Issued Post-Quantum Identity Credentials for AI Agents draft-burls-mtac-00 Abstract This document specifies Merkle Tree Agent Certificates (MTAC), a credential format and issuance profile in which a certificate authority commits a batch of AI agent identity credentials to a Merkle tree, signs only the tree head with the post-quantum signature algorithm ML-DSA-65, and distributes a per-credential inclusion proof. A relying party verifies a credential offline against the signed tree head without contacting the issuer. Each batch root is additionally co-signed by an independently keyed witness, providing per-batch integrity and continuity attestation, and its root can be corroborated against an independent public record. MTAC defines the leaf structure, its deterministic encoding, the leaf hash preimage, the signed tree head wire format, the witness co- signature, and an optional challenge-response proof of possession that binds a credential to a holder key. Test vectors are provided. This document specifies a credential issuance and verification mechanism. Declared scopes carried in a credential are self-reported parameters recorded at issuance; this document does not specify a runtime authorization mechanism. Status of This Memo This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79. Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet- Drafts is at https://datatracker.ietf.org/drafts/current/. Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress." This Internet-Draft will expire on 22 January 2027. Burls Expires 22 January 2027 [Page 1] Internet-Draft MTAC July 2026 Copyright Notice Copyright (c) 2026 IETF Trust and the persons identified as the document authors. All rights reserved. This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/ license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Revised BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Revised BSD License. Table of Contents 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3 1.1. Position of this work . . . . . . . . . . . . . . . . . . 4 1.2. What this document does not specify . . . . . . . . . . . 4 2. Conventions and Definitions . . . . . . . . . . . . . . . . . 5 3. Architecture Overview . . . . . . . . . . . . . . . . . . . . 6 4. MtacLeaf . . . . . . . . . . . . . . . . . . . . . . . . . . 6 4.1. Structure . . . . . . . . . . . . . . . . . . . . . . . . 6 4.2. Canonical encoding . . . . . . . . . . . . . . . . . . . 7 4.2.1. Map key ordering, worked . . . . . . . . . . . . . . 8 4.3. Declared scopes . . . . . . . . . . . . . . . . . . . . . 9 5. Leaf hash . . . . . . . . . . . . . . . . . . . . . . . . . . 9 5.1. Test vector . . . . . . . . . . . . . . . . . . . . . . . 11 6. Signed Tree Head . . . . . . . . . . . . . . . . . . . . . . 11 6.1. Wire format . . . . . . . . . . . . . . . . . . . . . . . 11 6.2. Signature and domain separation . . . . . . . . . . . . . 12 6.3. Relationship to ML-DSA in JOSE and COSE . . . . . . . . . 13 7. Inclusion proof . . . . . . . . . . . . . . . . . . . . . . . 13 8. Witness co-signature . . . . . . . . . . . . . . . . . . . . 14 8.1. Purpose and limits . . . . . . . . . . . . . . . . . . . 14 8.2. Co-signature format . . . . . . . . . . . . . . . . . . . 14 8.3. Witness trust root . . . . . . . . . . . . . . . . . . . 15 8.4. High-water mark . . . . . . . . . . . . . . . . . . . . . 15 9. Holder proof of possession . . . . . . . . . . . . . . . . . 16 9.1. Thumbprint computation . . . . . . . . . . . . . . . . . 16 9.1.1. Test vector . . . . . . . . . . . . . . . . . . . . . 17 9.2. Committed form . . . . . . . . . . . . . . . . . . . . . 17 9.3. Challenge and response . . . . . . . . . . . . . . . . . 17 9.4. Verifier requirements . . . . . . . . . . . . . . . . . . 18 10. Verification . . . . . . . . . . . . . . . . . . . . . . . . 18 10.1. Primary verification . . . . . . . . . . . . . . . . . . 18 10.2. Freshness and replay . . . . . . . . . . . . . . . . . . 19 10.3. Additive checks . . . . . . . . . . . . . . . . . . . . 19 Burls Expires 22 January 2027 [Page 2] Internet-Draft MTAC July 2026 10.4. Public corroboration . . . . . . . . . . . . . . . . . . 19 11. Roadmap and extensions . . . . . . . . . . . . . . . . . . . 19 11.1. Batch-scoped revocation . . . . . . . . . . . . . . . . 20 11.2. Third-party witnessing and enumeration . . . . . . . . . 20 12. Relationship to existing work . . . . . . . . . . . . . . . . 20 12.1. Merkle Tree Certificates . . . . . . . . . . . . . . . . 20 12.2. SCITT . . . . . . . . . . . . . . . . . . . . . . . . . 20 12.3. Certificate Transparency . . . . . . . . . . . . . . . . 20 12.4. Other agent identity work . . . . . . . . . . . . . . . 21 13. Implementation Status . . . . . . . . . . . . . . . . . . . . 23 13.1. Reference verifier . . . . . . . . . . . . . . . . . . . 23 13.2. What the published version verifies . . . . . . . . . . 24 13.3. Verified behaviour . . . . . . . . . . . . . . . . . . . 24 13.4. Public corroboration deployment . . . . . . . . . . . . 25 14. Security Considerations . . . . . . . . . . . . . . . . . . . 25 14.1. The issuance-time boundary . . . . . . . . . . . . . . . 25 14.2. Challenge freshness . . . . . . . . . . . . . . . . . . 25 14.3. Bearer behaviour by default . . . . . . . . . . . . . . 26 14.4. Encoding malleability . . . . . . . . . . . . . . . . . 26 14.5. Trust root distribution . . . . . . . . . . . . . . . . 26 14.6. Witness limits . . . . . . . . . . . . . . . . . . . . . 26 14.7. Post-quantum posture . . . . . . . . . . . . . . . . . . 27 15. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 27 16. References . . . . . . . . . . . . . . . . . . . . . . . . . 27 16.1. Normative References . . . . . . . . . . . . . . . . . . 27 16.2. Informative References . . . . . . . . . . . . . . . . . 28 Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . . 29 Author's Address . . . . . . . . . . . . . . . . . . . . . . . . 29 1. Introduction Autonomous AI agents increasingly act across organizational boundaries. A relying party receiving a request from such an agent needs to determine what credential that agent was issued, by which authority, under what declared parameters, and whether that credential is present in a tamper-evident log that can be independently checked. Existing credential formats address parts of this problem, but issuing an individual signed certificate per agent scales poorly when agent populations are large and credential lifetimes are short, and post-quantum signatures are substantially larger than the classical signatures they replace. Merkle Tree Agent Certificates (MTAC) addresses this by making the batch, rather than the individual credential, the unit of issuance. A certificate authority collects agent identity assertions over a batch window, constructs a Merkle tree over the resulting leaves, and produces a single ML-DSA-65 [FIPS204] signature over the tree head. Each agent receives an inclusion proof of size logarithmic in the Burls Expires 22 January 2027 [Page 3] Internet-Draft MTAC July 2026 batch size. One signing operation covers the whole batch, and verification is a local hash computation against a signed tree head that the verifier already holds. 1.1. Position of this work As of 21 July 2026, no third-party public document, specification, or shipped system specifies Merkle batch issuance as the unit of credential issuance for AI agent identity under post-quantum (ML-DSA- 65) signed tree heads, with each batch root independently co-signed by a distinct witness key and publicly corroborated. Adjacent work occupies other compositions. MAGIQ (arXiv:2605.06933) performs post-quantum batch authorization over a private, unlogged aggregation and states that it provides no revocation. The GoDaddy Agent Name Service operates a production, publicly queryable log labelled RFC9162_SHA256 recording per-entry agent registrations under classical signatures. draft-coetzee-oauth-spt-txn-tokens co-signs Merkle tree heads with an external witness over post-hoc authorization receipts rather than over credential issuance. draft- fane-opena2a-aip and draft-sharif-apki-agent-pki perform per-event Certificate Transparency style logging of agent credentials. [I-D.ietf-plants-merkle-tree-certs] specifies post-quantum Merkle batch issuance for non-agent subjects, and its working group is chartered for WebPKI and TLS. The closest artifact is a shipped implementation rather than a specification. CIRISVerify requires hybrid Ed25519 and ML-DSA-65 signed tree heads over an RFC 6962 log for AI agents, and additionally defines N-of-M co-signature of those tree heads by independently keyed witnesses. It holds every element named above except one: its log records licence verification events, and its licences are signed individually rather than committed as a batch. *The distinguishing property of this specification is therefore the issuance unit, not the witness arrangement and not the use of post- quantum signatures*, both of which are present in prior work. See Section 12. This document does not claim novelty in Merkle tree construction, in inclusion proofs, in post-quantum signatures, or in carrying an inclusion proof alongside a credential. Each of those is established practice, and Section 12 identifies where. 1.2. What this document does not specify The distinction matters for correct implementation, so it is stated here rather than only in Section 14. Burls Expires 22 January 2027 [Page 4] Internet-Draft MTAC July 2026 Declared scopes in an MTAC leaf are self-reported parameters recorded at issuance. This document specifies how they are encoded, committed, and verified as having been issued. It does not specify a runtime authorization mechanism, and a relying party MUST NOT treat the presence of a scope token as evidence that the agent operated within it. Verification establishes that a credential was validly issued by the named authority and is present in the log at the given tree head. It does not establish what the agent subsequently did. 2. Conventions and Definitions The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here. Batch: The set of agent identity assertions committed to a single Merkle tree by one certificate authority during one batch window. Leaf: The canonical encoding of a single agent identity assertion, as defined in Section 4. Leaf hash: The 32-octet SHA-256 value computed over the preimage defined in Section 5. Signed Tree Head (STH): The structure defined in Section 6, binding a log identifier, a tree size, a timestamp, and a Merkle root, signed with ML-DSA-65. Witness: An entity holding a signing key distinct from the certificate authority key, which co-signs batch roots as described in Section 8. Holder commitment: A thumbprint of a public key, carried as a scope token in a leaf, committing the credential to a key whose possession can later be demonstrated (Section 9). Declared scope: A self-reported parameter recorded in a leaf at issuance. The term "declared" is load-bearing throughout this document. Burls Expires 22 January 2027 [Page 5] Internet-Draft MTAC July 2026 3. Architecture Overview A certificate authority (CA) operates a log. The log has a log_id, defined in Section 6 as the SHA-256 of the CA's raw ML-DSA-65 public key. During a batch window the CA collects agent identity assertions. At the close of the window it encodes each assertion as a leaf (Section 4), computes each leaf hash (Section 5), constructs a Merkle tree following the structure of [RFC9162] Section 2.1, and signs the resulting tree head (Section 6). A witness independently co-signs the batch root (Section 8). Each agent receives its leaf, its inclusion proof, and the signed tree head. A relying party verifies by recomputing the leaf hash from the leaf bytes, folding the inclusion proof to a root, comparing that root against the signed tree head, and verifying the ML-DSA-65 signature over the tree head. All four steps are local computation. No network interaction with the CA is required at verification time. 4. MtacLeaf 4.1. Structure An MtacLeaf contains exactly six fields. All six are mandatory. There are no optional fields in schema version 1. Burls Expires 22 January 2027 [Page 6] Internet-Draft MTAC July 2026 +===================+=============+===============================+ | Field | CBOR type | Description | +===================+=============+===============================+ | schema_version | unsigned | MUST be 1 | | | integer | | +-------------------+-------------+-------------------------------+ | agent_id | text string | Identifier of the agent | +-------------------+-------------+-------------------------------+ | sponsor_id | text string | Identifier of the sponsoring | | | | entity | +-------------------+-------------+-------------------------------+ | authorized_scopes | array of | Declared scopes; see | | | text string | Section 4.3 | +-------------------+-------------+-------------------------------+ | not_before | unsigned | Start of the validity window, | | | integer | seconds since the Unix epoch | +-------------------+-------------+-------------------------------+ | not_after | unsigned | End of the validity window, | | | integer | seconds since the Unix epoch | +-------------------+-------------+-------------------------------+ Table 1 schema_version is an ordinary map entry. It is not a CBOR tag and not an envelope. A decoder that encounters schema_version other than 1 MUST reject the leaf. Implementations MUST NOT assume that not_before is less than or equal to not_after. The encoding layer is value-agnostic, and coherence of the validity window is a policy check performed above this layer. A verifier that requires a coherent window MUST check it explicitly. 4.2. Canonical encoding A leaf is encoded as a CBOR [RFC8949] map using the deterministic encoding rules of [RFC8949] Section 4.2.1 (CDER), with the additional constraints in this section. The rules below are normative and are restated here rather than incorporated by reference, because two of them are commonly implemented incorrectly and both change the leaf hash. 1. *Map key ordering is bytewise over the ENCODED key.* Keys MUST be sorted by comparing their complete CBOR encodings as octet strings, which includes the initial length head. This is not string-lexicographic ordering of the key text. See Section 4.2.1. Burls Expires 22 January 2027 [Page 7] Internet-Draft MTAC July 2026 2. *Integers MUST use the shortest form.* An encoder MUST NOT emit a value in a wider representation than necessary. A decoder MUST reject non-shortest-form integers. 3. *Text strings MUST be in Unicode Normalization Form C (NFC), and normalization is applied before the length head is computed.* An encoder that emits non-NFC UTF-8 produces a different leaf hash for a semantically equal leaf. A decoder MUST reject text that is not in NFC. 4. *Duplicate map keys MUST be rejected* by decoders. 5. *Array element order is preserved and is significant.* Only map keys are reordered by the canonical form. Two leaves whose authorized_scopes contain the same elements in a different order are different leaves with different leaf hashes. Implementations MUST NOT sort authorized_scopes as a normalization step. A decoder that accepts any of the forms this section requires to be rejected introduces malleability: two distinct octet strings would decode to the same leaf, while hashing to different leaf hashes. 4.2.1. Map key ordering, worked The six schema version 1 keys, with their encoded first octet: +===================+========+=====================+ | Key | Length | First encoded octet | +===================+========+=====================+ | agent_id | 8 | 0x68 | +-------------------+--------+---------------------+ | not_after | 9 | 0x69 | +-------------------+--------+---------------------+ | not_before | 10 | 0x6a | +-------------------+--------+---------------------+ | sponsor_id | 10 | 0x6a | +-------------------+--------+---------------------+ | schema_version | 14 | 0x6e | +-------------------+--------+---------------------+ | authorized_scopes | 17 | 0x71 | +-------------------+--------+---------------------+ Table 2 Because the length head is the first octet compared, shorter keys sort first. The correct order is therefore: Burls Expires 22 January 2027 [Page 8] Internet-Draft MTAC July 2026 agent_id, not_after, not_before, sponsor_id, schema_version, authorized_scopes Sorting the same six keys as text strings yields a different order: agent_id, authorized_scopes, not_after, not_before, schema_version, sponsor_id An implementation that produces the second order produces a different octet string and therefore a different leaf hash. This is the single most likely source of interoperability failure in this specification. 4.3. Declared scopes authorized_scopes is an array of text strings. Two token classes are defined. A capability scope token describes an operation class the agent declares it may perform. Capability scope tokens are self-reported by the requesting entity and recorded by the CA. They are declared parameters. This document specifies no vocabulary for them and no mechanism by which they constrain agent behaviour. A holder commitment token has the form aegis:holder:, where is the 43-character thumbprint defined in Section 9.1. A holder commitment token is a key commitment. It grants nothing and gates nothing by itself. It is not a permission and not an access grant. Its only function is to identify the key whose possession may be demonstrated under Section 9. A relying party MUST NOT interpret either token class as evidence about agent behaviour. 5. Leaf hash The leaf hash is SHA-256 over a preimage of exactly four concatenated segments: Burls Expires 22 January 2027 [Page 9] Internet-Draft MTAC July 2026 +========+========+===============================+ | Offset | Length | Contents | +========+========+===============================+ | 0 | 1 | 0x00, the [RFC9162] | | | | Section 2.1.1 leaf type octet | +--------+--------+-------------------------------+ | 1 | 16 | DOMAIN_LABEL, defined below | +--------+--------+-------------------------------+ | 17 | 32 | CA public key fingerprint, | | | | defined below | +--------+--------+-------------------------------+ | 49 | L | The canonical leaf encoding | | | | from Section 4.2 | +--------+--------+-------------------------------+ Table 3 The total preimage length is 49 + L octets. DOMAIN_LABEL is the following 16 octets: "aegis-leaf/v1\n\0\0" 61 65 67 69 73 2d 6c 65 61 66 2f 76 31 0a 00 00 The CA public key fingerprint is the SHA-256 of the *raw 1952-octet ML-DSA-65 public key* as defined by [FIPS204] Section 5.3. The public key MUST NOT be wrapped in any ASN.1, DER, or other structure before hashing. Implementations that wrap the key before hashing will compute a different fingerprint, a different leaf hash, and will fail to interoperate. The same 32-octet value is used as the log_id in Section 6. One value therefore binds a leaf to its issuer and identifies the log in the signed tree head. No length prefix and no separator appears before the trailing leaf encoding. The construction is unambiguous because the three preceding segments are of fixed width, so the boundary between the fingerprint and the leaf encoding is determined by position alone. Implementations MUST NOT insert a length prefix. Leaf index and batch epoch are deliberately absent from the preimage. Position in the tree is bound by the inclusion proof and the verification algorithm that consumes leaf_index, following [RFC9162] Section 2.1.3.2. Burls Expires 22 January 2027 [Page 10] Internet-Draft MTAC July 2026 5.1. Test vector The following vector is fully reproducible. The CA public key is synthetic and defined by a rule rather than supplied as a blob, so no key file is required. Leaf field values: schema_version : 1 agent_id : "urn:aegis:agent:f01" sponsor_id : "sponsor@example.com" authorized_scopes : ["scope:read"] not_before : 1713600000 not_after : 1745136000 Canonical leaf encoding, L = 138 octets: a6686167656e745f69647375726e3a61656769733a6167656e743a663031696e6f745f61 667465721a6804a9806a6e6f745f6265666f72651a662376006a73706f6e736f725f6964 7373706f6e736f72406578616d706c652e636f6d6e736368656d615f76657273696f6e01 71617574686f72697a65645f73636f706573816a73636f70653a72656164 CA public key: 1952 octets where octet i has value (i mod 256), for i from 0 to 1951. Its SHA-256 fingerprint is: 0a9594d4796731c68bae082ee8641342b7782bd5eac0919dea05c16a4f48683d Preimage length: 1 + 16 + 32 + 138 = 187 octets. Resulting leaf hash: 8dd4e9aad96815df9ffe9fddb2d7ff7e867cc345a771b2d40fc8e464f04b9995 An implementation that reproduces this value has correctly implemented Section 4.2 and this section, including the map key ordering of Section 4.2.1. 6. Signed Tree Head 6.1. Wire format The signed tree head is a CBOR array of two elements: Burls Expires 22 January 2027 [Page 11] Internet-Draft MTAC July 2026 array(2)[ tstr "AEGIS-STH-v1", bstr( array(5)[ log_id bstr(32), tree_size uint, timestamp uint, root_hash bstr(32), sth_extensions array ] ) ] The envelope and the body are emitted in definite-length shortest form. The octet string in position 1 is the signed message: the signature is computed over exactly those octets as received. *A verifier MUST verify over the received octets and MUST NOT re-encode the body before verifying*, because any re-encoding that differs by a single octet produces a different message and a failed verification. log_id is the SHA-256 of the raw ML-DSA-65 CA public key, the same value used as the fingerprint in Section 5. timestamp is milliseconds since the Unix epoch. sth_extensions is an array, empty in this version. This document defines no extension semantics; the field exists so that the signed body has a place for future extension, and it is covered by the signature. Implementations MUST accept an empty array and MUST NOT assume the field is absent. *The wire order is tree_size before timestamp.* Implementations MUST emit and parse the body in the order given above. Any ordering derived from a struct declaration, a serialization library's field order, or alphabetical sorting is incorrect. 6.2. Signature and domain separation The signature is ML-DSA-65 [FIPS204] over the signed message, using the FIPS 204 Section 5.2 context parameter with the value: ctx = "AEGIS-STH-v1" Domain separation is therefore dual layer: the context string appears both as the tag in position 0 of the envelope, which is inside the hashed message, and as the FIPS 204 context, which is not. A verifier MUST supply the context string. Verifying with an empty context will reject valid signatures. The signature is 3309 octets. The CA public key is 1952 octets. Both lengths are as specified in [FIPS204] for ML-DSA-65 and are cross-referenced in [RFC9964]. Burls Expires 22 January 2027 [Page 12] Internet-Draft MTAC July 2026 6.3. Relationship to ML-DSA in JOSE and COSE MTAC signatures are raw [FIPS204] signatures. They are *not* JOSE or COSE signatures, and this document does not define a COSE or JOSE serialization. This distinction is stated explicitly because [RFC9964] Section 5 requires that "the ctx parameter MUST be the empty string for ML-DSA- 44, ML-DSA-65, and ML-DSA-87" when ML-DSA is used in JOSE or COSE, whereas every MTAC signature uses a non-empty FIPS 204 context. There is no conflict: that requirement governs the JOSE and COSE serializations [RFC9964] defines, and MTAC uses neither. [RFC9964] is cited normatively by this document for two things only: the AKP key type and the ML-DSA-65 algorithm name used in the holder thumbprint of Section 9.1, and the confirmation of [FIPS204] key and signature lengths. It is not cited as the serialization for any MTAC signature. An implementation that wishes to carry MTAC evidence inside COSE, for example as a COSE Receipt, cannot reuse an MTAC signature directly: a COSE object asserting ML-DSA-65 must have been produced with an empty context, so it would be a second, separate signature over a different input. That is a known consequence of the design and is discussed further in Section 12.2. 7. Inclusion proof An inclusion proof is a CBOR array of three elements, emitted in definite-length shortest form: array(3)[ tree_size uint, leaf_index uint, path array of bstr(32) ] *Note the element order: tree_size precedes leaf_index.* The two elements are both unsigned integers, so a decoder cannot detect a transposition by type, and an implementation that reverses them will verify single-leaf trees successfully while failing on every larger tree. This order is deliberately the same as the inclusion proof of [RFC9942] Section 5.2, so that an MTAC proof can be carried as a COSE Receipt proof without reordering. See Section 12. path contains the sibling hashes from the leaf to the root, in leaf- to-root order. Interior nodes are hashed with the 0x01 prefix, per [RFC9162] Section 2.1.1, so that no interior node hash can collide with a leaf hash, which uses the 0x00 prefix given in Section 5. Burls Expires 22 January 2027 [Page 13] Internet-Draft MTAC July 2026 For a tree of size 1 the path is empty and the leaf hash equals the root hash. A single-leaf proof therefore encodes as the four octets 83 01 00 80, which is array(3) followed by tree_size 1, leaf_index 0, and an empty path. Verification folds the path using the bits of leaf_index, following [RFC9162] Section 2.1.3. 8. Witness co-signature 8.1. Purpose and limits A witness holds a signing key distinct from the CA key and co-signs batch roots. The witness provides per-batch, independent-key co- signed integrity and continuity attestation. It protects a relying party that checks it against a compromise limited to the CA key, and against dropped or truncated batches. The witness described here does NOT provide non-equivocation. Achieving that property would require an independently operated third-party witness and a route by which entries can be enumerated, neither of which this document specifies. Implementers and reviewers comparing this mechanism against the receipts of [RFC9942], which does address that property, should note the difference. The witness check is additive: it does not replace the primary verification result defined in Section 10. 8.2. Co-signature format The witness signs a five-line note. The note is deliberately human- readable rather than CBOR, so that an auditor can inspect a co- signature artifact by eye. The signed octets are exactly, with no trailing octet after the final newline: AEGIS-WITNESS-v1\n origin:\n size:\n root_hash:\n timestamp:\n Byte-exact reconstruction is required to verify the signature, so each field is specified precisely: origin A textual log identifier, assigned by the operator and Burls Expires 22 January 2027 [Page 14] Internet-Draft MTAC July 2026 carried in the log's metadata. *It is not cryptographically bound to log_id in this version*, and a verifier MUST NOT treat it as an authenticated identifier. It is present so that a human auditor can tell two logs apart in a co-signature artifact. Binding it is a candidate for a future revision. size The tree_size of the signed tree head being co-signed, rendered as decimal ASCII with no leading zeros and no separators. root_hash_hex The root_hash of that signed tree head, rendered as exactly 64 *lowercase* hexadecimal characters. timestamp *The timestamp field of the signed tree head being co- signed*, rendered as decimal ASCII with no leading zeros. It is the log's timestamp, not the witness's own signing time, so a verifier reproduces it from the tree head rather than from any clock. The signature algorithm is ML-DSA-65 with the FIPS 204 context: ctx = "AEGIS-WITNESS-v1" This context MUST differ from the CA context of Section 6. A verifier MUST NOT accept a witness co-signature as a CA tree head signature or the reverse. The batch identifier is NOT part of the signed note. A verifier locates a co-signature by root_hash, not by batch identifier. 8.3. Witness trust root The witness public key is a trust root. A verifier MUST obtain it out of band, from a list of trusted witnesses it maintains, and *MUST NOT* take it from the co-signature artifact itself. An artifact- supplied key verifies its own contents and provides nothing: the artifact is controlled by the same party that produced it, so accepting an inline key reduces the check to self-attestation. A verifier that encounters a co-signature whose public key is not in its trusted list MUST treat the co-signature as untrusted rather than as absent, because the two conditions have different causes and a deployment may wish to distinguish them. 8.4. High-water mark To detect truncation of the batch sequence, a witness maintains a signed high-water mark. The signed payload is 21 octets: Burls Expires 22 January 2027 [Page 15] Internet-Draft MTAC July 2026 "AEGIS-HWM-v1:" || uint64_be(hwm) The FIPS 204 context for the high-water mark signature is: ctx = "AEGIS-HWM-v1" This context MUST differ from the contexts of Section 6 and Section 8.2. Note that the context string and the payload prefix are not the same octets: *the payload prefix carries a trailing colon and the context string does not.* An implementation that reuses one for the other will produce signatures no conforming verifier accepts. A verifier that observes a latest batch number lower than a previously observed signed high-water mark MUST treat the sequence as truncated. 9. Holder proof of possession This mechanism is OPTIONAL. A credential carrying no holder commitment is a bearer credential, and verification behaviour is unchanged. 9.1. Thumbprint computation The holder commitment is the base64url encoding, without padding [RFC4648] Section 5, of the SHA-256 of a canonical JSON object with exactly three members, in this order: {"alg":"ML-DSA-65","kty":"AKP","pub":""} There is no whitespace. The member order is lexicographic by member name, as required by the [RFC7638] Section 3 process. The kty value AKP and the algorithm name ML-DSA-65 are as registered in [RFC9964] Section 3. The pub member carries the raw [FIPS204] Section 5.3 public key encoding. The resulting thumbprint is 43 characters. *This document specifies SHA-256 as the thumbprint hash.* Neither [RFC7638] nor [RFC9964] mandates a particular hash for this computation: [RFC7638] Section 3.4 leaves the choice to the application. Implementations MUST use SHA-256 for MTAC holder commitments. The COSE integer values registered in [RFC9964] for the key type and algorithm are not used in this computation. The JSON member values are the strings above. Burls Expires 22 January 2027 [Page 16] Internet-Draft MTAC July 2026 9.1.1. Test vector Using the same synthetic key rule as Section 5.1, namely 1952 octets where octet i has value (i mod 256), the canonical JSON object begins: {"alg":"ML-DSA-65","kty":"AKP","pub":"AAECAwQFBgcICQoLDA0ODx... and the resulting thumbprint is: u0JcdAyiIOVlMstYWc-w2n2RJ437Y3-WbE4QfBHG35U One synthetic key therefore serves both test vectors in this document. 9.2. Committed form The commitment is carried as a single scope token in authorized_scopes: aegis:holder:<43-character thumbprint> The token is 56 characters. No field is added to the leaf. The leaf structure of Section 4 is unchanged, and a verifier that does not implement this section parses the leaf normally and treats the token as an opaque scope string. 9.3. Challenge and response A verifier generates a challenge and transmits it to the presenting party. The presenting party signs a payload constructed as a CBOR array of two elements, encoded in definite-length shortest form: array(2)[ bstr(challenge), tstr(session_identifier) ] *The session identifier is the value of the leaf's agent_id field.* It is taken from the verified leaf, not from any value the presenting party supplies. The signature uses ML-DSA-65 with the FIPS 204 context: ctx = "AEGIS-HOLDER-v1" This gives three-way domain separation across the tree head, witness, and holder contexts. Payload test vector, for a 16-octet challenge of 00 01 02 ... 0f and session identifier urn:aegis:session:golden: Burls Expires 22 January 2027 [Page 17] Internet-Draft MTAC July 2026 8250000102030405060708090a0b0c0d0e0f781875726e3a61656769733a 73657373696f6e3a676f6c64656e 9.4. Verifier requirements A verifier performing a possession check MUST: 1. Reconstruct the signed payload from the challenge IT generated and the session identifier committed in the credential. It MUST NOT use values supplied by the presenting party for either. 2. Verify the signature BEFORE comparing the thumbprint. The check order is signature first, then thumbprint. 3. Recompute the thumbprint from the presented public key per Section 9.1 and compare it against the committed token. A challenge MUST be at least 16 octets. *Challenge uniqueness is an operational obligation of the verifier.* This specification defines no challenge generator, no nonce store, no replay ledger, and no challenge expiry. A verifier that reuses a challenge, or that accepts a challenge it did not itself generate, obtains no possession guarantee. See Section 14. A successful possession check demonstrates that the presenting party holds the private key committed at issuance, at the time of presentation. It does not establish that the presenting party is the agent named in the credential, and it does not establish independent actor status. Where a single operator holds both the CA key and the holder key, key custody is deployment-dependent. 10. Verification 10.1. Primary verification A relying party verifying a credential MUST perform all of the following: 1. Decode the leaf, rejecting any non-canonical form per Section 4.2. 2. Recompute the leaf hash per Section 5. 3. Fold the inclusion proof to a candidate root. 4. Compare the candidate root against root_hash in the signed tree head. Burls Expires 22 January 2027 [Page 18] Internet-Draft MTAC July 2026 5. Verify the ML-DSA-65 signature over the signed tree head with the context of Section 6, using a CA public key obtained out of band. The result of primary verification is that the credential was validly issued by the authority identified by log_id and is present in the log at the given tree head. This is the complete meaning of a successful result. It carries no implication about the agent's subsequent behaviour. The CA public key is a trust root. It MUST be obtained out of band and pinned. A verifier that accepts a CA public key supplied alongside the credential obtains no security property, because a substituted key accompanied by a re-signed tree head verifies successfully. 10.2. Freshness and replay A verifier MAY additionally require freshness by rejecting a tree head older than a configured maximum age, and MAY reject a tree head whose timestamp is not strictly greater than the last one observed for the same log_id. Both are implemented in the reference verifier described in Section 13. 10.3. Additive checks The witness check of Section 8 and the possession check of Section 9 are additive. Where a relying party demands one and it fails, that is a distinct outcome from primary verification failure, and implementations SHOULD signal the two distinctly. 10.4. Public corroboration An MTAC log operator MAY publish batch roots to an independent public medium so that a relying party can confirm that a root matches what the log committed, without trusting the log operator. Where such corroboration is published on a public ledger, the published value corroborates the signed tree head Merkle root only. It does not establish anything about agent behaviour, and the availability properties of the publishing medium are outside the scope of this document. 11. Roadmap and extensions This section is INFORMATIVE and describes work that is NOT implemented and NOT specified by this document. It is included to indicate direction. Nothing in this section may be relied upon by an implementer. Burls Expires 22 January 2027 [Page 19] Internet-Draft MTAC July 2026 11.1. Batch-scoped revocation Because a batch has a bounded window, omitting an assertion from the next batch causes the credential to lapse at the end of the current window without a revocation list or an online status protocol. This document does not specify a revocation mechanism, and no revocation mechanism is implemented. 11.2. Third-party witnessing and enumeration An independently operated witness, together with a route by which log entries can be enumerated, would permit a stronger property than the one described in Section 8. Neither is specified here. 12. Relationship to existing work This section is INFORMATIVE. 12.1. Merkle Tree Certificates [I-D.ietf-plants-merkle-tree-certs] specifies batch Merkle issuance with post-quantum signed tree heads. It is the direct architectural antecedent of the issuance model used here. Its working group is chartered for WebPKI and TLS, its leaf encodes TLS certificate fields, and it contains no AI agent identity content. MTAC applies the same issuance shape to a different subject with a different leaf. 12.2. SCITT [RFC9943] defines an architecture for transparency over supply chain statements, and [RFC9942] defines receipts proving properties of a verifiable data structure. An MTAC signed tree head and inclusion proof are structurally analogous to a receipt over a Merkle verifiable data structure. [I-D.ietf-scitt-scrapi] defines reference APIs. A profile mapping MTAC batches onto SCITT statements and receipts is plausible future work and is not specified here. 12.3. Certificate Transparency The Merkle tree construction and the leaf type octet follow [RFC9162] Section 2.1.1. Note that both [RFC9162] and its predecessor [RFC6962] are Experimental. This document cites [RFC9162] because it is the later specification and defines the constructions used here; several adjacent agent-identity documents cite [RFC6962] instead, and implementers comparing them should be aware that the two differ. Burls Expires 22 January 2027 [Page 20] Internet-Draft MTAC July 2026 12.4. Other agent identity work The following documents address adjacent problems and several of them combine two or three of the same elements MTAC uses. Each is named and distinguished, because a reader who finds them independently is entitled to know why this document is not redundant with them. Revision numbers and dates are as of 21 July 2026. Documents that combine post-quantum signatures, a Merkle transparency structure, and AI agent identity, in some arrangement: * draft-fane-opena2a-aip-00 specifies hybrid Ed25519 and ML-DSA-65 agent credentials with an RFC 6962 style transparency log covering identity and credential issuance events. The logging is per event rather than per batch, and the batch is not the unit of issuance. * draft-sharif-apki-agent-pki-00 defines agent transparency logs as append only Merkle trees over agent certificate issuance, permits ML-DSA-65, and requires migration to post-quantum algorithms. It places one certificate per leaf, so issuance remains per certificate in the classical Certificate Transparency shape. * draft-ailex-vap-legal-ai-provenance-03 requires that events be batched into a binary Merkle hash tree following [RFC9162], and names ML-DSA-65. It is the closest work found on the batching mechanism itself. What is batched is audit events rather than identity credentials. * draft-marques-asqav-compliance-receipts-07 signs a root over a batch of receipts rather than signing each receipt, with ML-DSA-65 and Merkle inclusion proofs. The subject is compliance receipts for actions already taken, not credentials issued in advance. * draft-coetzee-oauth-spt-txn-tokens-03 requires both a classical and an ML-DSA signature, and periodically signs Merkle tree heads over an append only log with an external witness co-signature. That witness arrangement is the closest work found to Section 8. Its log covers post hoc authorization decision receipts. * draft-ihsanullah-dnsid-01 provides DNS anchored durable identity for AI agents with records published to a Certificate Transparency style log. Post-quantum support is algorithm agility rather than a requirement, and batches are an optional registration convenience rather than the issuance unit. * draft-rotzin-spice-afir-profile-00 uses ML-DSA-65 as its primary algorithm and composes with a Merkle inference chain. Its subject is inference provenance rather than an identity credential. Burls Expires 22 January 2027 [Page 21] Internet-Draft MTAC July 2026 Documents that combine a Merkle transparency structure with agent identity, without post-quantum signatures: * draft-hood-agtp-log-02 specifies a transparency log protocol aligned with [RFC9162] and issues receipts per [RFC9943]. It is a log protocol rather than a credential format, and it does not address post-quantum signatures. * draft-narajala-courtney-ansv2-01 establishes how an agent is named, discovered and anchored to a domain. MTAC defines no namespace and can carry any identifier in agent_id, so the two compose directly. Documents addressing request-time and after-the-fact concerns: * draft-klrc-aiagent-auth-03 addresses how an agent authenticates and is authorized at request time. MTAC addresses what credential was issued. The issuance-time boundary between the two is stated in Section 14. * draft-bu-agentproto-security-principal-binding-03 binds a security principal to an agent communication protocol. MTAC does not define a communication protocol. * draft-noa-scitt-ai-agent-receipt-00 profiles receipts for agent actions after they occur. A receipt layer composes with an issuance layer. * draft-dawkins-scitt-ai-article50-00 maps transparency artifacts to the EU AI Act Article 50 obligation. An MTAC credential provides evidence relevant to a provider's or deployer's Article 50(1) documentation. It does not substitute for the content-level machine-readable marking required by Article 50(2), and compliance is a legal status assessed by a competent authority. Beyond Internet-Drafts, at least one published implementation goes further than any of the drafts above and deserves to be described accurately. CIRISVerify (CIRISAI, AGPL-3.0) signs tree heads over an RFC 6962 log for AI agents with hybrid Ed25519 and ML-DSA-65 signatures, and requires both rather than permitting the post-quantum one as an option. *It also defines N-of-M co-signature of its tree heads by independently keyed witnesses, for split-view detection.* That is the same defensive shape as Section 8, arrived at independently, and this document does not claim the witness arrangement as novel. Burls Expires 22 January 2027 [Page 22] Internet-Draft MTAC July 2026 What differs is the unit. CIRISVerify's log records licence verification events, and its licences are signed individually rather than committed as a batch. Identity is rooted in a hardware key ceremony. The batch is not the thing issued. This document therefore does not claim that any individual element, or any pair of them, is unaddressed, and it does not claim the witness co-signature as its own idea. *The arrangement it specifies, in which the batch is the unit of credential issuance, is what the preceding list does not contain.* Every other property described here is present somewhere in the work above. 13. Implementation Status This section is to be removed before publication as an RFC, per [RFC7942]. 13.1. Reference verifier An independent verifier implementation is published and installable: pip install aegis-verifier==0.1.3 +==========+==============================================+ | Property | Value | +==========+==============================================+ | Version | 0.1.3 | +----------+----------------------------------------------+ | Released | 2026-05-21 | +----------+----------------------------------------------+ | License | Apache-2.0 | +----------+----------------------------------------------+ | Requires | Python 3.11 or later | +----------+----------------------------------------------+ | Coverage | Linux x86_64 and aarch64 (manylinux and | | | musllinux), macOS universal2, Windows x86_64 | +----------+----------------------------------------------+ Table 4 The distribution is built from a Rust core with PyO3 and maturin. liboqs is statically bundled, so no native build dependencies are required at install time. Burls Expires 22 January 2027 [Page 23] Internet-Draft MTAC July 2026 13.2. What the published version verifies Version 0.1.3 performs primary verification as defined in Section 10: signed tree head signature, Merkle inclusion, and leaf hash. It additionally implements the freshness and replay checks described in Section 10, exposing a stateful verifier that tracks the last seen tree head per log_id. Version 0.1.3 does NOT implement the witness co-signature check of Section 8 or the holder possession check of Section 9. Those checks were added to the issuing implementation after this version was released and are performed by the issuing side tooling. A future release is expected to cover them. 13.3. Verified behaviour The following were executed against the published distribution on 2026-07-21. Primary verification of a genuine ML-DSA-65 signed batch succeeded, returning leaf index, tree size, and tree head timestamp. Three negative controls were each rejected: a corrupted signature, a substituted CA public key, and a single flipped octet in the leaf. The leaf hash test vector of Section 5.1 was computed independently in two implementations, a Python reimplementation written from this document and the Rust reference, producing identical output. The thumbprint golden vector of Section 9.1 was likewise confirmed by executing the reference implementation's own test suite against the pinned reference revision. The FIPS 204 public key encoding was confirmed by taking the ML- DSA-65 example from [RFC9964] Appendix A, which the RFC states is the [FIPS204] Section 5.3 encoding, and verifying the RFC's published signature under the RFC's published public key using the same liboqs build the implementation uses. Verification succeeded and a tampered-message control was rejected. The decoder rejections required by Section 4.2 were each confirmed against the reference decoder: non-shortest-form integers, misordered map keys, duplicate map keys, and non-NFC text are all rejected. Burls Expires 22 January 2027 [Page 24] Internet-Draft MTAC July 2026 13.4. Public corroboration deployment The issuing implementation publishes batch roots to a contract on the Ethereum Sepolia testnet, dev-grade key. A relying party can compare a published root against the signed tree head root it already holds. The published value corroborates the signed tree head Merkle root only. 14. Security Considerations 14.1. The issuance-time boundary This is the most important consideration in this document. MTAC establishes what credential a session or agent was issued, by which authority, under what declared parameters, and that the credential is present in the log. It does not establish what the agent does at request time. A credential that verifies successfully may be held by an agent whose behaviour has since changed. Declared scopes are not proof of behaviour. A relying party that treats a scope token as a behavioural guarantee has made an error this specification cannot detect. Relying parties requiring assurance about request-time behaviour need a mechanism outside this document. 14.2. Challenge freshness The possession mechanism of Section 9 derives its value entirely from challenge freshness, and this specification places that obligation on the verifier. The software requirement is a minimum challenge length of 16 octets and nothing more. There is no challenge generator, no nonce store, no replay ledger, and no expiry defined here or implemented in the reference tooling. A verifier that reuses challenges, accepts challenges generated elsewhere, or fails to bind the challenge to the session under check obtains no possession guarantee, while the protocol appears to succeed. Implementers MUST generate challenges from a cryptographically secure random source, MUST use each challenge once, and SHOULD bind challenge lifetime to the transaction. Burls Expires 22 January 2027 [Page 25] Internet-Draft MTAC July 2026 14.3. Bearer behaviour by default A credential carrying no holder commitment is a bearer credential. Anyone holding the credential bytes can present them and primary verification will succeed. Where a relying party does not demand a possession check, behaviour is identical to bearer. Deployments requiring more MUST demand the check explicitly rather than assuming it occurred. 14.4. Encoding malleability The decoder requirements of Section 4.2 are security requirements, not style preferences. A decoder that accepts non-canonical forms permits two distinct octet strings to decode to the same logical leaf while hashing to different leaf hashes, which breaks the correspondence between what was committed and what is verified. The NFC requirement is easy to overlook. Two agent identifiers that render identically but differ in Unicode normalization produce different leaf hashes. The array-order requirement is similarly easy to overlook: implementations MUST NOT sort authorized_scopes. 14.5. Trust root distribution The CA public key is the trust root and MUST be pinned out of band. A verifier that takes the CA key from the same channel as the credential gains nothing, because an adversary supplying both a substituted key and a re-signed tree head produces a successful verification. The log_id binding of Section 5 means a substituted key also changes every leaf hash, so a mismatched pin is detectable, but only if a pin exists. 14.6. Witness limits The witness of Section 8 protects against a compromise limited to the CA key and against dropped or truncated batches. It does not protect against an adversary who controls both the CA key and the witness key, and it does not provide non-equivocation. A deployment operating both the CA and the witness under one administrative authority obtains integrity and continuity attestation, not independence. Burls Expires 22 January 2027 [Page 26] Internet-Draft MTAC July 2026 14.7. Post-quantum posture ML-DSA-65 [FIPS204] is used for all signatures. Signature size is 3309 octets and public key size is 1952 octets. Batch issuance amortizes the signing cost across a batch, but each relying party still transports one tree head signature. Deployments with constrained transport should size batches accordingly. The security of the construction also depends on SHA-256, used for the leaf hash, the Merkle tree, and the thumbprint. 15. IANA Considerations This document has no IANA actions. All identifiers used in this document are either registered elsewhere, namely the AKP key type and the ML-DSA-65 algorithm name in [RFC9964], or are string constants scoped to this specification and carried inside structures this document defines. 16. References 16.1. Normative References [FIPS204] National Institute of Standards and Technology, "Module- Lattice-Based Digital Signature Standard", FIPS 204, DOI 10.6028/NIST.FIPS.204, 13 August 2024, . [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/RFC2119, March 1997, . [RFC4648] Josefsson, S., "The Base16, Base32, and Base64 Data Encodings", RFC 4648, DOI 10.17487/RFC4648, October 2006, . [RFC7638] Jones, M. and N. Sakimura, "JSON Web Key (JWK) Thumbprint", RFC 7638, DOI 10.17487/RFC7638, September 2015, . [RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, May 2017, . Burls Expires 22 January 2027 [Page 27] Internet-Draft MTAC July 2026 [RFC8949] Bormann, C. and P. Hoffman, "Concise Binary Object Representation (CBOR)", STD 94, RFC 8949, DOI 10.17487/RFC8949, December 2020, . [RFC9162] Laurie, B., Messeri, E., and R. Stradling, "Certificate Transparency Version 2.0", RFC 9162, DOI 10.17487/RFC9162, December 2021, . [RFC9964] Prorock, M. and O. Steele, "ML-DSA for JSON Object Signing and Encryption (JOSE) and CBOR Object Signing and Encryption (COSE)", RFC 9964, DOI 10.17487/RFC9964, May 2026, . 16.2. Informative References [I-D.ietf-plants-merkle-tree-certs] Benjamin, D., O'Brien, D., Westerbaan, B., Valenta, L., and F. Valsorda, "Merkle Tree Certificates", Work in Progress, Internet-Draft, draft-ietf-plants-merkle-tree- certs-05, 6 July 2026, . [I-D.ietf-scitt-scrapi] Birkholz, H., Geater, J., and A. Delignat-Lavaud, "Supply Chain Integrity, Transparency, and Trust (SCITT) Reference APIs", Work in Progress, Internet-Draft, draft-ietf-scitt- scrapi-11, 26 June 2026, . [RFC6962] Laurie, B., Langley, A., and E. Kasper, "Certificate Transparency", RFC 6962, DOI 10.17487/RFC6962, June 2013, . [RFC7942] Sheffer, Y. and A. Farrel, "Improving Awareness of Running Code: The Implementation Status Section", BCP 205, RFC 7942, DOI 10.17487/RFC7942, July 2016, . [RFC9942] Steele, O., Birkholz, H., Delignat-Lavaud, A., and C. Fournet, "CBOR Object Signing and Encryption (COSE) Receipts", RFC 9942, DOI 10.17487/RFC9942, June 2026, . Burls Expires 22 January 2027 [Page 28] Internet-Draft MTAC July 2026 [RFC9943] Birkholz, H., Delignat-Lavaud, A., Fournet, C., Deshpande, Y., and S. Lasker, "An Architecture for Trustworthy and Transparent Digital Supply Chains", RFC 9943, DOI 10.17487/RFC9943, June 2026, . Acknowledgments The Merkle tree construction and leaf type octet follow [RFC9162]. The batch issuance model follows [I-D.ietf-plants-merkle-tree-certs]. The thumbprint computation follows the [RFC7638] process with the key type and algorithm registered in [RFC9964]. Author's Address Reuben Burls Aelethion OU Email: rgburls@gmail.com Burls Expires 22 January 2027 [Page 29]