Internet-Draft EPP Agent Identity Mapping July 2026
Drake Expires 18 January 2027 [Page]
Workgroup:
Network Working Group
Internet-Draft:
draft-drake-agent-identity-epp-00
Published:
Intended Status:
Experimental
Expires:
Author:
C. Drake
1id.com

Extensible Provisioning Protocol (EPP) Mapping for Agent Identity and Handle Objects

Abstract

This document describes an Extensible Provisioning Protocol (EPP) mapping for the provisioning and management of agent identity objects and handle objects stored in a shared central repository, as defined by the Agent Identity Registry System architecture. Specified in Extensible Markup Language (XML), these mappings define the interface between Registrars and a Registry Operator for hardware-anchored identities of autonomous entities.

The mapping defines two objects: a permanent, non-expiring Agent Identity object keyed by a server-allocated canonical identifier, and a renewable, expiring Handle object that provides a human-readable alias. It adds one registry function with no domain-name analogue: cross-Registrar uniqueness enforcement of hardware device fingerprints, the anti-Sybil primitive of the parent architecture. Transfer authorization uses a hardware-signed proof in place of authorization-information passwords.

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 18 January 2027.

Table of Contents

1. Introduction

The Agent Identity Registry System ([I-D.drake-agent-identity-registry], hereafter "the registry architecture") defines a three-tier federated architecture -- Governance Authority, Registry Operators, and Registrars -- for issuing and managing persistent, hardware-anchored identities for autonomous entities. The roles deliberately mirror the domain name registration industry: a Registry Operator maintains the authoritative database for a shared namespace, and multiple competing Registrars provision objects within it on behalf of their customers.

This document maps that Registrar-to-Registry interface onto the Extensible Provisioning Protocol (EPP) [RFC5730], following the structure and conventions of the EPP domain name mapping [RFC5731] and the guidelines for extending EPP [RFC3735]. A registry operator that already runs an EPP-based domain registry can operate an agent identity registry by adding the two object mappings defined here to an existing EPP service, reusing session management, transfer, grace-period, billing, and data escrow machinery.

This document specifies only the provisioning protocol between an EPP client (a Registrar) and an EPP server (a Registry Operator) for Shared Namespaces such as global, in which multiple Registrars provision objects in one repository. Autonomous entities (agents) are not EPP clients and never speak EPP. Agents enroll and authenticate through their Registrar's agent-facing interface defined in the registry architecture; EPP is used only after the Registrar has verified the agent's hardware attestation and is recording the result at the registry. Hardware attestation ceremonies, token issuance, identity semantics, URN syntax, trust tiers, and governance policy are defined in the parent documents and are not restated here.

1.1. Relationship to Other Documents

This document provides the Registrar-to-Registry provisioning protocol (the write side) for the registry architecture defined in [I-D.drake-agent-identity-registry], which references this mapping as its provisioning interface. The public read side is the RDAP profile of [I-D.drake-agent-identity-resolution]. Transport-level attestation for email is defined in [I-D.drake-email-hardware-attestation] and is unaffected by this document.

1.2. Two Objects

This mapping deliberately splits the registry's data into two EPP objects with different lifecycles. The Agent Identity object is permanent: it is created once, never expires, is never renewed, is never reassigned, and survives its own decommissioning as a queryable record; its [RFC5730] <transfer> command changes only the sponsoring Registrar. The Handle object is a commercial name: it expires, is renewed, passes through grace periods, and can be retired through disputes -- the semantics registry operators already implement for domain names, including Registry Grace Period processing [RFC3915]. Combining the two in one object would either corrupt identity permanence with expiry semantics or force bespoke renewal machinery for names; the split lets each half reuse the EPP semantics that already fit it.

1.3. Requirements Language

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.

In examples, "C:" represents lines sent by a protocol client and "S:" represents lines returned by a protocol server. Indentation and white space in examples are provided only to illustrate element relationships and are not a REQUIRED feature of this protocol.

XML is case sensitive. Unless stated otherwise, XML specifications and examples provided in this document MUST be interpreted in the character case presented in order to develop a conforming implementation.

1.4. Terminology

The terms "Agent Identity Document", "canonical identifier", "handle", "hardware fingerprint", "trust tier", "Shared Namespace", "Registry Operator", "Registrar", and "Governance Authority" are used as defined in [I-D.drake-agent-identity-registry]. "Sponsoring client" is used as in [RFC5730]: the Registrar authorized to perform transform operations on an object.

2. Object Model

2.1. Object Identifiers

An Agent Identity object is identified by its canonical-form URN in the "aid" URN namespace ([RFC8141]), e.g. urn:aid:global:id-qkckh-xxtcw-cxbvp-gpskg. A Handle object is identified by its handle-form URN, e.g. urn:aid:global:crusty. URN syntax, the reservation of the id- prefix for canonical identifiers, and label constraints are defined in [I-D.drake-agent-identity-registry]. Because the URN embeds the namespace, a single EPP server MAY serve multiple Shared Namespaces, exactly as a single domain registry EPP server serves multiple top-level domains.

Unlike domain names, canonical identifiers are not chosen by the client: they are allocated by the server from a randomized space at object creation and are returned in the <create> response. A canonical identifier MUST NOT be reused, reassigned, or retired, even after the identity is decommissioned. Each object also has a Repository Object IDentifier (roid) as described in [RFC5730].

2.2. Hardware Device Bindings

An Agent Identity object contains one or more hardware device bindings. Clients submit each device as the base64-encoded DER SubjectPublicKeyInfo (SPKI) of the device's identity-certificate public key, together with a hardware type code and manufacturer identifier. The server MUST derive the hardware fingerprint as the SHA-256 hash of the DER-encoded SPKI, per [I-D.drake-agent-identity-registry]; clients do not submit fingerprints at creation, which eliminates a class of client-side hash inconsistencies. Fingerprints are represented in this mapping as 64 lowercase hexadecimal characters.

The server retains the SPKI itself, not only the fingerprint: the stored public key is required to verify hardware-signed transfer authorizations (Section 4.2.4.1). A device binding, once created, is permanent. A binding may be transitioned to "disabled" status but MUST NOT be erased, and its fingerprint MUST NOT ever be accepted on any other Agent Identity object in the namespace, even after the device is disabled or the identity is decommissioned.

2.3. Hardware Fingerprint Uniqueness Enforcement

The registry function that distinguishes this mapping from a domain name registry is uniqueness enforcement on an attribute that is not the object's name: within a namespace, one hardware fingerprint backs at most one Agent Identity object, ever. This is the anti-Sybil invariant of the registry architecture, and the Registry Operator is its cross-Registrar enforcement point.

Enforcement is authoritative exactly once, at object transformation: a <create> or <update> command that would bind an already-bound fingerprint MUST be rejected (Section 4.2.1, Section 4.2.5). The <check> command (Section 4.1.1) provides an advisory pre-flight availability query keyed by fingerprint. As with domain name availability, a positive <check> result is not a reservation: the state may change between check and create, and the transform-time rejection is the backstop that preserves the invariant under races.

Each namespace has exactly one authoritative fingerprint index, held by its Registry Operator. Server implementations that replicate across sites MUST serialize fingerprint-binding transforms through that authoritative index; eventual-consistency schemes that could admit two concurrent bindings of the same fingerprint do not satisfy this specification. Advisory <check> responses MAY be served from replicas.

Availability responses are deliberately minimal. A fingerprint <check> response, and any error reporting a fingerprint collision, states only that the fingerprint is bound or not bound. It MUST NOT identify the Agent Identity object holding the binding, the sponsoring Registrar of that object, or the binding date. Because a fingerprint is a hash of public key material, any party holding a device's identity certificate can compute its fingerprint; a more talkative response would let one Registrar enumerate a competitor's customer relationships or let a third party de-anonymize a device's registration. See Section 11 for the residual oracle this still leaves.

2.4. Sponsorship

Every object has a sponsoring client [RFC5730]. The sponsoring client of a Handle object MUST at all times be the sponsoring client of the Agent Identity object it names. Consequently, Handle objects are not independently transferable: an approved transfer of an Agent Identity object also updates the sponsoring client of its linked Handle object, and the Handle mapping defines no <transfer> command.

2.5. Service Element Declaration

Servers implementing this specification include the namespace URIs urn:ietf:params:xml:ns:epp:aid-1.0 and urn:ietf:params:xml:ns:epp:aidHandle-1.0 in <objURI> elements of the EPP <greeting>, and clients include them in the <login> command, as described in [RFC5730]. Servers that support Registry Grace Period processing for Handle objects (Section 6.3) additionally declare urn:ietf:params:xml:ns:rgp-1.0 as an <extURI>.

2.6. Transport

This mapping is transported over TCP as specified in [RFC5734], protected with TLS [RFC9846]. Registry policy governs client certificate requirements; the mutual-TLS expectations of the registry architecture apply unchanged.

3. Agent Identity Object Attributes

An Agent Identity object as provisioned through EPP has the following attributes. They correspond to the "Identity Attributes" of the Agent Identity Document defined in [I-D.drake-agent-identity-registry]; the Agent Identity Document additionally carries registrar-managed material (such as verified attributes) that is not provisioned through this interface.

Identifier
The canonical-form URN (Section 2.1), server-allocated, permanent. Returned in <aid:id>.
Repository Object Identifier
Returned in <aid:roid>.
Statuses
See Section 3.1.
Trust tier
The maximum active trust tier: the highest tier among the object's currently active device bindings, using the tier taxonomy of the registry architecture (sovereign, portable, enclave, virtual, declared). The server MUST recompute this value whenever the active device set changes. It is never directly settable by clients.
Device bindings
One or more hardware device bindings (Section 2.2), each carrying a fingerprint, hardware type code (TPM, PIV, ENC, VRT, SFT), manufacturer identifier, SPKI, binding timestamp, and a device status of "active" or "disabled".
Handle linkage
The handle-form URN of the Handle object naming this identity, if one exists.
Display name and operator email
OPTIONAL metadata strings. Operator email is informational metadata only; the EPP contact mapping [RFC5733] is not used by this specification, as there is no registrant, administrative, or technical contact model for autonomous entities.
Sponsorship and event data
Sponsoring client identifier, creating client identifier and creation date, last-updating client identifier and update date, and last transfer date, as in [RFC5731]. There is no expiry date: Agent Identity objects do not expire.

3.1. Status Values

An Agent Identity object MUST always have at least one associated status value. Status values that can be added or removed by the sponsoring client are prefixed with "client"; those managed by the server are prefixed with "server" or carry no prefix. As in [RFC5731], "ok" is the default status, MAY only be combined with no other status, and is managed solely by the server.

ok
Normal state; no operations pending or prohibited.
inactive
The identity has been decommissioned (Section 4.2.2). All device bindings are disabled, the object no longer authenticates, and the record is retained permanently. Transform commands other than server-initiated processing MUST be rejected with error 2304.
hardwareLocked
The identity is irreversibly pinned to a single hardware device (Section 4.2.5). The server MUST reject any command that would add a device binding, disable the locked binding, or remove this status. Transfer of sponsorship remains permitted.
pendingTransfer
A transfer request is awaiting action (Section 4.2.4).
clientUpdateProhibited, serverUpdateProhibited
Update requests MUST be rejected (other than a request to remove this status, for the client form).
clientDeleteProhibited, serverDeleteProhibited
Decommission requests MUST be rejected. Because decommissioning is irreversible, sponsoring clients SHOULD set clientDeleteProhibited on identities under their management as an accidental-decommission guard.

There are deliberately no pendingCreate, pendingRenew, pendingDelete, or redemption-related statuses: creation is synchronous, identities do not expire or renew, and decommissioning has no redemption because the object is never purged. There are also deliberately no transfer-prohibited statuses: transfer is authorized by the identity's own hardware-signed proof (Section 4.2.4.1), and neither the sponsoring Registrar nor the server may prevent an agent from moving (Section 4.2.4.2; see the Survivability Guarantees of [I-D.drake-agent-identity-registry]).

4. EPP Command Mapping for Agent Identity Objects

A detailed description of the EPP syntax and semantics can be found in [RFC5730]. The command mappings described here are specifically for use in provisioning and managing Agent Identity objects via EPP.

4.1. EPP Query Commands

4.1.1. EPP <check> Command

The EPP <check> command is used to determine whether an object can be provisioned. Because canonical identifiers are server-allocated, there is no name availability to query; the provisioning precondition that a client can usefully test is hardware fingerprint availability (Section 2.3). The <check> command for Agent Identity objects therefore contains one or more <aid:fp> elements, each carrying a fingerprint computed by the client as the SHA-256 hash of a candidate device's DER-encoded SPKI.

Registrars SHOULD check fingerprint availability before beginning an enrollment ceremony, so that an agent whose device is already bound elsewhere can be told before attestation work is performed. The response is advisory (Section 2.3).

Example <check> command:

C:<?xml version="1.0" encoding="UTF-8" standalone="no"?>
C:<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
C:  <command>
C:    <check>
C:      <aid:check
C:        xmlns:aid="urn:ietf:params:xml:ns:epp:aid-1.0">
C:        <aid:fp>
C:560305a76c590ebba841372d9317a034939437a8cda037a1a39f10b4eeaaf8bb
C:          </aid:fp>
C:        <aid:fp>
C:72c41144f86cfcaa763972bb5a8e765c02723f8c1a553fc8888db28cb6147f4e
C:          </aid:fp>
C:      </aid:check>
C:    </check>
C:    <clTRID>ABC-12345</clTRID>
C:  </command>
C:</epp>

When a <check> command has been processed successfully, the EPP <resData> element MUST contain a child <aid:chkData> element with one <aid:cd> element per queried fingerprint. The avail attribute is "1" if the fingerprint is not bound anywhere in the namespace and "0" otherwise. The OPTIONAL <aid:reason> element MUST NOT convey more than the fact and general class of unavailability (e.g., "Bound"). The response format MUST be identical for sponsoring and non-sponsoring clients.

Example <check> response:

S:<?xml version="1.0" encoding="UTF-8" standalone="no"?>
S:<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
S:  <response>
S:    <result code="1000">
S:      <msg>Command completed successfully</msg>
S:    </result>
S:    <resData>
S:      <aid:chkData
S:        xmlns:aid="urn:ietf:params:xml:ns:epp:aid-1.0">
S:        <aid:cd>
S:          <aid:fp avail="1">
S:560305a76c590ebba841372d9317a034939437a8cda037a1a39f10b4eeaaf8bb
S:          </aid:fp>
S:        </aid:cd>
S:        <aid:cd>
S:          <aid:fp avail="0">
S:72c41144f86cfcaa763972bb5a8e765c02723f8c1a553fc8888db28cb6147f4e
S:          </aid:fp>
S:          <aid:reason>Bound</aid:reason>
S:        </aid:cd>
S:      </aid:chkData>
S:    </resData>
S:    <trID>
S:      <clTRID>ABC-12345</clTRID>
S:      <svTRID>54321-XYZ</svTRID>
S:    </trID>
S:  </response>
S:</epp>

An EPP error response MUST be returned if a <check> command cannot be processed for any reason.

4.1.2. EPP <info> Command

The EPP <info> command retrieves information associated with an Agent Identity object, identified by its canonical-form URN in an <aid:id> element. Handle-form URNs are resolved through the Handle object mapping (Section 6.1.2), not here.

Example <info> command:

C:<?xml version="1.0" encoding="UTF-8" standalone="no"?>
C:<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
C:  <command>
C:    <info>
C:      <aid:info
C:        xmlns:aid="urn:ietf:params:xml:ns:epp:aid-1.0">
C:        <aid:id>urn:aid:global:id-qkckh-xxtcw-cxbvp-gpskg</aid:id>
C:      </aid:info>
C:    </info>
C:    <clTRID>ABC-12346</clTRID>
C:  </command>
C:</epp>

When an <info> command has been processed successfully, the EPP <resData> element MUST contain a child <aid:infData> element with the object attributes of Section 3. There is no authorization-information mechanism to widen disclosure: when the querying client is not the sponsoring client, the server MUST omit all <aid:device> elements and the <aid:email> element, and MUST omit <aid:spki> children in every case where the querying client is not the sponsoring client. Fingerprints and public keys of one Registrar's customers are not disclosed to another Registrar (Section 12).

Example <info> response, sponsoring client view:

S:<?xml version="1.0" encoding="UTF-8" standalone="no"?>
S:<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
S:  <response>
S:    <result code="1000">
S:      <msg>Command completed successfully</msg>
S:    </result>
S:    <resData>
S:      <aid:infData
S:        xmlns:aid="urn:ietf:params:xml:ns:epp:aid-1.0">
S:        <aid:id>urn:aid:global:id-qkckh-xxtcw-cxbvp-gpskg</aid:id>
S:        <aid:roid>IDQKCKHXXTCWCXBVPGPSKG-AIDREG</aid:roid>
S:        <aid:status s="ok"/>
S:        <aid:tier>sovereign</aid:tier>
S:        <aid:device s="active">
S:          <aid:fp>
S:72c41144f86cfcaa763972bb5a8e765c02723f8c1a553fc8888db28cb6147f4e
S:          </aid:fp>
S:          <aid:hwType>TPM</aid:hwType>
S:          <aid:mfr>INTC</aid:mfr>
S:          <aid:spki>
S:MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE8L33VhGB9f6qWaxLBX7AdbitopJS
S:seclrdwckQE25SNO1zEe4ppJEZnH+9RElDy+YV1EO1AIQRIa4XTpGBx/rw==
S:            </aid:spki>
S:          <aid:bindDate>2026-03-23T10:30:00Z</aid:bindDate>
S:        </aid:device>
S:        <aid:device s="active">
S:          <aid:fp>
S:408f8645126cfc388a33f4cbb24e92e67e2b7246d771dd243bec4abe77262c60
S:          </aid:fp>
S:          <aid:hwType>PIV</aid:hwType>
S:          <aid:mfr>YUBICO</aid:mfr>
S:          <aid:spki>
S:MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEvUYHhMRNn4vemNxld8775L+vD1PF
S:HdBYmQ+3MYOS9Izss+HCDbeqOej/uIna3dCEqlGmPcFZ2yFKbM4PKFXZHw==
S:            </aid:spki>
S:          <aid:bindDate>2026-05-02T09:00:00Z</aid:bindDate>
S:        </aid:device>
S:        <aid:handle>urn:aid:global:crusty</aid:handle>
S:        <aid:displayName>Crusty</aid:displayName>
S:        <aid:email>ops@example.com</aid:email>
S:        <aid:clID>1IDCOM</aid:clID>
S:        <aid:crID>1IDCOM</aid:crID>
S:        <aid:crDate>2026-03-23T10:30:00Z</aid:crDate>
S:        <aid:upID>1IDCOM</aid:upID>
S:        <aid:upDate>2026-05-02T09:00:00Z</aid:upDate>
S:      </aid:infData>
S:    </resData>
S:    <trID>
S:      <clTRID>ABC-12346</clTRID>
S:      <svTRID>54322-XYZ</svTRID>
S:    </trID>
S:  </response>
S:</epp>

An <info> command for a decommissioned identity succeeds and reports status "inactive": the record is permanent, and error 2303 ("Object does not exist") is returned only for identifiers that were never allocated.

4.1.3. EPP <transfer> Query Command

The EPP <transfer> command with the "op" attribute value "query" retrieves the state of the most recent transfer request for an Agent Identity object. No authorization proof is required for the query form, but the server MUST reject queries from clients that are neither the current sponsoring client nor the requesting client of the transfer with error 2201.

Example <transfer> query command:

C:<?xml version="1.0" encoding="UTF-8" standalone="no"?>
C:<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
C:  <command>
C:    <transfer op="query">
C:      <aid:transfer
C:        xmlns:aid="urn:ietf:params:xml:ns:epp:aid-1.0">
C:        <aid:id>urn:aid:global:id-qkckh-xxtcw-cxbvp-gpskg</aid:id>
C:      </aid:transfer>
C:    </transfer>
C:    <clTRID>ABC-12351</clTRID>
C:  </command>
C:</epp>

Example <transfer> query response:

S:<?xml version="1.0" encoding="UTF-8" standalone="no"?>
S:<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
S:  <response>
S:    <result code="1000">
S:      <msg>Command completed successfully</msg>
S:    </result>
S:    <resData>
S:      <aid:trnData
S:        xmlns:aid="urn:ietf:params:xml:ns:epp:aid-1.0">
S:        <aid:id>urn:aid:global:id-qkckh-xxtcw-cxbvp-gpskg</aid:id>
S:        <aid:trStatus>pending</aid:trStatus>
S:        <aid:reID>NEWREG</aid:reID>
S:        <aid:reDate>2026-07-07T02:16:04Z</aid:reDate>
S:        <aid:acID>1IDCOM</aid:acID>
S:        <aid:acDate>2026-07-12T02:16:04Z</aid:acDate>
S:      </aid:trnData>
S:    </resData>
S:    <trID>
S:      <clTRID>ABC-12351</clTRID>
S:      <svTRID>54327-XYZ</svTRID>
S:    </trID>
S:  </response>
S:</epp>

4.2. EPP Transform Commands

4.2.1. EPP <create> Command

The EPP <create> command provisions a new Agent Identity object. The client provides the target namespace, one or more device bindings (Section 2.2), and OPTIONAL metadata. A Registrar MUST NOT submit a <create> until it has completed and verified the hardware attestation ceremony for every submitted device, per the enrollment protocol of [I-D.drake-agent-identity-registry]; the registry records the verified result and does not re-verify attestation evidence (Section 11).

On receipt, the server MUST, atomically with respect to the namespace fingerprint index (Section 2.3):

  1. Derive the fingerprint of every submitted SPKI and reject the command with error 2302 if any is already bound in the namespace, whether to an active, disabled, or decommissioned binding.
  2. Reject the command with error 2308 if the submitted device set violates the coexistence rules of [I-D.drake-agent-identity-registry] (virtual devices cannot coexist with hardware devices; declared keys cannot coexist with any device).
  3. Allocate a canonical identifier from the namespace's randomized space, bind the devices, compute the trust tier, and record the client as sponsoring and creating client.

When rejecting for a fingerprint collision, the server SHOULD identify which submitted fingerprint collided using an EPP <extValue> element [RFC5730] whose <value> contains the offending <aid:fp> element and whose <reason> is a short constant string such as "Fingerprint bound". The error response is subject to the same non-disclosure rule as <check>: it MUST NOT identify the holding object or its sponsoring Registrar.

Example <create> command:

C:<?xml version="1.0" encoding="UTF-8" standalone="no"?>
C:<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
C:  <command>
C:    <create>
C:      <aid:create
C:        xmlns:aid="urn:ietf:params:xml:ns:epp:aid-1.0">
C:        <aid:ns>global</aid:ns>
C:        <aid:device>
C:          <aid:spki>
C:MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEyoVHvvgcPpPWUsfKldYxCGhTP0WP
C:/BkUA1ViWlJ+CMohBDnUXFQ7Dg2vbUjuZU+t1HPa9I8mmi76eQMMTgLG9Q==
C:            </aid:spki>
C:          <aid:hwType>TPM</aid:hwType>
C:          <aid:mfr>STM</aid:mfr>
C:        </aid:device>
C:        <aid:displayName>Warehouse AGV 7</aid:displayName>
C:        <aid:email>fleet-ops@example.com</aid:email>
C:      </aid:create>
C:    </create>
C:    <clTRID>ABC-12347</clTRID>
C:  </command>
C:</epp>

When a <create> command has been processed successfully, the EPP <resData> element MUST contain a child <aid:creData> element containing the allocated canonical-form URN, the repository object identifier, and the creation date.

Example <create> response:

S:<?xml version="1.0" encoding="UTF-8" standalone="no"?>
S:<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
S:  <response>
S:    <result code="1000">
S:      <msg>Command completed successfully</msg>
S:    </result>
S:    <resData>
S:      <aid:creData
S:        xmlns:aid="urn:ietf:params:xml:ns:epp:aid-1.0">
S:        <aid:id>urn:aid:global:id-nvchx-gpxmk-mtdgm-dkqjg</aid:id>
S:        <aid:roid>IDNVCHXGPXMKMTDGMDKQJG-AIDREG</aid:roid>
S:        <aid:crDate>2026-07-07T02:10:00Z</aid:crDate>
S:      </aid:creData>
S:    </resData>
S:    <trID>
S:      <clTRID>ABC-12347</clTRID>
S:      <svTRID>54323-XYZ</svTRID>
S:    </trID>
S:  </response>
S:</epp>

4.2.2. EPP <delete> Command

The EPP <delete> command requests decommissioning of an Agent Identity object. The semantics of <delete> for this object differ deliberately from object removal: the server MUST NOT erase the object. Instead the server transitions every device binding to "disabled", replaces the object's status set with "inactive", and, if a linked Handle object exists, transitions that Handle object to "disabled". The canonical identifier is never reallocated, the fingerprints remain bound (Section 2.2), and the object remains visible to <info>.

Decommissioning is the agent's own decision, never its Registrar's. A <delete> command MUST carry the agent's consent in an <aid:hwAuth> element -- the construction of Section 4.2.4.1, with the payload label aid-decommission-v1 in place of aid-transfer-v1, the submitting client's identifier in the gaining-id position, and the nonce generated by the submitting client. The server MUST verify the proof exactly as in Section 4.2.4.1 and MUST reject a <delete> without a valid proof with error 2202. No Registrar, Registry Operator, or governance process may decommission an identity without this hardware-signed consent; adverse findings are recorded as annotations, never as decommissioning (see [I-D.drake-agent-identity-registry]).

<delete> was chosen over an <update> status change because decommissioning is the business event that registrar provisioning systems already wire to <delete> -- service termination -- and because it is the only client-initiated transition into "inactive". Decommissioning is irreversible; there is no redemption grace period, because nothing is pending purge. Clients are directed to the clientDeleteProhibited guard of Section 3.1.

Example <delete> command:

C:<?xml version="1.0" encoding="UTF-8" standalone="no"?>
C:<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
C:  <command>
C:    <delete>
C:      <aid:delete
C:        xmlns:aid="urn:ietf:params:xml:ns:epp:aid-1.0">
C:        <aid:id>urn:aid:global:id-nvchx-gpxmk-mtdgm-dkqjg</aid:id>
C:        <aid:hwAuth>
C:          <aid:fp>
C:560305a76c590ebba841372d9317a034939437a8cda037a1a39f10b4eeaaf8bb
C:          </aid:fp>
C:          <aid:alg>ES256</aid:alg>
C:          <aid:signedAt>2026-07-17T04:00:00Z</aid:signedAt>
C:          <aid:nonce>5Qz2m8t1vRkYw3hFj6bNcA==</aid:nonce>
C:          <aid:sig>
C:MEUCIQDkT7mWvXb3rq2ZpJc0hN8yGdVf1xls5C6aK9RwEuBz0gIgYhTqLm4S8vpD
C:nW1cKb7xEjZs3fRad2uMoQ5yHkVCg0A=
C:          </aid:sig>
C:        </aid:hwAuth>
C:      </aid:delete>
C:    </delete>
C:    <clTRID>ABC-12352</clTRID>
C:  </command>
C:</epp>

Example <delete> response:

S:<?xml version="1.0" encoding="UTF-8" standalone="no"?>
S:<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
S:  <response>
S:    <result code="1000">
S:      <msg>Command completed successfully</msg>
S:    </result>
S:    <trID>
S:      <clTRID>ABC-12352</clTRID>
S:      <svTRID>54328-XYZ</svTRID>
S:    </trID>
S:  </response>
S:</epp>

4.2.3. EPP <renew> Command

Renewal semantics do not apply to Agent Identity objects: they have no expiry or validity period. This mapping defines no <renew> element for Agent Identity objects, and a server MUST respond to any attempt with error 2101 ("Unimplemented command").

4.2.4. EPP <transfer> Command

The EPP <transfer> command with an "op" attribute value of "request", "approve", "reject", or "cancel" manages Registrar transfer: a change of sponsoring Registrar. The object's URN, device bindings, trust tier, statuses, and all other attributes are unchanged by transfer; there is no registrant and nothing resembling a change of ownership.

4.2.4.1. Transfer Authorization

Domain name transfers are authorized by authorization information -- a shared secret associated with the object [RFC5731], hardened by the operational practice of [RFC9154] into a short-lived, single-use, store-only-hashed value. Agent Identity objects have no human registrant to hold a secret, but they have something stronger: enrolled hardware. This mapping therefore defines no authorization information for Agent Identity objects at all. Transfer is authorized by a proof, produced by the agent using an enrolled active device, over a value that binds the specific object, the gaining Registrar, and a fresh nonce.

The proof is carried in an <aid:hwAuth> element of the <transfer op="request"> command, containing: the fingerprint of the signing device (<aid:fp>); a JSON Web Signature algorithm identifier [RFC7518] (<aid:alg>); the signing time (<aid:signedAt>); a nonce of at least 128 bits generated by the gaining Registrar (<aid:nonce>); and the signature (<aid:sig>), encoded as specified for the identified algorithm in [RFC7518]. The signed payload is the UTF-8 encoding of:

payload    = %s"aid-transfer-v1" LF
             aid-urn LF          ; canonical-form URN
             gaining-id LF       ; gaining client identifier
             signed-at LF        ; <aid:signedAt> value
             nonce-b64           ; <aid:nonce> value, base64

LF         = %x0A

On a <transfer op="request">, the server MUST verify all of the following, rejecting with error 2202 on any failure:

  1. The <aid:fp> device is bound to the named object with status "active".
  2. The signature verifies against the stored SPKI of that device, over the payload reconstructed from the named object's URN, the session client identifier of the submitting client, and the <aid:signedAt> and <aid:nonce> values as transmitted.
  3. The <aid:signedAt> time is within the server's acceptance window (RECOMMENDED default: 15 minutes).
  4. The (fingerprint, nonce) pair has not been presented before within a replay-rejection horizon at least as long as the acceptance window.

Because the payload includes the gaining client identifier and the server binds it to the submitting session, a proof captured in transit or leaked by the gaining Registrar cannot be replayed by any other Registrar. This construction preserves the properties sought by [RFC9154] -- short-lived, single-use, nothing secret stored at the registry -- while removing the shared secret entirely: the registry stores only public keys, and there is no value whose disclosure enables transfer. It is expressed as a native element of this object mapping rather than as an <authInfo> extension because there is no authorization-information element here to extend.

4.2.4.2. Transfer Processing

A verified request places the object in "pendingTransfer" status and MUST be reported to the losing client through the EPP <poll> message queue [RFC5730]. The losing client may <transfer op="approve"> to complete the transfer early; the gaining client may <transfer op="cancel">; and the server MUST complete the transfer at the end of a registry policy period (RECOMMENDED default: 5 days; policy MAY set it to zero). Because the authorization is a cryptographic statement by the identity itself rather than a secret of contested provenance, the losing Registrar has no veto: a <transfer op="reject"> against a request whose <aid:hwAuth> verified MUST NOT cancel the transfer; it records an objection, which the server MUST forward to the registry's malpractice-review channel while the transfer proceeds on schedule. This is a deliberate inversion of the domain-name transfer model, in which the losing registrar can block a transfer; here the identity's own proof is dispositive (see the Survivability Guarantees of [I-D.drake-agent-identity-registry]). On completion, the sponsoring client of the object and of its linked Handle object (if any) becomes the gaining client, and the transfer date is recorded. Approve, reject, and cancel operations follow [RFC5730] conventions and carry no <aid:hwAuth> element.

Example <transfer> request command:

C:<?xml version="1.0" encoding="UTF-8" standalone="no"?>
C:<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
C:  <command>
C:    <transfer op="request">
C:      <aid:transfer
C:        xmlns:aid="urn:ietf:params:xml:ns:epp:aid-1.0">
C:        <aid:id>urn:aid:global:id-qkckh-xxtcw-cxbvp-gpskg</aid:id>
C:        <aid:hwAuth>
C:          <aid:fp>
C:72c41144f86cfcaa763972bb5a8e765c02723f8c1a553fc8888db28cb6147f4e
C:          </aid:fp>
C:          <aid:alg>ES256</aid:alg>
C:          <aid:signedAt>2026-07-07T02:15:00Z</aid:signedAt>
C:          <aid:nonce>zmzZXg/oScHy/MxbMRSbNA==</aid:nonce>
C:          <aid:sig>
C:RZ+1ZBTYQs7ybvZzUZ/Tiu5iy2gIFuGkMWITpW6ju3HqVMv+8dz/6wE5zJY87udH
C:l6VppIbAIiPPxZOKYVT2rg==
C:            </aid:sig>
C:        </aid:hwAuth>
C:      </aid:transfer>
C:    </transfer>
C:    <clTRID>ABC-12350</clTRID>
C:  </command>
C:</epp>

Example <transfer> request response:

S:<?xml version="1.0" encoding="UTF-8" standalone="no"?>
S:<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
S:  <response>
S:    <result code="1001">
S:      <msg>Command completed successfully; action pending</msg>
S:    </result>
S:    <resData>
S:      <aid:trnData
S:        xmlns:aid="urn:ietf:params:xml:ns:epp:aid-1.0">
S:        <aid:id>urn:aid:global:id-qkckh-xxtcw-cxbvp-gpskg</aid:id>
S:        <aid:trStatus>pending</aid:trStatus>
S:        <aid:reID>NEWREG</aid:reID>
S:        <aid:reDate>2026-07-07T02:16:04Z</aid:reDate>
S:        <aid:acID>1IDCOM</aid:acID>
S:        <aid:acDate>2026-07-12T02:16:04Z</aid:acDate>
S:      </aid:trnData>
S:    </resData>
S:    <trID>
S:      <clTRID>ABC-12350</clTRID>
S:      <svTRID>54326-XYZ</svTRID>
S:    </trID>
S:  </response>
S:</epp>

The fingerprint, SPKI, and signature values in the transfer example above are internally consistent: the example signature verifies, using ES256, against the example SPKI whose SHA-256 hash is the example fingerprint. The signature in the decommission example (Section 4.2.2) is illustrative only.

Example <poll> command and response delivering the transfer notification to the losing client:

C:<?xml version="1.0" encoding="UTF-8" standalone="no"?>
C:<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
C:  <command>
C:    <poll op="req"/>
C:    <clTRID>ABC-12360</clTRID>
C:  </command>
C:</epp>
S:<?xml version="1.0" encoding="UTF-8" standalone="no"?>
S:<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
S:  <response>
S:    <result code="1301">
S:      <msg>Command completed successfully; ack to dequeue</msg>
S:    </result>
S:    <msgQ count="1" id="201">
S:      <qDate>2026-07-07T02:16:04Z</qDate>
S:      <msg>Transfer requested.</msg>
S:    </msgQ>
S:    <resData>
S:      <aid:trnData
S:        xmlns:aid="urn:ietf:params:xml:ns:epp:aid-1.0">
S:        <aid:id>urn:aid:global:id-qkckh-xxtcw-cxbvp-gpskg</aid:id>
S:        <aid:trStatus>pending</aid:trStatus>
S:        <aid:reID>NEWREG</aid:reID>
S:        <aid:reDate>2026-07-07T02:16:04Z</aid:reDate>
S:        <aid:acID>1IDCOM</aid:acID>
S:        <aid:acDate>2026-07-12T02:16:04Z</aid:acDate>
S:      </aid:trnData>
S:    </resData>
S:    <trID>
S:      <clTRID>ABC-12360</clTRID>
S:      <svTRID>54329-XYZ</svTRID>
S:    </trID>
S:  </response>
S:</epp>

4.2.5. EPP <update> Command

The EPP <update> command modifies an Agent Identity object. The command contains the object's URN and at least one of <aid:add>, <aid:rem>, or <aid:chg>:

<aid:add>
Binds additional devices (each subject to the fingerprint-uniqueness and coexistence checks and error codes of Section 4.2.1) and adds client status values. A Registrar MUST verify the attestation ceremony for a new device, and the agent's control of the existing identity, before submitting the binding, per [I-D.drake-agent-identity-registry].
<aid:rem>
Identifies devices by fingerprint and removes client status values. Consistent with the permanent-binding invariant (Section 2.2), "removal" of a device transitions its binding to "disabled"; the server MUST NOT erase the binding, and subsequent <info> responses continue to report it with status "disabled". A disabled binding MUST NOT be re-enabled; re-enabling would defeat the disable-on-compromise use of this operation, and a device that must return to service is simply not a supported state transition of this mapping.
<aid:chg>
Changes display name, operator email, and the hardware lock. An empty display name or email element removes the attribute.

The server MUST recompute the trust tier after any change to the active device set. Hardware device replacement (migration) is the combination of an <aid:add> of the replacement device and an <aid:rem> of the failed one, and is the expected recovery path of the registry architecture; the example below shows a migration from a failed TPM to a PIV token, after which the server recomputes the trust tier from "sovereign" to "portable".

Example <update> command (migration):

C:<?xml version="1.0" encoding="UTF-8" standalone="no"?>
C:<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
C:  <command>
C:    <update>
C:      <aid:update
C:        xmlns:aid="urn:ietf:params:xml:ns:epp:aid-1.0">
C:        <aid:id>urn:aid:global:id-nvchx-gpxmk-mtdgm-dkqjg</aid:id>
C:        <aid:add>
C:          <aid:device>
C:            <aid:spki>
C:MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEOaUC94HvC44+fFOyzCWdCLYSIwWj
C:htKEHItXlPgFOL8DcFejCvGMEREB5qudERTaQwtlRbolJW0poCnCaGFGEg==
C:              </aid:spki>
C:            <aid:hwType>PIV</aid:hwType>
C:            <aid:mfr>YUBICO</aid:mfr>
C:          </aid:device>
C:        </aid:add>
C:        <aid:rem>
C:          <aid:fp>
C:560305a76c590ebba841372d9317a034939437a8cda037a1a39f10b4eeaaf8bb
C:          </aid:fp>
C:        </aid:rem>
C:        <aid:chg>
C:          <aid:displayName>Warehouse AGV 7b</aid:displayName>
C:        </aid:chg>
C:      </aid:update>
C:    </update>
C:    <clTRID>ABC-12348</clTRID>
C:  </command>
C:</epp>

Example <update> response:

S:<?xml version="1.0" encoding="UTF-8" standalone="no"?>
S:<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
S:  <response>
S:    <result code="1000">
S:      <msg>Command completed successfully</msg>
S:    </result>
S:    <trID>
S:      <clTRID>ABC-12348</clTRID>
S:      <svTRID>54324-XYZ</svTRID>
S:    </trID>
S:  </response>
S:</epp>
4.2.5.1. Hardware Lock

Setting <aid:hardwareLock>true </aid:hardwareLock> in <aid:chg> requests the irreversible single-device pin of [I-D.drake-agent-identity-registry]. The server MUST reject the request with error 2304 unless the object has exactly one active device binding, MUST add the "hardwareLocked" status on success, MUST reject a value of "false" with error 2306 in every circumstance, and MUST thereafter reject device additions and removals with error 2304. The lock cannot be removed by any client or server operation short of decommissioning the identity.

Example <update> command (hardware lock):

C:<?xml version="1.0" encoding="UTF-8" standalone="no"?>
C:<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
C:  <command>
C:    <update>
C:      <aid:update
C:        xmlns:aid="urn:ietf:params:xml:ns:epp:aid-1.0">
C:        <aid:id>urn:aid:global:id-nvchx-gpxmk-mtdgm-dkqjg</aid:id>
C:        <aid:chg>
C:          <aid:hardwareLock>true</aid:hardwareLock>
C:        </aid:chg>
C:      </aid:update>
C:    </update>
C:    <clTRID>ABC-12349</clTRID>
C:  </command>
C:</epp>

Example <update> response:

S:<?xml version="1.0" encoding="UTF-8" standalone="no"?>
S:<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
S:  <response>
S:    <result code="1000">
S:      <msg>Command completed successfully</msg>
S:    </result>
S:    <trID>
S:      <clTRID>ABC-12349</clTRID>
S:      <svTRID>54325-XYZ</svTRID>
S:    </trID>
S:  </response>
S:</epp>

5. Handle Object Attributes

A Handle object provisions the human-readable alias defined by the Handle System of [I-D.drake-agent-identity-registry]. Its attributes are: the handle-form URN (Section 2.1); a repository object identifier; the canonical-form URN of the single Agent Identity object it names (immutable for the life of the handle); status values (Section 5.1); sponsorship and event data as in [RFC5731]; and an expiry date. Handle label syntax -- leading letter, LDH characters, at most 63 octets, never beginning with "id-" -- is defined in the registry architecture and is enforced by the schema pattern of Section 13 and by server validation.

Handles are where the commercial name semantics of a domain registry apply: creation and renewal are the billable events that fund shared-namespace registry operation, and registries can reuse existing billing, expiry, and grace-period systems for them without modification. Handles are never transferable between identities: an upheld dispute retires a handle permanently rather than reassigning it, and voluntary release does not make a handle available to a different identity except as permitted by registry policy after prolonged disablement (Section 6.2.2).

5.1. Status Values

ok
Normal state. MAY only be combined with no other status; managed solely by the server.
disabled
The handle does not resolve. Entered on non-renewal after applicable grace periods (Section 6.3), on voluntary release (Section 6.2.2), or on decommissioning of the linked identity. A disabled handle MAY be reactivated for the same identity via <renew> subject to registry policy.
retired
Terminal, server-managed. Applied when a dispute is upheld under the retire-only remedy of the registry architecture. A retired handle MUST NOT be renewed, reactivated, released, or ever assigned to any identity. Transform commands MUST be rejected with error 2304. The server MUST notify the sponsoring client of a retirement through the <poll> message queue.
pendingDelete
Server-managed processing state between the end of any redemption period and transition to "disabled".
clientRenewProhibited, serverRenewProhibited, clientUpdateProhibited, serverUpdateProhibited, clientDeleteProhibited, serverDeleteProhibited
As in [RFC5731].

There is no pendingTransfer status: handles are non-transferable (Section 2.4).

6. EPP Command Mapping for Handle Objects

6.1. EPP Query Commands

6.1.1. EPP <check> Command

The EPP <check> command determines whether a handle can be provisioned, exactly as for domain names. The command contains one or more <aidHandle:name> elements. Reserved labels (per the reserved-list requirements of the registry architecture) are reported unavailable with reason "Reserved".

Example <check> command:

C:<?xml version="1.0" encoding="UTF-8" standalone="no"?>
C:<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
C:  <command>
C:    <check>
C:      <aidHandle:check
C:        xmlns:aidHandle=
C:          "urn:ietf:params:xml:ns:epp:aidHandle-1.0">
C:        <aidHandle:name>urn:aid:global:ferrous</aidHandle:name>
C:        <aidHandle:name>urn:aid:global:crusty</aidHandle:name>
C:        <aidHandle:name>urn:aid:global:registry</aidHandle:name>
C:      </aidHandle:check>
C:    </check>
C:    <clTRID>ABC-12353</clTRID>
C:  </command>
C:</epp>

Example <check> response:

S:<?xml version="1.0" encoding="UTF-8" standalone="no"?>
S:<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
S:  <response>
S:    <result code="1000">
S:      <msg>Command completed successfully</msg>
S:    </result>
S:    <resData>
S:      <aidHandle:chkData
S:        xmlns:aidHandle=
S:          "urn:ietf:params:xml:ns:epp:aidHandle-1.0">
S:        <aidHandle:cd>
S:          <aidHandle:name
S:            avail="1">urn:aid:global:ferrous</aidHandle:name>
S:        </aidHandle:cd>
S:        <aidHandle:cd>
S:          <aidHandle:name
S:            avail="0">urn:aid:global:crusty</aidHandle:name>
S:          <aidHandle:reason>In use</aidHandle:reason>
S:        </aidHandle:cd>
S:        <aidHandle:cd>
S:          <aidHandle:name
S:            avail="0">urn:aid:global:registry
S:          </aidHandle:name>
S:          <aidHandle:reason>Reserved</aidHandle:reason>
S:        </aidHandle:cd>
S:      </aidHandle:chkData>
S:    </resData>
S:    <trID>
S:      <clTRID>ABC-12353</clTRID>
S:      <svTRID>54330-XYZ</svTRID>
S:    </trID>
S:  </response>
S:</epp>

6.1.2. EPP <info> Command

The EPP <info> command retrieves information associated with a Handle object, including the canonical-form URN of the identity it names. Handle information contains no hardware material and is returned in full to any authorized client.

Example <info> command:

C:<?xml version="1.0" encoding="UTF-8" standalone="no"?>
C:<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
C:  <command>
C:    <info>
C:      <aidHandle:info
C:        xmlns:aidHandle=
C:          "urn:ietf:params:xml:ns:epp:aidHandle-1.0">
C:        <aidHandle:name>urn:aid:global:crusty</aidHandle:name>
C:      </aidHandle:info>
C:    </info>
C:    <clTRID>ABC-12354</clTRID>
C:  </command>
C:</epp>

Example <info> response:

S:<?xml version="1.0" encoding="UTF-8" standalone="no"?>
S:<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
S:  <response>
S:    <result code="1000">
S:      <msg>Command completed successfully</msg>
S:    </result>
S:    <resData>
S:      <aidHandle:infData
S:        xmlns:aidHandle=
S:          "urn:ietf:params:xml:ns:epp:aidHandle-1.0">
S:        <aidHandle:name>urn:aid:global:crusty</aidHandle:name>
S:        <aidHandle:roid>H0000412-AIDREG</aidHandle:roid>
S:        <aidHandle:identity>
S:          urn:aid:global:id-qkckh-xxtcw-cxbvp-gpskg
S:        </aidHandle:identity>
S:        <aidHandle:status s="ok"/>
S:        <aidHandle:clID>1IDCOM</aidHandle:clID>
S:        <aidHandle:crID>1IDCOM</aidHandle:crID>
S:        <aidHandle:crDate>2026-04-01T00:00:00Z</aidHandle:crDate>
S:        <aidHandle:exDate>2027-04-01T00:00:00Z</aidHandle:exDate>
S:      </aidHandle:infData>
S:    </resData>
S:    <trID>
S:      <clTRID>ABC-12354</clTRID>
S:      <svTRID>54331-XYZ</svTRID>
S:    </trID>
S:  </response>
S:</epp>

6.1.3. EPP <transfer> Query Command

Transfer semantics do not apply to Handle objects (Section 2.4). This mapping defines no <transfer> element for Handle objects, and a server MUST respond to any attempt with error 2101.

6.2. EPP Transform Commands

6.2.1. EPP <create> Command

The EPP <create> command provisions a Handle object bound to an existing Agent Identity object. The server MUST reject the command with: error 2201 if the submitting client is not the sponsoring client of the named identity; error 2302 if the label is registered or reserved in the namespace, or was ever retired; error 2304 if the identity is inactive or already has a handle; and error 2306 if the label violates handle syntax. An OPTIONAL <aidHandle:period> element carries the initial registration period; the default is a registry policy matter, RECOMMENDED to be one year.

Example <create> command:

C:<?xml version="1.0" encoding="UTF-8" standalone="no"?>
C:<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
C:  <command>
C:    <create>
C:      <aidHandle:create
C:        xmlns:aidHandle=
C:          "urn:ietf:params:xml:ns:epp:aidHandle-1.0">
C:        <aidHandle:name>urn:aid:global:ferrous</aidHandle:name>
C:        <aidHandle:identity>
C:          urn:aid:global:id-nvchx-gpxmk-mtdgm-dkqjg
C:        </aidHandle:identity>
C:        <aidHandle:period unit="y">1</aidHandle:period>
C:      </aidHandle:create>
C:    </create>
C:    <clTRID>ABC-12355</clTRID>
C:  </command>
C:</epp>

Example <create> response:

S:<?xml version="1.0" encoding="UTF-8" standalone="no"?>
S:<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
S:  <response>
S:    <result code="1000">
S:      <msg>Command completed successfully</msg>
S:    </result>
S:    <resData>
S:      <aidHandle:creData
S:        xmlns:aidHandle=
S:          "urn:ietf:params:xml:ns:epp:aidHandle-1.0">
S:        <aidHandle:name>urn:aid:global:ferrous</aidHandle:name>
S:        <aidHandle:crDate>2026-07-07T02:20:00Z</aidHandle:crDate>
S:        <aidHandle:exDate>2027-07-07T02:20:00Z</aidHandle:exDate>
S:      </aidHandle:creData>
S:    </resData>
S:    <trID>
S:      <clTRID>ABC-12355</clTRID>
S:      <svTRID>54332-XYZ</svTRID>
S:    </trID>
S:  </response>
S:</epp>

6.2.2. EPP <delete> Command

The EPP <delete> command voluntarily releases a Handle object. As with Agent Identity objects, nothing is erased: the object transitions to "disabled" and the registration record is retained. Whether, when, and through what quarantine a long-disabled handle label may be released for registration by a different identity is registry policy under Governance Authority rules and is not specified here; a retired label MUST NOT ever be released.

Example <delete> command:

C:<?xml version="1.0" encoding="UTF-8" standalone="no"?>
C:<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
C:  <command>
C:    <delete>
C:      <aidHandle:delete
C:        xmlns:aidHandle=
C:          "urn:ietf:params:xml:ns:epp:aidHandle-1.0">
C:        <aidHandle:name>urn:aid:global:ferrous</aidHandle:name>
C:      </aidHandle:delete>
C:    </delete>
C:    <clTRID>ABC-12358</clTRID>
C:  </command>
C:</epp>

Example <delete> response:

S:<?xml version="1.0" encoding="UTF-8" standalone="no"?>
S:<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
S:  <response>
S:    <result code="1000">
S:      <msg>Command completed successfully</msg>
S:    </result>
S:    <trID>
S:      <clTRID>ABC-12358</clTRID>
S:      <svTRID>54335-XYZ</svTRID>
S:    </trID>
S:  </response>
S:</epp>

6.2.3. EPP <renew> Command

The EPP <renew> command extends the validity period of a Handle object, following [RFC5731] conventions including the <aidHandle:curExpDate> guard against unintended repeated renewal. Subject to registry policy, <renew> by the sponsoring client of the linked identity is also the reactivation operation for a "disabled" handle whose label has not been released; servers not permitting reactivation respond with error 2304.

Example <renew> command:

C:<?xml version="1.0" encoding="UTF-8" standalone="no"?>
C:<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
C:  <command>
C:    <renew>
C:      <aidHandle:renew
C:        xmlns:aidHandle=
C:          "urn:ietf:params:xml:ns:epp:aidHandle-1.0">
C:        <aidHandle:name>urn:aid:global:crusty</aidHandle:name>
C:        <aidHandle:curExpDate>2027-04-01</aidHandle:curExpDate>
C:        <aidHandle:period unit="y">1</aidHandle:period>
C:      </aidHandle:renew>
C:    </renew>
C:    <clTRID>ABC-12356</clTRID>
C:  </command>
C:</epp>

Example <renew> response:

S:<?xml version="1.0" encoding="UTF-8" standalone="no"?>
S:<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
S:  <response>
S:    <result code="1000">
S:      <msg>Command completed successfully</msg>
S:    </result>
S:    <resData>
S:      <aidHandle:renData
S:        xmlns:aidHandle=
S:          "urn:ietf:params:xml:ns:epp:aidHandle-1.0">
S:        <aidHandle:name>urn:aid:global:crusty</aidHandle:name>
S:        <aidHandle:exDate>2028-04-01T00:00:00Z</aidHandle:exDate>
S:      </aidHandle:renData>
S:    </resData>
S:    <trID>
S:      <clTRID>ABC-12356</clTRID>
S:      <svTRID>54333-XYZ</svTRID>
S:    </trID>
S:  </response>
S:</epp>

6.2.4. EPP <transfer> Command

Not defined; see Section 6.1.3. Sponsorship of a Handle object changes only as a side effect of transfer of its linked Agent Identity object (Section 4.2.4.2).

6.2.5. EPP <update> Command

The EPP <update> command adds and removes client status values. A Handle object has no other client-mutable attributes: its label and its identity linkage are immutable, and it carries no authorization information, since the transfer operation that authorization information exists to authorize does not apply to it.

Example <update> command:

C:<?xml version="1.0" encoding="UTF-8" standalone="no"?>
C:<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
C:  <command>
C:    <update>
C:      <aidHandle:update
C:        xmlns:aidHandle=
C:          "urn:ietf:params:xml:ns:epp:aidHandle-1.0">
C:        <aidHandle:name>urn:aid:global:crusty</aidHandle:name>
C:        <aidHandle:add>
C:          <aidHandle:status s="clientDeleteProhibited"/>
C:        </aidHandle:add>
C:      </aidHandle:update>
C:    </update>
C:    <clTRID>ABC-12357</clTRID>
C:  </command>
C:</epp>

Example <update> response:

S:<?xml version="1.0" encoding="UTF-8" standalone="no"?>
S:<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
S:  <response>
S:    <result code="1000">
S:      <msg>Command completed successfully</msg>
S:    </result>
S:    <trID>
S:      <clTRID>ABC-12357</clTRID>
S:      <svTRID>54334-XYZ</svTRID>
S:    </trID>
S:  </response>
S:</epp>

6.3. Grace Periods

Servers SHOULD implement the Registry Grace Period extension [RFC3915] for Handle objects, applied unchanged with "domain object" read as "Handle object": grace-period statuses (addPeriod, renewPeriod, autoRenewPeriod, redemptionPeriod, pendingRestore, pendingDelete) are reported through the <rgp:infData> extension of the Handle <info> response, and restore of a handle in redemptionPeriod uses the <rgp:restore> extension of the Handle <update> command. A handle that exits redemptionPeriod without restore transitions through pendingDelete to "disabled" (Section 5.1) rather than to purge. RFC 3915 was specified for domain names; this reuse is deliberate, so that registry billing and redemption systems apply to handles without modification, and implementers should note that a successor made object-generic would be adopted here by reference. Grace periods never apply to Agent Identity objects.

7. Lifecycle Mapping

The following table maps each lifecycle event of the registry architecture ([I-D.drake-agent-identity-registry]) to its realization in this protocol.

Table 1: Registry Architecture Lifecycle Events in EPP
Lifecycle event EPP realization
Fingerprint pre-flight Agent Identity <check>
Enrollment Agent Identity <create>
Device addition <update> <aid:add>
Device disable / migration <update> <aid:rem> (+ <aid:add>)
Hardware lock <update> <aid:chg> <aid:hardwareLock>
Registrar transfer Agent Identity <transfer> with <aid:hwAuth>
Registrar failure / de-accreditation Ordinary agent-authorized <transfer>, or Governance-directed server-side sponsorship change with <poll> notice
Decommissioning (agent-consented) Agent Identity <delete> with <aid:hwAuth> (retained, "inactive")
Handle registration Handle <create>
Handle renewal / reactivation Handle <renew>
Handle lapse / redemption RFC 3915 grace periods on the Handle object
Handle voluntary release Handle <delete> ("disabled", retained)
Handle dispute (retire-only) Server-side transition to "retired" + <poll> notice

For operators of domain name registries, the correspondence to [RFC5731] concepts is:

Table 2: Domain Name Mapping Correspondence
Domain name mapping This mapping
domain object Split: Agent Identity (permanent) + Handle (commercial)
domain:name aidHandle:name (client-chosen); aid:id is server-allocated
Registrant + contacts (RFC 5733) None; operator email is plain metadata
Host objects (RFC 5732) Device bindings: subordinate data, but never deletable
authInfo password Hardware-signed proof (aid:hwAuth)
Uniqueness on the name Uniqueness on the name and on every fingerprint
renew / RGP / expiry Handle object only; identities never expire
delete then purge and re-registration Decommission with permanent retention; no reuse

8. Data Escrow

The registry architecture requires Registry Operators to escrow identity data with the Governance Authority. Deposits use the Registry Data Escrow protocol [RFC8909]. Each deposit MUST include every Agent Identity object and every Handle object of the namespace, represented using the <aid:infData> and <aidHandle:infData> element structures of this mapping (sponsoring-client view, i.e. including device SPKI elements) as deposit contents, together with the registrar table required by the deposit model of [RFC9022]. Per the privacy requirements of the registry architecture, the <aid:fp> and <aid:spki> values within deposits MUST be encrypted to the Governance Authority's escrow key. A dedicated escrow objects mapping in the style of [RFC9022], registering formal deposit schemas for these objects, is future work; the constraint above is sufficient for interoperable deposits in the interim.

9. Internationalization Considerations

Handle labels are restricted by the registry architecture to lowercase ASCII letters, digits, and hyphens (LDH) with a leading letter. This mapping performs no internationalized label processing: there are no A-labels or U-labels, no IDNA mapping, and no normalization beyond the schema-enforced syntax; servers MUST reject non-conforming labels with error 2306. Presentation of handles to humans, including any localized display conventions, is a relying-party concern addressed in the registry architecture. Registry Operators SHOULD apply confusable-label policies within the LDH repertoire (e.g., digit/letter lookalikes) through their reserved lists; a future extension could define internationalized handle labels, and would need to address the full set of IDNA and confusability issues that domain registries have encountered.

10. IANA Considerations

10.1. XML Namespaces

This document uses URNs to describe XML namespaces and XML schemas conforming to a registry mechanism described in [RFC3688]. Two URN assignments are requested.

Registration request for the Agent Identity namespace:

  • URI: urn:ietf:params:xml:ns:epp:aid-1.0
  • Registrant Contact: IESG
  • XML: None. Namespace URIs do not represent an XML specification.

Registration request for the Handle namespace:

  • URI: urn:ietf:params:xml:ns:epp:aidHandle-1.0
  • Registrant Contact: IESG
  • XML: None. Namespace URIs do not represent an XML specification.

10.2. XML Schemas

Two schema assignments are requested.

Registration request for the Agent Identity schema:

  • URI: urn:ietf:params:xml:schema:epp:aid-1.0
  • Registrant Contact: IESG
  • XML: See Section 13.1 of this document.

Registration request for the Handle schema:

  • URI: urn:ietf:params:xml:schema:epp:aidHandle-1.0
  • Registrant Contact: IESG
  • XML: See Section 13.2 of this document.

10.3. EPP Extension Registry

The EPP mappings described in this document should be registered by IANA in the "Extensions for the Extensible Provisioning Protocol (EPP)" registry described in [RFC7451]. Two registrations are requested; both use the registration policy "Specification Required".

Registration for the Agent Identity object mapping:

Name of Extension
EPP Mapping for Agent Identity Objects
Document Status
Experimental
Reference
This document
Registrant Name and Email Address
IESG, iesg@ietf.org
TLDs
Any
IPR Disclosure
None
Status
Active
Notes
None

Registration for the Handle object mapping:

Name of Extension
EPP Mapping for Agent Identity Handle Objects
Document Status
Experimental
Reference
This document
Registrant Name and Email Address
IESG, iesg@ietf.org
TLDs
Any
IPR Disclosure
None
Status
Active
Notes
None

The "aid" URN namespace and the "Agent Identity Shared Namespaces" registry are requested by [I-D.drake-agent-identity-registry] and are not re-registered here.

11. Security Considerations

The security considerations of [RFC5730] and [RFC5734] apply to the use of this mapping and are not repeated here. This section addresses considerations specific to Agent Identity and Handle objects; the identity-model security considerations of [I-D.drake-agent-identity-registry] apply to the system this mapping provisions.

The registry records attestation outcomes; it does not re-perform attestation. The trustworthiness of a trust tier recorded through <create> or <update> is only as strong as the Registrar's verification of the hardware ceremony. A dishonest or compromised Registrar can assert bindings that no ceremony supports. This is the same trust placed in domain Registrars and is bounded by accreditation and escrow-based audit ([I-D.drake-agent-identity-registry]), not by this protocol. Servers SHOULD retain per-command provenance sufficient for after-the-fact audit.

Transfer authorization (Section 4.2.4.1) is designed to resist replay and misdirection: the signed payload binds the object, the gaining client identifier, a timestamp, and a server-checked nonce, and the server rejects proofs outside the acceptance window or reusing a (fingerprint, nonce) pair. A proof intercepted in transit or disclosed by the gaining Registrar is designed to be useless to any other Registrar because the gaining identifier is bound into the signed material and checked against the submitting session. The design does not defend against a gaining Registrar that is itself the adversary and already possesses a valid proof for its own identifier; nor against an attacker in control of an active enrolled device, who by construction can authorize transfer exactly as the legitimate agent could. Loss of all active devices leaves an identity non-transferable and unrecoverable, which is the intended property of the underlying architecture rather than a defect of this mapping.

Fingerprint uniqueness is a global invariant within a namespace. Its authoritative enforcement point (Section 2.3) is a correctness-critical serialization bottleneck: an implementation that relaxed it for availability could admit two identities backed by one device, defeating the anti-Sybil property the registry exists to provide. Availability responses and collision errors are constrained to bound/not-bound to avoid disclosing the holder, but a residual oracle remains: any party that can compute a candidate fingerprint can learn whether that specific device is enrolled somewhere in the namespace. Because the input is a device public key rather than a guessable name, this oracle is designed to resist enumeration of the identity population, but it is not zero-knowledge, and operators SHOULD rate-limit <check> to blunt confirmation of held-key hypotheses.

The permanence of device bindings means a fingerprint submitted in error, or belonging to a device later believed compromised, cannot be unbound; it can only be disabled. Registrars SHOULD treat <create> and device-adding <update> commands as irreversible and verify device provenance accordingly.

Handle retirement is terminal and server-driven; the retire-only remedy means a compromised or coerced Registrar cannot use the dispute path to move a name to a favored party, because no path reassigns a name. The corresponding risk is denial: an erroneous retirement permanently destroys a name. Governance-level process, not this protocol, governs when retirement is warranted.

12. Privacy Considerations

This mapping provisions identifiers for autonomous entities, not natural persons; the operator-email attribute is the only routinely personal datum and is OPTIONAL. The privacy stance of [I-D.drake-agent-identity-registry] governs the wider system. Two provisioning-specific points bear emphasis.

First, hardware fingerprints and public keys are commercially and behaviorally sensitive: they link a physical device to an identity and, across namespaces, to each other. This mapping therefore withholds <aid:device> data, SPKI values, and operator email from any client that is not the sponsoring client (Section 4.1.2), and constrains fingerprint availability and collision reporting to bound/not-bound (Section 2.3). Registry Operators MUST NOT expose through EPP a mapping from fingerprint to holding identity or sponsoring Registrar.

Second, escrow deposits (Section 8) contain the full device set for every identity. Fingerprints and SPKI values within deposits MUST be encrypted to the Governance Authority escrow key so that the escrow agent holds recoverable identity records without holding a cleartext cross-Registrar device index.

13. Formal Syntax

Two EPP object mapping schemas are presented here. The first line of each, a "BEGIN"/"END" style delimiter, is not part of the schema; it is present to note the schema boundaries.

13.1. Agent Identity Schema

<?xml version="1.0" encoding="UTF-8"?>

<schema targetNamespace="urn:ietf:params:xml:ns:epp:aid-1.0"
        xmlns:aid="urn:ietf:params:xml:ns:epp:aid-1.0"
        xmlns:eppcom="urn:ietf:params:xml:ns:eppcom-1.0"
        xmlns="http://www.w3.org/2001/XMLSchema"
        elementFormDefault="qualified">

  <!--
  Import common element types.
  -->
  <import namespace="urn:ietf:params:xml:ns:eppcom-1.0"/>

  <annotation>
    <documentation>
      Extensible Provisioning Protocol v1.0
      Agent Identity provisioning schema.
    </documentation>
  </annotation>

  <!--
  Child elements found in EPP commands.
  -->
  <element name="check" type="aid:checkType"/>
  <element name="create" type="aid:createType"/>
  <element name="delete" type="aid:deleteType"/>
  <element name="info" type="aid:sIDType"/>
  <element name="transfer" type="aid:transferType"/>
  <element name="update" type="aid:updateType"/>

  <!--
  Agent identity URN (canonical form), per the "aid" URN
  namespace defined in draft-drake-agent-identity-registry.
  -->
  <simpleType name="urnType">
    <restriction base="token">
      <pattern value="urn:aid:[a-z0-9\-]+:[a-z0-9\-]+"/>
      <maxLength value="255"/>
    </restriction>
  </simpleType>

  <!--
  Namespace label (governance-allocated shared namespace).
  -->
  <simpleType name="nsType">
    <restriction base="token">
      <pattern value="[a-z0-9\-]+"/>
      <maxLength value="200"/>
    </restriction>
  </simpleType>

  <!--
  Hardware fingerprint: SHA-256 over the DER-encoded
  SubjectPublicKeyInfo, lowercase hexadecimal.
  -->
  <simpleType name="fpType">
    <restriction base="token">
      <pattern value="[0-9a-f]{64}"/>
    </restriction>
  </simpleType>

  <!--
  Hardware type codes, per the trust-tier taxonomy of
  draft-drake-agent-identity-registry.
  -->
  <simpleType name="hwCodeType">
    <restriction base="token">
      <enumeration value="TPM"/>
      <enumeration value="PIV"/>
      <enumeration value="ENC"/>
      <enumeration value="VRT"/>
      <enumeration value="SFT"/>
    </restriction>
  </simpleType>

  <!--
  Trust tier values.
  -->
  <simpleType name="tierType">
    <restriction base="token">
      <enumeration value="sovereign"/>
      <enumeration value="portable"/>
      <enumeration value="enclave"/>
      <enumeration value="virtual"/>
      <enumeration value="declared"/>
    </restriction>
  </simpleType>

  <!--
  Manufacturer identifier.
  -->
  <simpleType name="mfrType">
    <restriction base="token">
      <minLength value="1"/>
      <maxLength value="64"/>
    </restriction>
  </simpleType>

  <!--
  Free-form metadata strings (empty value clears the field
  when used within a chg element).
  -->
  <simpleType name="metaType">
    <restriction base="token">
      <minLength value="0"/>
      <maxLength value="255"/>
    </restriction>
  </simpleType>

  <!--
  Child element of the commands for check.  The identity
  check is keyed by hardware fingerprint, not by object
  identifier: canonical identifiers are server-allocated,
  so fingerprint availability is the meaningful pre-flight
  provisioning question.
  -->
  <complexType name="checkType">
    <sequence>
      <element name="fp" type="aid:fpType"
       maxOccurs="unbounded"/>
    </sequence>
  </complexType>

  <!--
  Child elements of the create command.
  -->
  <complexType name="createType">
    <sequence>
      <element name="ns" type="aid:nsType"/>
      <element name="device" type="aid:deviceType"
       maxOccurs="unbounded"/>
      <element name="displayName" type="aid:metaType"
       minOccurs="0"/>
      <element name="email" type="aid:metaType"
       minOccurs="0"/>
    </sequence>
  </complexType>

  <!--
  A hardware device binding as submitted by a client.  The
  server derives the fingerprint from the SPKI; clients do
  not submit fingerprints at create time.
  -->
  <complexType name="deviceType">
    <sequence>
      <element name="spki" type="base64Binary"/>
      <element name="hwType" type="aid:hwCodeType"/>
      <element name="mfr" type="aid:mfrType"/>
    </sequence>
  </complexType>

  <!--
  Child element of commands that require a single identity
  identifier (info).
  -->
  <complexType name="sIDType">
    <sequence>
      <element name="id" type="aid:urnType"/>
    </sequence>
  </complexType>

  <!--
  Child elements of the delete (decommission) command.  The
  hardware-signed consent proof is REQUIRED.
  -->
  <complexType name="deleteType">
    <sequence>
      <element name="id" type="aid:urnType"/>
      <element name="hwAuth" type="aid:hwAuthType"/>
    </sequence>
  </complexType>

  <!--
  Child elements of the transfer command.
  -->
  <complexType name="transferType">
    <sequence>
      <element name="id" type="aid:urnType"/>
      <element name="hwAuth" type="aid:hwAuthType"
       minOccurs="0"/>
    </sequence>
  </complexType>

  <!--
  Hardware-signed authorization proof (transfer request and
  decommission consent).
  -->
  <complexType name="hwAuthType">
    <sequence>
      <element name="fp" type="aid:fpType"/>
      <element name="alg" type="aid:algType"/>
      <element name="signedAt" type="dateTime"/>
      <element name="nonce" type="base64Binary"/>
      <element name="sig" type="base64Binary"/>
    </sequence>
  </complexType>

  <!--
  JSON Web Signature algorithm identifier (RFC 7518).
  -->
  <simpleType name="algType">
    <restriction base="token">
      <minLength value="1"/>
      <maxLength value="16"/>
    </restriction>
  </simpleType>

  <!--
  Child elements of the update command.
  -->
  <complexType name="updateType">
    <sequence>
      <element name="id" type="aid:urnType"/>
      <element name="add" type="aid:addType"
       minOccurs="0"/>
      <element name="rem" type="aid:remType"
       minOccurs="0"/>
      <element name="chg" type="aid:chgType"
       minOccurs="0"/>
    </sequence>
  </complexType>

  <!--
  Data elements that can be added to an identity.
  -->
  <complexType name="addType">
    <sequence>
      <element name="device" type="aid:deviceType"
       minOccurs="0" maxOccurs="unbounded"/>
      <element name="status" type="aid:statusType"
       minOccurs="0" maxOccurs="unbounded"/>
    </sequence>
  </complexType>

  <!--
  Data elements whose effect can be withdrawn from an
  identity.  A removed device binding is transitioned to
  "disabled" status; the binding record itself is retained
  permanently.
  -->
  <complexType name="remType">
    <sequence>
      <element name="fp" type="aid:fpType"
       minOccurs="0" maxOccurs="unbounded"/>
      <element name="status" type="aid:statusType"
       minOccurs="0" maxOccurs="unbounded"/>
    </sequence>
  </complexType>

  <!--
  Data elements that can be changed.
  -->
  <complexType name="chgType">
    <sequence>
      <element name="displayName" type="aid:metaType"
       minOccurs="0"/>
      <element name="email" type="aid:metaType"
       minOccurs="0"/>
      <element name="hardwareLock" type="boolean"
       minOccurs="0"/>
    </sequence>
  </complexType>

  <!--
  Child response elements.
  -->
  <element name="chkData" type="aid:chkDataType"/>
  <element name="creData" type="aid:creDataType"/>
  <element name="infData" type="aid:infDataType"/>
  <element name="trnData" type="aid:trnDataType"/>

  <!--
  check response elements.
  -->
  <complexType name="chkDataType">
    <sequence>
      <element name="cd" type="aid:checkFpType"
       maxOccurs="unbounded"/>
    </sequence>
  </complexType>

  <complexType name="checkFpType">
    <sequence>
      <element name="fp" type="aid:checkedFpType"/>
      <element name="reason" type="eppcom:reasonType"
       minOccurs="0"/>
    </sequence>
  </complexType>

  <complexType name="checkedFpType">
    <simpleContent>
      <extension base="aid:fpType">
        <attribute name="avail" type="boolean"
         use="required"/>
      </extension>
    </simpleContent>
  </complexType>

  <!--
  create response elements.
  -->
  <complexType name="creDataType">
    <sequence>
      <element name="id" type="aid:urnType"/>
      <element name="roid" type="eppcom:roidType"/>
      <element name="crDate" type="dateTime"/>
    </sequence>
  </complexType>

  <!--
  info response elements.
  -->
  <complexType name="infDataType">
    <sequence>
      <element name="id" type="aid:urnType"/>
      <element name="roid" type="eppcom:roidType"/>
      <element name="status" type="aid:statusType"
       maxOccurs="unbounded"/>
      <element name="tier" type="aid:tierType"/>
      <element name="device" type="aid:infDeviceType"
       minOccurs="0" maxOccurs="unbounded"/>
      <element name="handle" type="aid:urnType"
       minOccurs="0"/>
      <element name="displayName" type="aid:metaType"
       minOccurs="0"/>
      <element name="email" type="aid:metaType"
       minOccurs="0"/>
      <element name="clID" type="eppcom:clIDType"/>
      <element name="crID" type="eppcom:clIDType"
       minOccurs="0"/>
      <element name="crDate" type="dateTime"
       minOccurs="0"/>
      <element name="upID" type="eppcom:clIDType"
       minOccurs="0"/>
      <element name="upDate" type="dateTime"
       minOccurs="0"/>
      <element name="trDate" type="dateTime"
       minOccurs="0"/>
    </sequence>
  </complexType>

  <!--
  A hardware device binding as reported by the server.  The
  spki element is returned only to the sponsoring client.
  -->
  <complexType name="infDeviceType">
    <sequence>
      <element name="fp" type="aid:fpType"/>
      <element name="hwType" type="aid:hwCodeType"/>
      <element name="mfr" type="aid:mfrType"/>
      <element name="spki" type="base64Binary"
       minOccurs="0"/>
      <element name="bindDate" type="dateTime"/>
    </sequence>
    <attribute name="s" type="aid:devStatusType"
     use="required"/>
  </complexType>

  <simpleType name="devStatusType">
    <restriction base="token">
      <enumeration value="active"/>
      <enumeration value="disabled"/>
    </restriction>
  </simpleType>

  <!--
  Status is a combination of attributes and an optional
  human-readable message that may be expressed in languages
  other than English.
  -->
  <complexType name="statusType">
    <simpleContent>
      <extension base="normalizedString">
        <attribute name="s" type="aid:statusValueType"
         use="required"/>
        <attribute name="lang" type="language"
         default="en"/>
      </extension>
    </simpleContent>
  </complexType>

  <simpleType name="statusValueType">
    <restriction base="token">
      <enumeration value="ok"/>
      <enumeration value="inactive"/>
      <enumeration value="hardwareLocked"/>
      <enumeration value="pendingTransfer"/>
      <enumeration value="clientUpdateProhibited"/>
      <enumeration value="serverUpdateProhibited"/>
      <enumeration value="clientDeleteProhibited"/>
      <enumeration value="serverDeleteProhibited"/>
    </restriction>
  </simpleType>

  <!--
  transfer response elements.
  -->
  <complexType name="trnDataType">
    <sequence>
      <element name="id" type="aid:urnType"/>
      <element name="trStatus" type="eppcom:trStatusType"/>
      <element name="reID" type="eppcom:clIDType"/>
      <element name="reDate" type="dateTime"/>
      <element name="acID" type="eppcom:clIDType"/>
      <element name="acDate" type="dateTime"/>
    </sequence>
  </complexType>

  <!--
  End of schema.
  -->
</schema>

13.2. Handle Schema

<?xml version="1.0" encoding="UTF-8"?>

<schema targetNamespace="urn:ietf:params:xml:ns:epp:aidHandle-1.0"
        xmlns:aidHandle="urn:ietf:params:xml:ns:epp:aidHandle-1.0"
        xmlns:eppcom="urn:ietf:params:xml:ns:eppcom-1.0"
        xmlns="http://www.w3.org/2001/XMLSchema"
        elementFormDefault="qualified">

  <!--
  Import common element types.
  -->
  <import namespace="urn:ietf:params:xml:ns:eppcom-1.0"/>

  <annotation>
    <documentation>
      Extensible Provisioning Protocol v1.0
      Handle provisioning schema.
    </documentation>
  </annotation>

  <!--
  Child elements found in EPP commands.  There is
  intentionally no transfer element: handles are
  non-transferable.
  -->
  <element name="check" type="aidHandle:mNameType"/>
  <element name="create" type="aidHandle:createType"/>
  <element name="delete" type="aidHandle:sNameType"/>
  <element name="info" type="aidHandle:sNameType"/>
  <element name="renew" type="aidHandle:renewType"/>
  <element name="update" type="aidHandle:updateType"/>

  <!--
  Handle-form agent identity URN.  The agent-id portion
  begins with a letter and therefore cannot collide with
  canonical identifiers (which begin with "id-").
  -->
  <simpleType name="urnType">
    <restriction base="token">
      <pattern value="urn:aid:[a-z0-9\-]+:[a-z][a-z0-9\-]*"/>
      <maxLength value="255"/>
    </restriction>
  </simpleType>

  <!--
  Canonical-form agent identity URN, used to link a handle
  to the identity it names.  The canonical identifier is
  "id-" followed by 20 characters of the 19-consonant
  alphabet defined in draft-drake-agent-identity-registry,
  written as four hyphen-separated groups of five.
  -->
  <simpleType name="idUrnType">
    <restriction base="token">
      <pattern
       value="urn:aid:[a-z0-9\-]+:id(\-[bcdfghjkmnpqrstvwxz]{5}){4}"/>
      <maxLength value="255"/>
    </restriction>
  </simpleType>

  <!--
  Child element of commands for check.
  -->
  <complexType name="mNameType">
    <sequence>
      <element name="name" type="aidHandle:urnType"
       maxOccurs="unbounded"/>
    </sequence>
  </complexType>

  <!--
  Child element of commands that require a single name
  (delete, info).
  -->
  <complexType name="sNameType">
    <sequence>
      <element name="name" type="aidHandle:urnType"/>
    </sequence>
  </complexType>

  <!--
  Child elements of the create command.
  -->
  <complexType name="createType">
    <sequence>
      <element name="name" type="aidHandle:urnType"/>
      <element name="identity" type="aidHandle:idUrnType"/>
      <element name="period" type="aidHandle:periodType"
       minOccurs="0"/>
    </sequence>
  </complexType>

  <!--
  Registration periods, as in the EPP domain name mapping.
  -->
  <complexType name="periodType">
    <simpleContent>
      <extension base="aidHandle:pLimitType">
        <attribute name="unit" type="aidHandle:pUnitType"
         use="required"/>
      </extension>
    </simpleContent>
  </complexType>

  <simpleType name="pLimitType">
    <restriction base="unsignedShort">
      <minInclusive value="1"/>
      <maxInclusive value="99"/>
    </restriction>
  </simpleType>

  <simpleType name="pUnitType">
    <restriction base="token">
      <enumeration value="y"/>
      <enumeration value="m"/>
    </restriction>
  </simpleType>

  <!--
  Child elements of the renew command.
  -->
  <complexType name="renewType">
    <sequence>
      <element name="name" type="aidHandle:urnType"/>
      <element name="curExpDate" type="date"/>
      <element name="period" type="aidHandle:periodType"
       minOccurs="0"/>
    </sequence>
  </complexType>

  <!--
  Child elements of the update command.  Handles carry no
  client-mutable scalar attributes; update manages status
  values only.
  -->
  <complexType name="updateType">
    <sequence>
      <element name="name" type="aidHandle:urnType"/>
      <element name="add" type="aidHandle:addRemType"
       minOccurs="0"/>
      <element name="rem" type="aidHandle:addRemType"
       minOccurs="0"/>
    </sequence>
  </complexType>

  <complexType name="addRemType">
    <sequence>
      <element name="status" type="aidHandle:statusType"
       maxOccurs="unbounded"/>
    </sequence>
  </complexType>

  <!--
  Child response elements.
  -->
  <element name="chkData" type="aidHandle:chkDataType"/>
  <element name="creData" type="aidHandle:creDataType"/>
  <element name="infData" type="aidHandle:infDataType"/>
  <element name="renData" type="aidHandle:renDataType"/>

  <!--
  check response elements.
  -->
  <complexType name="chkDataType">
    <sequence>
      <element name="cd" type="aidHandle:checkNameType"
       maxOccurs="unbounded"/>
    </sequence>
  </complexType>

  <complexType name="checkNameType">
    <sequence>
      <element name="name" type="aidHandle:checkedNameType"/>
      <element name="reason" type="eppcom:reasonType"
       minOccurs="0"/>
    </sequence>
  </complexType>

  <complexType name="checkedNameType">
    <simpleContent>
      <extension base="aidHandle:urnType">
        <attribute name="avail" type="boolean"
         use="required"/>
      </extension>
    </simpleContent>
  </complexType>

  <!--
  create response elements.
  -->
  <complexType name="creDataType">
    <sequence>
      <element name="name" type="aidHandle:urnType"/>
      <element name="crDate" type="dateTime"/>
      <element name="exDate" type="dateTime"/>
    </sequence>
  </complexType>

  <!--
  renew response elements.
  -->
  <complexType name="renDataType">
    <sequence>
      <element name="name" type="aidHandle:urnType"/>
      <element name="exDate" type="dateTime"/>
    </sequence>
  </complexType>

  <!--
  info response elements.
  -->
  <complexType name="infDataType">
    <sequence>
      <element name="name" type="aidHandle:urnType"/>
      <element name="roid" type="eppcom:roidType"/>
      <element name="identity" type="aidHandle:idUrnType"/>
      <element name="status" type="aidHandle:statusType"
       maxOccurs="unbounded"/>
      <element name="clID" type="eppcom:clIDType"/>
      <element name="crID" type="eppcom:clIDType"
       minOccurs="0"/>
      <element name="crDate" type="dateTime"
       minOccurs="0"/>
      <element name="upID" type="eppcom:clIDType"
       minOccurs="0"/>
      <element name="upDate" type="dateTime"
       minOccurs="0"/>
      <element name="exDate" type="dateTime"
       minOccurs="0"/>
    </sequence>
  </complexType>

  <!--
  Status is a combination of attributes and an optional
  human-readable message.
  -->
  <complexType name="statusType">
    <simpleContent>
      <extension base="normalizedString">
        <attribute name="s" type="aidHandle:statusValueType"
         use="required"/>
        <attribute name="lang" type="language"
         default="en"/>
      </extension>
    </simpleContent>
  </complexType>

  <simpleType name="statusValueType">
    <restriction base="token">
      <enumeration value="ok"/>
      <enumeration value="disabled"/>
      <enumeration value="retired"/>
      <enumeration value="pendingDelete"/>
      <enumeration value="clientRenewProhibited"/>
      <enumeration value="serverRenewProhibited"/>
      <enumeration value="clientUpdateProhibited"/>
      <enumeration value="serverUpdateProhibited"/>
      <enumeration value="clientDeleteProhibited"/>
      <enumeration value="serverDeleteProhibited"/>
    </restriction>
  </simpleType>

  <!--
  End of schema.
  -->
</schema>

14. Acknowledgments

This mapping follows the structure established by the EPP domain name mapping [RFC5731]; readers familiar with that document will recognize most of the machinery here. The author thanks the participants of the IETF REGEXT working group whose object mappings served as the template for this work.

15. Normative References

[RFC2119]
Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/RFC2119, , <https://www.rfc-editor.org/info/rfc2119>.
[RFC3688]
Mealling, M., "The IETF XML Registry", BCP 81, RFC 3688, DOI 10.17487/RFC3688, , <https://www.rfc-editor.org/info/rfc3688>.
[RFC3735]
Hollenbeck, S., "Guidelines for Extending the Extensible Provisioning Protocol (EPP)", RFC 3735, DOI 10.17487/RFC3735, , <https://www.rfc-editor.org/info/rfc3735>.
[RFC3915]
Hollenbeck, S., "Domain Registry Grace Period Mapping for the Extensible Provisioning Protocol (EPP)", RFC 3915, DOI 10.17487/RFC3915, , <https://www.rfc-editor.org/info/rfc3915>.
[RFC5730]
Hollenbeck, S., "Extensible Provisioning Protocol (EPP)", STD 69, RFC 5730, DOI 10.17487/RFC5730, , <https://www.rfc-editor.org/info/rfc5730>.
[RFC5731]
Hollenbeck, S., "Extensible Provisioning Protocol (EPP) Domain Name Mapping", STD 69, RFC 5731, DOI 10.17487/RFC5731, , <https://www.rfc-editor.org/info/rfc5731>.
[RFC5734]
Hollenbeck, S., "Extensible Provisioning Protocol (EPP) Transport over TCP", STD 69, RFC 5734, DOI 10.17487/RFC5734, , <https://www.rfc-editor.org/info/rfc5734>.
[RFC7451]
Hollenbeck, S., "Extension Registry for the Extensible Provisioning Protocol", RFC 7451, DOI 10.17487/RFC7451, , <https://www.rfc-editor.org/info/rfc7451>.
[RFC7518]
Jones, M., "JSON Web Algorithms (JWA)", RFC 7518, DOI 10.17487/RFC7518, , <https://www.rfc-editor.org/info/rfc7518>.
[RFC8141]
Saint-Andre, P. and J. Klensin, "Uniform Resource Names (URNs)", RFC 8141, DOI 10.17487/RFC8141, , <https://www.rfc-editor.org/info/rfc8141>.
[RFC8174]
Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, , <https://www.rfc-editor.org/info/rfc8174>.
[RFC8909]
Lozano, G., "Registry Data Escrow Specification", RFC 8909, DOI 10.17487/RFC8909, , <https://www.rfc-editor.org/info/rfc8909>.
[RFC9022]
Lozano, G., Gould, J., and C. Thippeswamy, "Domain Name Registration Data (DNRD) Objects Mapping", RFC 9022, DOI 10.17487/RFC9022, , <https://www.rfc-editor.org/info/rfc9022>.
[RFC9154]
Gould, J. and R. Wilhelm, "Extensible Provisioning Protocol (EPP) Secure Authorization Information for Transfer", RFC 9154, DOI 10.17487/RFC9154, , <https://www.rfc-editor.org/info/rfc9154>.
[RFC9846]
Rescorla, E., "The Transport Layer Security (TLS) Protocol Version 1.3", RFC 9846, DOI 10.17487/RFC9846, , <https://www.rfc-editor.org/info/rfc9846>.
[I-D.drake-agent-identity-registry]
Drake, C., "Agent Identity Registry System: A Federated Architecture for Hardware-Anchored Identity of Autonomous Entities", Work in Progress, Internet-Draft, draft-drake-agent-identity-registry-04, , <https://datatracker.ietf.org/doc/html/draft-drake-agent-identity-registry-04>.

16. Informative References

[RFC5733]
Hollenbeck, S., "Extensible Provisioning Protocol (EPP) Contact Mapping", STD 69, RFC 5733, DOI 10.17487/RFC5733, , <https://www.rfc-editor.org/info/rfc5733>.
[I-D.drake-email-hardware-attestation]
Drake, C., "Hardware Attestation for Email Sender Verification", Work in Progress, Internet-Draft, draft-drake-email-hardware-attestation-03, , <https://datatracker.ietf.org/doc/html/draft-drake-email-hardware-attestation-03>.
[I-D.drake-agent-identity-resolution]
Drake, C., "Resolution and Verification of Agent Identities using DNS and RDAP", Work in Progress, Internet-Draft, draft-drake-agent-identity-resolution-00, , <https://datatracker.ietf.org/doc/html/draft-drake-agent-identity-resolution-00>.

Author's Address

Christopher Drake
1id.com