<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="rfc2629.xslt"?>
<!DOCTYPE rfc [
  <!ENTITY nbsp    "&#160;">
  <!ENTITY zwsp   "&#8203;">
  <!ENTITY nbhy   "&#8209;">
  <!ENTITY wj     "&#8288;">
]>
<rfc xmlns:xi="http://www.w3.org/2001/XInclude"
     category="info"
     docName="draft-helixar-hdp-agentic-delegation-02"
     ipr="trust200902"
     obsoletes=""
     updates=""
     xml:lang="en"
     version="3">

  <front>
    <title abbrev="HDP Agentic Delegation">
      Human Delegation Provenance Protocol (HDP):
      Cryptographic Chain-of-Custody for Agentic AI Systems
    </title>

    <seriesInfo name="Internet-Draft" value="draft-helixar-hdp-agentic-delegation-02"/>

    <author fullname="Asiri Dalugoda" initials="A." surname="Dalugoda">
      <organization>Helixar Limited</organization>
      <address>
        <email>protocol@helixar.ai</email>
        <uri>https://helixar.ai</uri>
      </address>
    </author>

    <date year="2026" month="September" day="11"/>

    <area>Security</area>

    <keyword>agentic AI</keyword>
    <keyword>delegation</keyword>
    <keyword>provenance</keyword>
    <keyword>Ed25519</keyword>
    <keyword>token</keyword>
    <keyword>chain of custody</keyword>
    <keyword>human authorization</keyword>

    <abstract>
      <t>
        Agentic AI systems operate on behalf of human principals, often
        delegating tasks through multi-step chains of AI agents. There is
        currently no standard mechanism to record who authorized an agent to
        act, under what scope, and through what chain of delegation, in a
        way that can be verified offline, without a central registry, and
        without third-party trust anchors.
      </t>
      <t>
        This document specifies the Human Delegation Provenance Protocol
        (HDP) version 0.1, a lightweight token-based protocol that captures,
        structures, cryptographically signs, and verifies human delegation
        context in agentic AI systems. An HDP token binds a human
        authorization event to a session, records each agent's delegation
        action as a signed hop in an append-only chain, and enables any
        participant to verify the full provenance record using only the
        issuer's Ed25519 public key and the current session identifier.
        Verification is fully offline. No registry lookup, no network call,
        and no third-party trust anchor is required.
      </t>
      <t>
        HDP's distinguishing contribution is a signed, tamper-evident
        record of each agent's declared action at each hop, an execution audit
        trail that complements, rather than replaces, capability-based
        delegation formats such as UCAN and ZCAP-LD. The underlying
        append-only, offline-verifiable chain-of-custody mechanism is
        payload-agnostic; human-authorized agentic delegation is the
        reference profile specified in this document.
      </t>
      <t>
        HDP is not an authorization protocol. An HDP token confers no
        authority and its presentation entitles the presenter to nothing.
        It is a record of who authorized a task and of what each agent
        declared it did with that authorization, carried with the task
        and read at audit.
      </t>
    </abstract>
  </front>

  <middle>

    <!-- ================================================================ -->
    <section anchor="introduction" numbered="true" toc="default">
      <name>Introduction</name>

      <t>
        Autonomous AI agents are increasingly used to execute consequential
        actions: sending emails, modifying files, running code, calling APIs,
        and transacting on behalf of users. When a human authorizes an
        orchestrator agent, which in turn delegates to sub-agents, which
        further delegate to tool-execution agents, the originating human
        authorization becomes disconnected from the terminal action. There is
        no standard record of the authorization chain.
      </t>
      <t>
        This gap creates accountability, auditability, and safety problems:
      </t>
      <ul spacing="normal">
        <li>
          Downstream agents cannot verify that the action they are being asked
          to perform was actually authorized by a human.
        </li>
        <li>
          Post-hoc audits cannot reconstruct who approved what, and when.
        </li>
        <li>
          Prompt injection attacks (where malicious content in the
          environment instructs an agent to act) cannot be distinguished
          from legitimate human delegation.
        </li>
      </ul>
      <t>
        HDP addresses this by defining a token that:
      </t>
      <ul spacing="normal">
        <li>Records the human principal, their declared scope, and the
        session binding at issuance.</li>
        <li>Accumulates a cryptographically signed hop record for each
        agent that handles the token.</li>
        <li>Allows any recipient to verify the entire chain (root
        signature plus all hop signatures) using only the issuer's
        Ed25519 public key and the session identifier.</li>
      </ul>

      <section anchor="what-hdp-is-not" numbered="true" toc="default">
        <name>What HDP Is Not</name>
        <t>
          HDP is not an authorization protocol, and an HDP token is not
          a capability, an access token, or a credential that entitles
          its holder to anything. Presenting a valid HDP token to a
          service does not authorize the presenter to perform the
          requested action. That decision belongs to the service's own
          access control mechanism, whether that is OAuth 2.0
          (<xref target="comparison-rfc8693"/>), a capability system
          such as UCAN or ZCAP-LD (<xref target="comparison-ucan"/>,
          <xref target="comparison-zcap"/>), or something else. HDP is
          designed to travel alongside such mechanisms, not to replace
          them (<xref target="security-threat-model"/>).
        </t>
        <t>
          Several parts of this document can be misread as
          authorization if this distinction is not kept in view. The
          <tt>scope</tt> object (<xref target="scope"/>) records what
          the human declared, in fields named
          <tt>authorized_tools</tt> and <tt>authorized_resources</tt>
          among others; it is a signed record of the authorization
          event, not a grant. The verification pipeline
          (<xref target="verification"/>) establishes that a token is
          authentic and intact, not that its presenter may act. The
          HTTP transport (<xref target="transport"/>) shows a token
          accompanying a request because the task travels in the
          request, not because the token authorizes it.
        </t>
        <t>
          The primary reader of an HDP token is therefore not the
          service receiving a request but whoever examines the record
          afterwards: post-incident reconstruction of which agent did
          what, under whose authorization, and in what order; compliance
          evidence that a human authorized a class of action; and human
          oversight, where an approver inspects the chain a task has
          accumulated before permitting it to continue. A token is
          carried at invocation and read at audit.
        </t>
      </section>

      <section anchor="motivation" numbered="true" toc="default">
        <name>Motivation</name>
        <t>
          The need for agentic delegation provenance is not hypothetical.
          Production deployments of AI orchestration systems (LangChain,
          AutoGPT, CrewAI, and similar frameworks) today pass natural language
          task descriptions between agents with no cryptographic binding to the
          original human authorization. The operational risk compounds as
          models become more capable and agents are granted access to higher-
          consequence tools.
        </t>
        <t>
          A provenance token that travels alongside the task (tamper-evident,
          offline-verifiable, and scoped to what the human actually
          approved) provides the foundation for auditable, accountable
          agentic systems.
        </t>
      </section>

      <section anchor="design-goals" numbered="true" toc="default">
        <name>Design Goals</name>
        <t>HDP is designed with the following goals in order of priority:</t>
        <ol spacing="normal" type="1">
          <li><strong>Offline verifiability.</strong> Verification MUST require
          only a public key, a session ID, and state held locally by the
          verifier. No network call, registry lookup, or third-party
          endpoint is required.</li>
          <li><strong>Self-sovereignty.</strong> Any organization MUST be able
          to issue and verify HDP tokens without registering with a central
          authority or anchoring to a third-party key.</li>
          <li><strong>Tamper evidence.</strong> Any modification to a
          token's recorded content (its header, principal, scope, or any
          recorded hop) MUST be detectable by the verification pipeline.
          Completeness of the chain (that no trailing hop has been omitted)
          is a separate property; see <xref target="security-truncation"/>.</li>
          <li><strong>Minimal footprint.</strong> The protocol MUST be
          implementable in any language with Ed25519 and JSON support. No
          mandatory infrastructure beyond key management is required.</li>
          <li><strong>Privacy by design.</strong> Principal identity fields
          MUST be separable from the audit-relevant parts of the token, so
          tokens can be transmitted to agents without exposing PII.</li>
        </ol>
      </section>

      <section anchor="relationship-to-ipp" numbered="true" toc="default">
        <name>Relationship to IPP (draft-haberkamp-ipp-01)</name>
        <t>
          The Intent Provenance Protocol
          <xref target="I-D.haberkamp-ipp"/> addresses the same problem space.
          HDP and IPP share the use of Ed25519 signatures and append-only
          provenance chains but make different architectural trade-offs, which
          are detailed in <xref target="comparison"/>. The two protocols are
          not interoperable. HDP is offered as a distinct design point, not a
          revision of IPP.
        </t>
        <t>
          The full HDP protocol specification is available at
          <xref target="HDP-SPEC"/>. A TypeScript reference implementation
          is available at <xref target="HDP-IMPL"/>.
        </t>
      </section>

      <section anchor="generality" numbered="true" toc="default">
        <name>Generality of the Chain-of-Custody Mechanism</name>
        <t>
          The core of HDP is an append-only, cryptographically chained
          record: each hop extends a signed entry that covers all prior
          state, gaps in the hop sequence are tamper-evident, and any
          party can verify the entire chain offline using only a public
          key. This chain-of-custody mechanism is independent of what the
          chain carries.
        </t>
        <t>
          This document profiles that mechanism for one application:
          human-authorized agentic delegation. In this profile the
          carried payload is the <tt>scope</tt> object
          (<xref target="scope"/>) and each hop record describes an agent
          delegation action. The same mechanism could carry other
          payloads, for example data provenance, consent delegation, or
          physical-world command chains, each as a distinct profile.
          Such profiles are out of scope for this document; HDP v0.1
          defines only the agentic-delegation profile. Where practical,
          the signing (<xref target="root-signing"/>,
          <xref target="hop-signing"/>) and verification
          (<xref target="verification"/>) procedures are described in a
          payload-agnostic way so that future profiles can reuse them
          unchanged.
        </t>
      </section>
    </section>

    <!-- ================================================================ -->
    <section anchor="conventions" numbered="true" toc="default">
      <name>Conventions and Definitions</name>
      <t>
        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 <xref target="RFC2119"/> and <xref target="RFC8174"/> when,
        and only when, they appear in all capitals, as shown here.
      </t>
      <dl spacing="normal" newline="false">
        <dt>Issuer:</dt>
        <dd>The system or person that creates and signs an HDP token on
        behalf of a human principal.</dd>
        <dt>Principal:</dt>
        <dd>The human who authorized the agentic task. Represented in the
        token's <tt>principal</tt> object.</dd>
        <dt>Agent:</dt>
        <dd>Any AI system, model, or automated process that receives and
        acts upon an HDP token.</dd>
        <dt>Hop:</dt>
        <dd>A single delegation event, recorded as a signed entry in the
        token's <tt>chain</tt> array.</dd>
        <dt>Root signature:</dt>
        <dd>The Ed25519 signature over the token's header, principal, and
        scope, computed by the issuer at token creation time.</dd>
        <dt>Hop signature:</dt>
        <dd>The Ed25519 signature over the cumulative chain state at the
        time of extension. In HDP v0.1 it is produced by the issuer using
        the same key as the root signature.</dd>
        <dt>Session:</dt>
        <dd>A logical unit of work identified by a <tt>session_id</tt>
        string, established between the issuer and the agent framework
        before the token is issued.</dd>
        <dt>Verifier:</dt>
        <dd>Any party that checks an HDP token: an agent receiving a
        task uses the live acceptance pipeline
        (<xref target="verification"/>); an audit system or human
        reviewer's tooling uses historical audit verification
        (<xref target="historical-audit"/>).</dd>
        <dt>Presenter:</dt>
        <dd>The agent that transmits a token to a verifier. In a
        complete chain the presenter is the agent that appended the
        final hop.</dd>
      </dl>
    </section>

    <!-- ================================================================ -->
    <section anchor="token-structure" numbered="true" toc="default">
      <name>Token Structure</name>
      <t>
        An HDP token is a JSON object with six top-level fields. The token
        MUST conform to the following structure. All integer timestamps are
        Unix milliseconds (milliseconds since 1970-01-01T00:00:00Z).
      </t>

      <t>
        Before signing or verifying a token, implementations MUST validate
        its JSON representation and all REQUIRED fields, types, and
        constraints defined in this section. The input MUST satisfy the
        I-JSON requirements of RFC 8785, including rejection of duplicate
        object member names, invalid Unicode strings, and non-finite
        numbers. Duplicate names MUST be detected before parsing discards
        them. Values MUST NOT be coerced from strings or booleans to
        satisfy a numeric field's type.
      </t>
      <t anchor="integer-ranges">
        The integer fields <tt>header.issued_at</tt>,
        <tt>header.expires_at</tt>, and each hop's <tt>timestamp</tt>
        and <tt>parent_hop</tt> MUST be in the inclusive range 0 through
        9007199254740991 (2^53 - 1). Each hop's <tt>seq</tt> and
        <tt>scope.max_hops</tt>, when present, MUST be in the inclusive
        range 1 through 9007199254740991. These are JSON numbers, not
        strings. Implementations MUST check their numeric values before
        any lossy conversion and MUST reject fractional or out-of-range
        values rather than round them. The bounds ensure exact integer
        representation in the IEEE 754 double-precision model used by
        RFC 8785. They are representation bounds, not an operational
        delegation budget. Other numeric values, such as numbers inside
        <tt>principal.metadata</tt>, remain subject to RFC 8785.
      </t>

      <figure anchor="token-overview-diagram">
        <name>HDP Token Top-Level Structure</name>
        <artwork type="ascii-art"><![CDATA[
{
  "hdp"       : "0.1",          // protocol version
  "header"    : { ... },        // session binding + lifecycle
  "principal" : { ... },        // authorizing human
  "scope"     : { ... },        // authorized intent + constraints
  "chain"     : [ ... ],        // delegation hops (append-only)
  "signature" : { ... }         // root Ed25519 signature
}
        ]]></artwork>
      </figure>

      <section anchor="header" numbered="true" toc="default">
        <name>Header</name>
        <t>
          The <tt>header</tt> object carries token lifecycle and session
          binding fields.
        </t>
        <sourcecode type="json"><![CDATA[
{
  "token_id"        : "550e8400-e29b-41d4-a716-446655440000",
  "issued_at"       : 1711483200000,
  "expires_at"      : 1711569600000,
  "session_id"      : "sess-20260326-abc123",
  "version"         : "0.1",
  "parent_token_id" : "..."
}
        ]]></sourcecode>
        <dl spacing="normal" newline="false">
          <dt>token_id:</dt>
          <dd>REQUIRED. A version 4 UUID <xref target="RFC9562"/>. Unique
          identifier for this token.</dd>
          <dt>issued_at:</dt>
          <dd>REQUIRED. Unix milliseconds. Time of issuance.</dd>
          <dt>expires_at:</dt>
          <dd>REQUIRED. Unix milliseconds. MUST be greater than
          <tt>issued_at</tt>. A token MUST NOT be accepted for live use
          at or after this time. Expiry does not prevent historical
          integrity verification (<xref target="historical-audit"/>).
          HDP defines no default lifetime; the value is an issuer
          choice, and <xref target="security-replay"/> discusses how
          to make it.</dd>
          <dt>session_id:</dt>
          <dd>REQUIRED. Opaque string. Established out-of-band between
          issuer and agent framework before token issuance. Provides
          replay defense: a token is only valid within the session for
          which it was issued.</dd>
          <dt>version:</dt>
          <dd>REQUIRED. MUST equal the value of the top-level <tt>hdp</tt>
          field.</dd>
          <dt>parent_token_id:</dt>
          <dd>OPTIONAL. If present, identifies the token this token
          supersedes in a re-authorization chain. See
          <xref target="reauthorization"/>.</dd>
        </dl>
      </section>

      <section anchor="principal" numbered="true" toc="default">
        <name>Principal</name>
        <t>
          The <tt>principal</tt> object identifies the authorizing human.
          It MUST contain <tt>id</tt> and <tt>id_type</tt>. All other
          fields are OPTIONAL.
        </t>
        <sourcecode type="json"><![CDATA[
{
  "id"             : "usr_alice_opaque",
  "id_type"        : "opaque",
  "display_name"   : "Alice Chen",
  "poh_credential" : "...",
  "metadata"       : {}
}
        ]]></sourcecode>
        <t>
          The <tt>id_type</tt> field MUST be one of the following defined
          values, or a custom string prefixed with <tt>x-</tt>:
        </t>
        <ul spacing="normal">
          <li><tt>opaque</tt>: Application-defined identifier. No resolution
          semantics are implied.</li>
          <li><tt>email</tt>: An email address as defined in
          <xref target="RFC5321"/>.</li>
          <li><tt>uuid</tt>: A UUID as defined in <xref target="RFC9562"/>.</li>
          <li><tt>did</tt>: W3C Decentralized Identifier
          <xref target="W3C.DID"/>. DID resolution is application-
          defined and not required by this protocol.</li>
          <li><tt>poh</tt>: A Proof-of-Humanity credential identifier.
          Verification semantics are application-defined; see
          <xref target="poh"/>.</li>
        </ul>
        <t>
          HDP does not mandate any specific identity model. The <tt>did</tt>
          <tt>id_type</tt> is available for deployments with existing DID
          infrastructure; it is not required.
        </t>
      </section>

      <section anchor="scope" numbered="true" toc="default">
        <name>Scope</name>
        <t>
          The <tt>scope</tt> object records what the human authorized. It
          is signed as part of the root signature and MUST NOT be modified
          after issuance.
        </t>
        <t>
          The <tt>scope</tt> object is a record, not a grant. Its fields
          describe the authorization the human gave at issuance so that
          the record can later be compared with what agents declared
          they did. Nothing in this object confers authority on an agent
          that holds the token (<xref target="what-hdp-is-not"/>).
        </t>
        <sourcecode type="json"><![CDATA[
{
  "intent"               : "Analyze Q1 sales data and report.",
  "authorized_tools"     : ["database_read", "file_write"],
  "authorized_resources" : ["db://sales/q1-2026", "file://reports/"],
  "data_classification"  : "confidential",
  "network_egress"       : false,
  "persistence"          : true,
  "max_hops"             : 3
}
        ]]></sourcecode>
        <t>
          The values above are illustrative. In particular, the
          <tt>max_hops</tt> value shown is an issuer choice for this
          example, not a protocol limit.
        </t>
        <dl spacing="normal" newline="false">
          <dt>intent:</dt>
          <dd>REQUIRED. Natural language description of the authorized task.
          Free-form string. This is the authorization statement, and
          SHOULD be written to be both human- and agent-readable.</dd>
          <dt>authorized_tools:</dt>
          <dd>OPTIONAL. Array of tool identifiers the principal declared
          as authorized. The field records the declaration; it does not
          grant access to the tools named, and enforcement, if any, is
          application-defined.</dd>
          <dt>authorized_resources:</dt>
          <dd>OPTIONAL. Array of resource identifiers (URIs, paths, etc.)
          the principal declared as authorized. As with
          <tt>authorized_tools</tt>, this records the declaration and
          grants nothing.</dd>
          <dt>data_classification:</dt>
          <dd>REQUIRED. One of: <tt>public</tt>, <tt>internal</tt>,
          <tt>confidential</tt>, <tt>restricted</tt>. Expresses the
          sensitivity level of data the agent is authorized to access.</dd>
          <dt>network_egress:</dt>
          <dd>REQUIRED. Boolean. Whether the agent is authorized to make
          outbound network requests.</dd>
          <dt>persistence:</dt>
          <dd>REQUIRED. Boolean. Whether the agent is authorized to write
          persistent state.</dd>
          <dt>max_hops:</dt>
          <dd>OPTIONAL. Positive integer, chosen by the issuer, expressing
          the delegation budget the human authorized for this token.
          An issuer MAY choose any value within the representation bounds
          in <xref target="integer-ranges"/>. HDP defines no fixed
          operational budget. Verification MUST reject tokens whose
          chain length
          exceeds this value. If <tt>max_hops</tt> is absent, HDP places no
          limit on chain length, and delegation depth is governed by
          application policy (see <xref target="chain-rules"/>). Issuers
          SHOULD omit this field unless the delegation budget is itself
          part of what the human declared;
          <xref target="security-max-hops"/> explains why.</dd>
        </dl>
        <t>
          HDP does not mandate a central taxonomy for <tt>intent</tt>,
          <tt>authorized_tools</tt>, or <tt>authorized_resources</tt>.
          These are self-described by the issuer. Semantic validation of
          agent actions against declared scope is an application-layer
          concern.
        </t>
        <t>
          The <tt>authorized_tools</tt> and <tt>authorized_resources</tt>
          arrays are independent lists. HDP v0.1 defines no binding
          between a tool and the resources it may be used on: the example
          above lists two tools and two resources, and nothing in it
          states which tool the principal authorized against which
          resource. Applications MUST NOT infer a per-tool resource
          binding from a v0.1 <tt>scope</tt>. Issuers that need the
          binding recorded SHOULD state it in <tt>intent</tt>, and
          SHOULD list a resource for every tool that acts on one, as
          <xref target="complete-token-example"/> does. A structured
          per-resource permission map is planned for a future version;
          it is a wire-format change and is not part of v0.1.
        </t>
      </section>

      <section anchor="chain" numbered="true" toc="default">
        <name>Chain</name>
        <t>
          The <tt>chain</tt> array is append-only. Each element records a
          single delegation event (hop). The array is empty at issuance and
          grows as the token passes through agents. Agents MUST NOT remove
          or modify existing entries.
        </t>
        <sourcecode type="json"><![CDATA[
{
  "seq"               : 1,
  "agent_id"          : "orchestrator-v2",
  "agent_type"        : "orchestrator",
  "agent_fingerprint" : "sha256:abc123...",
  "timestamp"         : 1711483260000,
  "action_summary"    : "Decompose task; delegate to sub-agents.",
  "parent_hop"        : 0,
  "hop_signature"     : "<base64url-encoded Ed25519 signature>"
}
        ]]></sourcecode>
        <dl spacing="normal" newline="false">
          <dt>seq:</dt>
          <dd>REQUIRED. Positive integer. Sequential index, starting at 1.
          MUST be exactly one greater than the previous hop's seq. Gaps
          in sequence are a protocol violation.</dd>
          <dt>agent_id:</dt>
          <dd>REQUIRED. Identifier of the agent adding this hop. The
          identifier need not be globally meaningful; it is sufficient
          that the delegator which assigned it can interpret it
          (<xref target="minimum-disclosure"/>).</dd>
          <dt>agent_type:</dt>
          <dd>REQUIRED. One of: <tt>orchestrator</tt>, <tt>sub-agent</tt>,
          <tt>tool-executor</tt>, <tt>custom</tt>.</dd>
          <dt>agent_fingerprint:</dt>
          <dd>OPTIONAL. Model or binary fingerprint for the acting agent.</dd>
          <dt>timestamp:</dt>
          <dd>REQUIRED. Unix milliseconds. Time of hop extension, as
          declared by the agent extending the chain. Hop timestamps are
          declared values: the hop signature proves who attested the
          value, not that it is accurate. MUST be greater than or equal
          to the previous hop's <tt>timestamp</tt> (Rule 5 of
          <xref target="chain-rules"/>).</dd>
          <dt>action_summary:</dt>
          <dd>REQUIRED. Description of an action declared by the agent,
          written to be both human- and agent-readable. The description
          MUST distinguish an intended action from an attempted, blocked,
          or observed action whenever that distinction affects its
          interpretation. Out-of-scope attempts and observed violations
          MAY be recorded, with the deviation stated explicitly; their
          inclusion does not imply principal approval. This remains a
          signed declaration, not proof that an action occurred
          (<xref target="security-threat-model"/>).</dd>
          <dt>parent_hop:</dt>
          <dd>REQUIRED. Non-negative integer. Index of the hop that
          triggered this delegation, where 0 indicates the root (human)
          authorization.</dd>
          <dt>hop_signature:</dt>
          <dd>REQUIRED. Base64url-encoded (no padding) Ed25519 signature. See
          <xref target="hop-signing"/>. Absence is a protocol violation
          per Rule 6 of <xref target="chain-rules"/>.</dd>
        </dl>
      </section>

      <section anchor="signature-field" numbered="true" toc="default">
        <name>Signature</name>
        <t>
          The <tt>signature</tt> object carries the root signature computed
          by the issuer.
        </t>
        <sourcecode type="json"><![CDATA[
{
  "kid"   : "alice-signing-key-v1",
  "alg"   : "Ed25519",
  "value" : "<base64url Ed25519 signature over canonical JSON>"
}
        ]]></sourcecode>
        <t>
          The <tt>alg</tt> field MUST be <tt>Ed25519</tt> for HDP v0.1.
          The <tt>kid</tt> field SHOULD be used by verifiers to identify
          the correct public key when multiple keys are in circulation.
        </t>
      </section>
    </section>

    <!-- ================================================================ -->
    <section anchor="cryptographic-signing" numbered="true" toc="default">
      <name>Cryptographic Signing</name>

      <section anchor="root-signing" numbered="true" toc="default">
        <name>Root Signature</name>
        <t>
          The root signature is computed by the issuer at token creation
          time. It covers the token's header, principal, and scope, the
          fields that constitute the human authorization event.
        </t>
        <t>The signing procedure is:</t>
        <ol spacing="normal" type="1">
          <li>
            Construct the unsigned token object containing the
            <tt>hdp</tt>, <tt>header</tt>, <tt>principal</tt>,
            <tt>scope</tt>, and <tt>chain</tt> (empty array at issuance)
            fields.
          </li>
          <li>
            Serialize the object to canonical JSON using RFC 8785
            <xref target="RFC8785"/> (JSON Canonicalization Scheme).
            This ensures deterministic byte representation across
            implementations and platforms.
          </li>
          <li>
            Compute the Ed25519 <xref target="RFC8032"/> signature
            over the canonical JSON bytes using the issuer's private key.
          </li>
          <li>
            Encode the signature bytes as base64url
            <xref target="RFC4648"/> (no padding).
          </li>
          <li>
            Attach the <tt>signature</tt> object (<tt>kid</tt>,
            <tt>alg</tt>, <tt>value</tt>) to the token.
          </li>
        </ol>
        <t>
          The <tt>signature</tt> field itself MUST NOT be included in the
          canonical JSON payload before signing. Because the root signature
          is computed while <tt>chain</tt> is empty, the signed payload is
          deterministically recoverable from a populated token by removing
          the <tt>signature</tt> field, resetting <tt>chain</tt> to an empty
          array, and re-serializing with RFC 8785. The root signature
          therefore covers <tt>hdp</tt>, <tt>header</tt>, <tt>principal</tt>,
          and <tt>scope</tt>; the <tt>chain</tt> is protected by the hop
          signatures (<xref target="hop-signing"/>) rather than by the root
          signature.
        </t>
      </section>

      <section anchor="hop-signing" numbered="true" toc="default">
        <name>Hop Signature</name>
        <t>
          Each hop MUST carry a <tt>hop_signature</tt>. This signature
          binds the new hop record to the entire accumulated delegation
          history and to the root signature, making retroactive chain
          modification detectable.
        </t>
        <t>The hop signing procedure is:</t>
        <ol spacing="normal" type="1">
          <li>
            Construct the new hop record (all fields except
            <tt>hop_signature</tt>).
          </li>
          <li>
            Build the signing payload as a JSON array:
            <tt>[hop_1, hop_2, ..., hop_(n-1), new_hop_unsigned]</tt>
            where <tt>hop_1</tt> through <tt>hop_(n-1)</tt> are the
            previously signed hops (WITH their <tt>hop_signature</tt>
            fields) and <tt>new_hop_unsigned</tt> is the new hop record
            WITHOUT its <tt>hop_signature</tt>.
          </li>
          <li>
            Prepend the root signature value (base64url string) to the
            array as its first element:
            <tt>[root_sig_value, hop_1, ..., new_hop_unsigned]</tt>.
            This chains the hop signature to the root.
          </li>
          <li>
            Serialize the array to canonical JSON per RFC 8785.
          </li>
          <li>
            Compute the Ed25519 signature over the canonical JSON bytes
            using the issuer's private key.
          </li>
          <li>
            Encode as base64url and attach as the <tt>hop_signature</tt>
            field on the new hop record.
          </li>
          <li>
            Append the signed hop to the token's <tt>chain</tt> array.
          </li>
        </ol>
        <t>
          The asymmetry between previously-signed hops (WITH
          <tt>hop_signature</tt>) and the new hop (WITHOUT
          <tt>hop_signature</tt>) in step 2 is intentional and critical.
          The verifier MUST reconstruct this exact payload structure
          when verifying each hop. See <xref target="verification"/>.
        </t>
        <t>
          In HDP v0.1, all signatures (the root signature and every hop
          signature) are produced by the issuer using a single key. An
          extending agent that is not the issuer submits its hop to the
          issuer, which signs it and returns the extended token. Two
          consequences follow, and implementers should weigh both.
        </t>
        <t>
          First, a v0.1 hop signature attests that the issuer recorded a
          delegation claim naming the agent in <tt>agent_id</tt>. It does
          not attest that the named agent consented to, or knew of, the
          hop, because the agent signed nothing. The chain is a record of
          what the issuer recorded, not of what each agent agreed to.
          Deployments in which that distinction matters need per-agent
          signing.
        </t>
        <t>
          Second, the single-key design is practical only where the
          issuer is reachable whenever any agent wishes to extend the
          chain. This adds a round trip to every delegation, and it makes
          delegation across trust domains awkward, since an issuer in one
          domain must sign on behalf of agents in another. Only
          verification is offline; extension is not.
        </t>
        <t>
          The single-key design does not, however, gain anything for
          offline verification that per-agent signing would lose. If each
          hop carried the public key of the agent appending it, signed
          into the chain by that agent's delegator, a verifier would
          authenticate every key after the first from the chain itself
          and would still resolve exactly one key out of band: the
          issuer's. Per-agent hop signing on that pattern is the planned
          extension for a future version. It is not part of v0.1, and
          v0.1 tokens carry no per-agent keys.
        </t>
      </section>

      <section anchor="chain-rules" numbered="true" toc="default">
        <name>Chain Integrity Rules</name>
        <t>The following rules govern chain construction and MUST be
        enforced by both extenders and verifiers:</t>
        <ol spacing="normal" type="1">
          <li>Hop <tt>seq</tt> values MUST start at 1 and increment by
          exactly 1. No gaps are permitted.</li>
          <li>Existing hop records MUST NOT be modified or removed.</li>
          <li>A hop's <tt>parent_hop</tt> MUST reference a valid prior
          hop index (0 for the root human authorization, or the
          <tt>seq</tt> value of a prior hop).</li>
          <li>If <tt>scope.max_hops</tt> is set, the chain length MUST
          NOT exceed it. A token with a full chain MUST NOT be
          extended.</li>
          <li>Each hop's <tt>timestamp</tt> MUST be greater than or equal
          to the <tt>timestamp</tt> of the hop before it. A verifier MUST
          reject a chain in which a hop's <tt>timestamp</tt> is less than
          its predecessor's (Step 4 of <xref target="verification"/>).
          Because the issuer signs every hop in v0.1, all hop timestamps
          pass through one clock domain, which is what makes this rule
          enforceable.</li>
          <li>The <tt>hop_signature</tt> field MUST be present on every
          hop. A hop without a <tt>hop_signature</tt> is a protocol
          violation and MUST cause verification to fail.</li>
        </ol>
      </section>
    </section>

    <!-- ================================================================ -->
    <section anchor="verification" numbered="true" toc="default">
      <name>Verification Pipeline</name>
      <t>
        For live acceptance, a verifier MUST first validate the input
        as specified in <xref target="token-structure"/>, then execute
        the following seven steps in order. A failure at any step MUST
        cause immediate rejection for live use with an appropriate error;
        the live acceptance pipeline MUST NOT proceed to subsequent
        steps. Historical audit is a separate procedure defined in
        <xref target="historical-audit"/>. Rejecting live use does not
        prohibit that procedure from examining the same record.
      </t>

      <ol spacing="normal" type="1">
        <li>
          <strong>Version check.</strong>
          The <tt>hdp</tt> field MUST contain a recognized protocol
          version string. For this specification, the only recognized
          value is <tt>"0.1"</tt>. The <tt>header.version</tt> field MUST
          equal the <tt>hdp</tt> field; a mismatch MUST cause rejection.
          A verifier MAY reject a version it no longer supports.
        </li>
        <li>
          <strong>Lifecycle check.</strong>
          The current time MUST be greater than or equal to
          <tt>header.issued_at</tt> and strictly less than
          <tt>header.expires_at</tt>. A token outside that interval
          MUST be rejected for live use. The verifier MUST also consult
          its local revocation state (<xref target="security-revocation"/>)
          and MUST reject live use if <tt>header.token_id</tt> is
          present there.
        </li>
        <li>
          <strong>Root signature verification.</strong>
          Reconstruct the canonical JSON payload by removing the
          <tt>signature</tt> field and resetting <tt>chain</tt> to an empty
          array (its value when the root signature was computed), then
          serializing the remaining token object per RFC 8785. Verify that
          <tt>signature.alg</tt> is <tt>Ed25519</tt>, then verify the
          signature in <tt>signature.value</tt> against this payload using
          the issuer's public key. A failure indicates tampering with the
          header, principal, or scope.
        </li>
        <li>
          <strong>Hop sequence and structure integrity.</strong>
          For each hop in <tt>chain</tt>, verify that
          <tt>hop.seq == (index + 1)</tt>; any gap or duplication MUST
          cause rejection. Verify that each hop's <tt>parent_hop</tt>
          references either 0 (the root authorization) or the <tt>seq</tt>
          of a prior hop; an out-of-range <tt>parent_hop</tt> MUST cause
          rejection (Rule 3 of <xref target="chain-rules"/>). Verify that
          each hop's <tt>timestamp</tt> is greater than or equal to that
          of the hop before it; a decrease MUST cause rejection (Rule 5
          of <xref target="chain-rules"/>).
        </li>
        <li>
          <t><strong>Hop signature verification.</strong>
          For each hop at index <tt>i</tt>:</t>
          <ol spacing="normal" type="a">
            <li>Verify that <tt>hop_signature</tt> is present. Absence
            MUST cause rejection.</li>
            <li>Reconstruct the signing payload as described in
            <xref target="hop-signing"/>, using the hops at indices
            0...(i-1) with their signatures, plus the hop at index
            <tt>i</tt> without its <tt>hop_signature</tt>, prepended
            by the root signature value.</li>
            <li>Serialize the payload per RFC 8785 and verify the
            <tt>hop_signature</tt> against the issuer's public key
            (the same key used for the root signature in HDP v0.1).</li>
          </ol>
        </li>
        <li>
          <strong>max_hops check.</strong>
          If <tt>scope.max_hops</tt> is defined, the length of
          <tt>chain</tt> MUST NOT exceed it.
        </li>
        <li>
          <strong>Session binding check.</strong>
          The token's <tt>header.session_id</tt> MUST exactly match the
          <tt>session_id</tt> provided by the verifying application. This
          prevents token replay across sessions. See
          <xref target="security-replay"/>.
        </li>
      </ol>

      <t>
        An optional eighth step MAY be performed if the application has
        registered a Proof-of-Humanity verifier: if
        <tt>principal.poh_credential</tt> is present and a verifier
        callback is configured, the credential MUST be validated by that
        callback. See <xref target="poh"/>. The callback runs last
        because it is application-defined and may be remote, costly, or
        side-effecting. Ordering it after Steps 1 through 7 keeps those
        steps offline and ensures that no external verifier is invoked
        for a token that fails its cryptographic checks.
      </t>

      <t>
        Verification is fully offline. Steps 1 through 7 require only the
        issuer's Ed25519 public key, the current session identifier, the
        current time (for the expiry check), and the verifier's own
        revocation state (for the lifecycle check). No network call,
        registry lookup, or third-party contact is required at any step.
      </t>
      <t>
        A token that passes all seven steps is authentic and intact: its
        header, principal, and scope are as the issuer signed them, and
        every recorded hop is as the issuer recorded it. Passing
        verification establishes nothing about whether the presenter may
        perform any action. That determination is made by the
        application's own authorization mechanism, to which the verified
        token is an input (<xref target="what-hdp-is-not"/>).
      </t>

      <section anchor="historical-audit" numbered="true" toc="default">
        <name>Historical Audit Verification</name>
        <t>
          An auditor MUST be able to examine an expired or revoked token
          without treating it as acceptable for a new request. Audit
          tooling MUST report the following results separately. These are
          verification results, not new fields in an HDP token:
        </t>
        <dl spacing="normal" newline="false">
          <dt>Record integrity:</dt>
          <dd>Whether the record conforms to the format and its root and
          hop signatures verify. Apply the input validation in
          <xref target="token-structure"/> and Steps 1, 3, 4, 5, and 6
          of <xref target="verification"/>, using a trusted archived
          issuer key. Failure of one of these checks MUST NOT be reported
          as valid integrity. Expiry and revocation do not invalidate the
          signature mathematics; they are reported separately. If the key
          or supported verification algorithm is unavailable, integrity is
          unverified rather than valid.</dd>
          <dt>Current acceptance:</dt>
          <dd>Whether the live acceptance pipeline succeeds now. It MAY
          be reported as not evaluated when no current request or session
          exists. Successful integrity verification MUST NOT be used as a
          substitute for live acceptance.</dd>
          <dt>Historical acceptance:</dt>
          <dd>Whether evidence establishes acceptance conditions at a
          particular verifier and time. The auditor MUST identify that
          verifier and evaluation time, check the recorded session context
          using Step 7, check that the time is within the token's signed
          issuance and expiry interval, and evaluate the revocation state
          and any additional acceptance policy applicable there at that
          time. A positive result MUST require valid record integrity and
          authenticated evidence bound to the token and evaluation context.
          Missing evidence MUST produce an indeterminate result,
          not a claim that the token was historically accepted.</dd>
        </dl>
        <t>
          Historical evidence SHOULD include an authenticated receipt or
          integrity-protected verifier log binding the complete token
          digest (<xref target="token-by-reference"/>), the observed
          request or event, session identifier, verifier identity, time,
          decision, and relevant revocation and policy state. Any required
          Proof-of-Humanity result belongs in that evidence; a credential
          check performed today is not evidence of its status then. A
          declared hop timestamp alone is not trusted time evidence, and
          an empty current revocation set does not establish past status.
          These records are application-layer artifacts whose encoding is
          outside HDP v0.1. They can be retained and checked offline.
        </t>
        <t>
          Historical acceptance describes the identified verifier's
          decision and available state; it does not establish global
          revocation freshness, that an action occurred, or that the
          human authorized that particular action. Applications requiring
          historical audit SHOULD retain the tokens, trusted public keys,
          session context, and evidence for their audit retention period,
          even after the tokens expire. Key-compromise information and
          applicable policy MUST qualify any conclusions drawn from a
          mathematically valid signature.
        </t>
      </section>

    </section>

    <!-- ================================================================ -->
    <section anchor="reauthorization" numbered="true" toc="default">
      <name>Re-Authorization</name>
      <t>
        Long-running or streaming sessions may exhaust the <tt>max_hops</tt>
        limit, require scope expansion, or encounter situations where a
        high-risk action warrants fresh human confirmation. In these cases,
        the issuer (acting on behalf of the human principal) issues a new
        token that supersedes the original.
      </t>
      <t>
        Re-authorization is indicated by setting
        <tt>header.parent_token_id</tt> to the <tt>token_id</tt> of the
        token being superseded. This field MUST be set before computing the
        root signature, so the parentage link is cryptographically covered
        by the new token's root signature.
      </t>
      <t>
        A re-authorized token:
      </t>
      <ul spacing="normal">
        <li>Has a new <tt>token_id</tt>, <tt>issued_at</tt>, and
        <tt>expires_at</tt>.</li>
        <li>Inherits <tt>session_id</tt>, <tt>principal</tt>, and
        <tt>scope</tt> from the original unless explicitly overridden.</li>
        <li>Starts with an empty <tt>chain</tt> (delegation count
        resets).</li>
        <li>Records <tt>parent_token_id</tt> pointing to the original,
        creating an auditable lineage of scope evolution.</li>
      </ul>
      <t>
        Verifiers that require re-authorization chain traversal SHOULD
        retain all tokens in a session and verify the full
        <tt>parent_token_id</tt> linkage.
      </t>
      <t>
        Re-authorization is a lineage mechanism, not a revocation
        mechanism. Issuing a superseding token does not invalidate the
        token it supersedes: the original remains eligible for live
        acceptance until its <tt>expires_at</tt> unless revoked, and
        verifiers are not notified that it has been superseded. Both
        records remain available for historical integrity verification
        (<xref target="historical-audit"/>). An issuer that requires
        the superseded token to stop being honoured MUST revoke its <tt>token_id</tt> at the
        verifiers concerned (<xref target="security-revocation"/>), in
        addition to issuing the replacement.
      </t>
    </section>

    <!-- ================================================================ -->
    <section anchor="multi-principal" numbered="true" toc="default">
      <name>Multi-Principal Delegation</name>
      <t>
        HDP v0.1 supports one principal per token. Joint authorization
        by multiple humans is achieved by sequential chaining: Human A
        issues token T1; Human B issues token T2 with
        <tt>parent_token_id</tt> equal to T1's <tt>token_id</tt>.
        Each token is independently signed with its issuer's key.
      </t>
      <t>
        To verify a multi-principal chain, the verifier MUST:
      </t>
      <ol spacing="normal" type="1">
        <li>Verify each token individually against its issuer's public
        key using the live acceptance pipeline, or historical audit
        verification when examining past records.</li>
        <li>Verify that <tt>T[i].header.parent_token_id == T[i-1].header.token_id</tt>
        for all i &gt; 0.</li>
        <li>Verify that all tokens in the chain share the same
        <tt>session_id</tt>.</li>
        <li>Obtain trusted application context that identifies each
        parent-child relationship as joint authorization, as described
        below. Without that context, report linked records with an
        unknown relationship, not established joint authorization.</li>
      </ol>
      <t>
        This pattern provides joint authorization auditably without
        requiring a threshold signature scheme. Each principal's
        authorization is a distinct signed artifact. A future version
        of HDP (v0.2) is planned to introduce simultaneous multi-
        signature primitives using threshold signature schemes.
      </t>
      <t>
        An alternative to chaining is composition: each principal issues
        an independent token, and the verifier's policy requires that
        both be presented. Composition is more general and composes
        further downstream, and a verifier MAY adopt it. Chaining is
        specified here because T2 signs a reference to T1, making the
        linkage part of the record. The link alone does not state that
        the authorizations were conjunctive or approved the same action;
        that meaning requires the application context below. Composition
        can also provide auditable evidence when an authenticated receipt
        binds both token digests to the request and the policy requiring
        them. Without such retained context, neither a bare parent link
        nor two independent tokens establishes joint approval.
      </t>
      <t>
        The <tt>parent_token_id</tt> field thus serves two distinct
        purposes: supersession, where a re-authorized token replaces an
        earlier one (<xref target="reauthorization"/>), and joint
        authorization, where both the parent and child tokens remain valid
        (this section). HDP v0.1 does not tag which relationship a given
        <tt>parent_token_id</tt> expresses. Applications MUST obtain its
        meaning from trusted, explicit context, such as an authenticated
        issuance record identifying the parent, child, and relationship
        type. Expiry, revocation, principal equality, and session equality
        alone MUST NOT be used to infer that meaning: a superseded token
        can remain valid, and a joint-authorization token can later expire
        or be revoked. Applications requiring audit MUST retain this
        context, with integrity protection and a binding to each token's
        issuer public key and root signature, alongside the tokens. This
        binding remains stable as the chains are extended. In its absence,
        auditors MUST report the relationship as unknown. A future version may
        add an explicit relationship type. Note also
        that a superseded token's <tt>session_id</tt> MAY be overridden on
        re-authorization, whereas the tokens in a joint-authorization chain
        MUST share one <tt>session_id</tt>.
      </t>
    </section>

    <!-- ================================================================ -->
    <section anchor="transport" numbered="true" toc="default">
      <name>Transport</name>
      <t>
        The HTTP header field names defined below do not use the "X-"
        prefix, in accordance with <xref target="RFC6648"/>.
      </t>

      <section anchor="http-header" numbered="true" toc="default">
        <name>HTTP Header: HDP-Token</name>
        <t>
          HDP tokens MAY be transmitted in HTTP requests and responses
          using the <tt>HDP-Token</tt> header. The header value is the
          base64url encoding (RFC 4648, no padding) of the UTF-8
          JSON serialization of the complete token object.
        </t>
        <figure anchor="http-header-example">
          <name>HDP-Token HTTP Header Example</name>
          <artwork type="http-message"><![CDATA[
POST /api/task HTTP/1.1
Host: agent.example.com
HDP-Token: eyJoZHAiOiIwLjEiLCJoZWFkZXIiOnsi...
Content-Type: application/json
          ]]></artwork>
        </figure>
        <t>
          Implementations MUST NOT include tokens in URL query parameters,
          as this exposes sensitive data in server logs and browser history.
        </t>
        <t>
          A token accompanies a request because the task it records
          travels in that request. Its presence does not authorize the
          request (<xref target="what-hdp-is-not"/>). The receiving
          service decides whether to act by its own means and MAY use
          the verified token as an input to that decision.
        </t>
        <t>
          HTTP header values are routinely written to access logs, proxy
          logs, and error reports, and the <tt>HDP-Token</tt> value
          contains the <tt>principal</tt> object and the full chain.
          Deployments SHOULD configure logging to treat
          <tt>HDP-Token</tt> as sensitive, as they would an
          <tt>Authorization</tt> header.
        </t>
      </section>

      <section anchor="token-by-reference" numbered="true" toc="default">
        <name>Token by Reference: HDP-Token-Ref</name>
        <t>
          When token size is a concern (e.g., large chains), the token
          MAY be stored server-side and referenced using the
          <tt>HDP-Token-Ref</tt> header. The reference is either the
          token's <tt>token_id</tt>, or a content-addressed reference:
          the string <tt>sha256:</tt> followed by the base64url encoding
          (no padding) of the SHA-256 digest <xref target="RFC6234"/> of
          the token's canonical JSON serialization per RFC 8785.
        </t>
        <t>
          A recipient resolving a content-addressed reference MUST
          validate the resolved token's input representation, serialize
          the complete token (including <tt>signature</tt> and all hop
          signatures) with RFC 8785, encode the result as UTF-8, compute
          SHA-256, and compare the digest with the reference. The digest
          in the reference MUST be exactly 32 bytes encoded as canonical
          unpadded base64url; malformed encodings or a digest mismatch
          MUST cause rejection. The comparison commits to canonical JSON,
          not to whitespace or member ordering in the stored serialization.
          For a UUID reference, the resolved <tt>header.token_id</tt>
          MUST identify the same UUID; equality is determined by the
          UUID's 128-bit value, not hexadecimal letter case. The recipient
          MUST reject a mismatch. Successful reference resolution MUST
          be followed by live acceptance or historical audit verification
          as appropriate; a valid signature alone does not establish that
          the requested reference was resolved correctly.
        </t>
        <figure anchor="token-ref-example">
          <name>HDP-Token-Ref HTTP Header Example</name>
          <artwork type="http-message"><![CDATA[
POST /api/task HTTP/1.1
Host: agent.example.com
HDP-Token-Ref: 550e8400-e29b-41d4-a716-446655440000
          ]]></artwork>
        </figure>
        <t>
          Implementations using token-by-reference MUST secure the
          token store and use transport-layer security (TLS) for all
          reference resolution. The store MUST be write-once per
          reference: once a reference resolves to a token, it MUST NOT
          later resolve to a different one. Here, sameness means an
          identical complete canonical JSON token, not an identical
          <tt>token_id</tt> alone. A UUID reference therefore identifies
          one immutable snapshot, optionally the final record. It MUST
          NOT be used as a mutable pointer to the latest chain. Because
          extension preserves <tt>token_id</tt>, subsequent snapshots
          MUST use new content-addressed references when transported by
          reference; the previous UUID mapping remains unchanged.
        </t>
        <t>
          The write-once requirement exists because a reference by
          <tt>token_id</tt> is a substitution point. A different but
          validly signed token stored under the same <tt>token_id</tt>
          passes every step of the verification pipeline and presents
          the wrong provenance. Session binding narrows the set of tokens
          that could be substituted but does not eliminate it. A
          content-addressed reference removes the substitution point,
          when the recipient performs the required digest check, and SHOULD be
          preferred where the resolving party does not control the
          store. A content-addressed reference changes each time the
          chain is extended, which is the intended behaviour: each
          extension is a different record.
        </t>
      </section>

      <section anchor="key-distribution" numbered="true" toc="default">
        <name>Key Distribution: Well-Known Endpoint</name>
        <t>
          Issuers that wish to publish their Ed25519 public keys for
          automated discovery SHOULD serve a JSON document at
          <tt>/.well-known/hdp-keys.json</tt> with the following
          structure:
        </t>
        <sourcecode type="json"><![CDATA[
{
  "keys": [
    {
      "kid" : "alice-signing-key-v1",
      "alg" : "Ed25519",
      "pub" : "<base64url-encoded 32-byte Ed25519 public key>"
    }
  ]
}
        ]]></sourcecode>
        <t>
          This endpoint is a discovery convenience only. It is not part
          of verification, which takes the issuer's public key as an
          input and remains fully offline
          (<xref target="security-offline"/>). A verifier that has
          obtained the key by other means has no reason to consult it.
        </t>
        <t>
          This format is intentionally minimal. Implementations MAY
          extend it with additional metadata. The <tt>alg</tt> field
          MUST be <tt>"Ed25519"</tt> for HDP v0.1 keys. Consumers MUST
          reject entries with unrecognized <tt>alg</tt> values.
          Consumers MUST validate that the decoded public key is
          exactly 32 bytes.
        </t>
      </section>
    </section>

    <!-- ================================================================ -->
    <section anchor="privacy" numbered="true" toc="default">
      <name>Privacy Considerations</name>

      <section anchor="minimum-disclosure" numbered="true" toc="default">
        <name>Minimum-Disclosure Principal Fields</name>
        <t>
          The <tt>principal</tt> object may contain PII (email address,
          display name). Issuers SHOULD apply the principle of minimum
          disclosure when constructing tokens that will traverse multiple
          agents. Specifically:
        </t>
        <ul spacing="normal">
          <li>Use <tt>id_type: "opaque"</tt> with an application-internal
          identifier rather than embedding the user's email address in
          tokens that will be sent to third-party agents.</li>
          <li>Omit <tt>display_name</tt> when the receiving agent does not
          require a human-readable identity.</li>
        </ul>
        <t>
          The token structure separates the identity fields
          (<tt>principal</tt>) from the audit-relevant fields
          (<tt>header</tt>, <tt>scope</tt>, <tt>chain</tt>). Implementations
          MAY strip the <tt>principal</tt> object when forwarding tokens
          to agents that do not require principal identity, while preserving
          the integrity of the signature chain. Note that stripping
          <tt>principal</tt> invalidates the root signature; stripped tokens
          MUST be clearly marked as audit-only records and MUST NOT be
          presented for signature verification.
        </t>
        <t>
          The same principle applies to the <tt>agent_id</tt> field in hop
          records (<xref target="chain"/>). An <tt>agent_id</tt> need not
          be meaningful to anyone but the delegator that assigned it.
          This is sufficient because accountability in a delegation
          chain is recursive: a delegator is responsible for how its
          direct delegate uses the delegation, even when the use occurred
          further down the chain, and that delegate is in turn
          responsible for its own direct delegate. A verifier or auditor
          therefore never needs to resolve an <tt>agent_id</tt>
          globally. It needs the delegator at each step to be able to
          identify the party it delegated to, and the <tt>agent_id</tt>
          and its <tt>action_summary</tt> are bound into the signed chain
          for exactly that purpose.
        </t>
        <t>
          Which identifier to use is context dependent, and HDP does not
          prescribe one. Non-exhaustively: a widely known identifier,
          such as an enterprise employee or service number, suits
          deployments where correlation is not a concern; an identifier
          meaningful only to the delegator suits deployments where an
          observer must be prevented from correlating requests across
          chains; a DID (<xref target="W3C.DID"/>) suits deployments
          where a trusted authority exists to assert claims about it. An
          issuer or extending agent MAY use a fresh identifier for every
          delegation.
        </t>
        <t>
          HDP v0.1 offers no field-level confidentiality: a token is
          either presented whole for verification or stripped and marked
          audit-only, as above. Encrypting <tt>principal</tt> fields is
          not specified, because the keys in circulation are Ed25519
          signing keys rather than encryption keys and because the set
          of verifiers is deliberately open, so there is no defined
          party to encrypt to. Selective disclosure of principal fields
          and of individual hops, which would allow a token to be
          verified with parts withheld, is planned for a future version.
        </t>
      </section>

      <section anchor="gdpr" numbered="true" toc="default">
        <name>Data Retention and the Right to Erasure</name>
        <t>
          HDP tokens may constitute personal data under applicable privacy
          regulations (e.g., GDPR Article 4(1)) when the
          <tt>principal.id</tt> or <tt>principal.display_name</tt> fields
          contain directly or indirectly identifying information.
        </t>
        <t>
          Implementations SHOULD:
        </t>
        <ul spacing="normal">
          <li>Store tokens with explicit retention periods derived from
          <tt>header.expires_at</tt>.</li>
          <li>Provide deletion mechanisms that remove stored tokens
          upon erasure requests.</li>
          <li>Use opaque identifiers in <tt>principal.id</tt> where
          possible, maintaining a separate mapping that can be
          destroyed independently of the token audit log.</li>
        </ul>
        <t>
          Encrypting stored tokens does not by itself discharge an
          erasure obligation, since the ciphertext remains personal data
          for as long as the key exists. Destroying the key
          (crypto-shredding) is a recognised technique for rendering
          retained tokens unreadable and MAY be used together with the
          mapping-destruction approach above.
        </t>
      </section>

      <section anchor="poh" numbered="true" toc="default">
        <name>Proof of Humanity</name>
        <t>
          The optional <tt>principal.poh_credential</tt> field MAY carry
          a credential attesting that the principal is a human (e.g., a
          Worldcoin World ID proof, a CAPTCHA session token, or a
          biometric attestation identifier). The HDP protocol does not
          define the semantics of this field; verification is entirely
          application-defined.
        </t>
        <t>
          When a PoH verifier is configured, the verification pipeline
          MUST validate the credential as the final step (after session
          binding) and MUST reject the token if validation fails. The
          verifier callback SHOULD be idempotent and SHOULD NOT have
          side effects. <xref target="verification"/> explains why the
          callback is ordered last.
        </t>
      </section>
    </section>

    <!-- ================================================================ -->
    <section anchor="security-considerations" numbered="true" toc="default">
      <name>Security Considerations</name>

      <section anchor="security-threat-model" numbered="true" toc="default">
        <name>Threat Model</name>
        <t>
          HDP is designed to provide provenance and tamper evidence, not
          runtime enforcement. An agent that exceeds its declared scope
          is still a bad actor; HDP creates an evidence trail, not a
          capability boundary. Applications requiring runtime enforcement
          MUST implement it at the application layer using the HDP token
          as audit input. HDP is not an authorization protocol
          (<xref target="what-hdp-is-not"/>); the properties discussed
          below are properties of the record: who could have produced
          it, whether it has been altered, and what it does and does not
          establish.
        </t>
      </section>

      <section anchor="security-forgery" numbered="true" toc="default">
        <name>Token Forgery</name>
        <t>
          A forged token (one whose <tt>header</tt>, <tt>principal</tt>,
          or <tt>scope</tt> fields do not match the original issuance) will
          fail Step 3 of the verification pipeline (root signature check).
          The security of this step relies on the unforgeability of Ed25519
          signatures and the collision resistance of SHA-512 (used
          internally by Ed25519). An attacker who does not possess the
          issuer's private key cannot produce a valid root signature for
          a modified token.
        </t>
      </section>

      <section anchor="security-chain-tampering" numbered="true" toc="default">
        <name>Chain Tampering</name>
        <t>
          Modification, reordering, or removal of any non-trailing hop is
          detectable: it either breaks the hop sequence check (Step 4) or
          invalidates the hop signatures of all subsequent hops (Step 5),
          because each hop signature covers all previous hops and the root
          signature. Insertion of a fabricated hop will similarly fail
          unless the attacker possesses the issuer's private key. Removal of
          one or more trailing hops is a distinct case that these checks do
          not detect; see <xref target="security-truncation"/>.
        </t>
      </section>

      <section anchor="security-truncation" numbered="true" toc="default">
        <name>Chain Truncation and Completeness</name>
        <t>
          Each hop signature covers only the hops that precede it and the
          root signature. Consequently, deleting one or more hops from the
          end of the <tt>chain</tt>, or presenting an earlier and shorter
          copy of a token, yields a token that still passes every step of
          the verification pipeline. HDP therefore provides tamper evidence
          for the hops that are present, but does not by itself prove that
          the chain is complete.
        </t>
        <t>
          Relatedly, a non-cooperating or compromised agent can decline to
          append a hop for an action it takes; HDP records declared
          delegation actions and cannot compel an agent to record one. HDP
          is an evidence trail, not an enforcement mechanism
          (<xref target="security-threat-model"/>).
        </t>
        <t>
          A verifier that can authenticate the presenter (for example,
          because the transport identifies the calling agent) SHOULD
          require that the final hop's <tt>agent_id</tt> correspond to
          that presenter. This is cheap and closes one truncation case:
          a third party holding a shorter, earlier copy of the token
          cannot present it, because the final hop of that copy names
          someone else. Capability systems impose the same requirement;
          UCAN Invocation requires the delegation chain to end at the
          invoker, and a ZCAP-LD invocation proof is rooted in the
          invoker's key.
        </t>
        <t>
          The presenter check does not make the chain complete. In a
          capability chain, truncation gains an attacker nothing beyond
          what the presenter check catches, because authority only
          narrows toward the tail: a truncated prefix is usable only by
          the delegatee of its last remaining hop, who holds that
          authority legitimately. HDP hops record actions, not grants,
          and there is no attenuation; a truncated chain carries the full
          original <tt>scope</tt>. The case HDP must consider is an
          intermediate agent that deletes the hops appended after its
          own, in order to hide what its sub-agents did. After
          truncation that agent genuinely is the presenter, and the
          presenter check passes.
        </t>
        <t>
          Concurrent extensions from the same prefix can produce two
          valid branches with the same <tt>token_id</tt>, hop count,
          and final <tt>agent_id</tt>, but different recorded actions.
          A hop count or presenter check cannot distinguish them. The
          signature pipeline verifies the supplied branch; it does not
          discover other branches or select a uniquely final one.
        </t>
        <t>
          Deployments that require one linear record per token MUST
          serialize extensions at the issuer. The issuer MUST atomically
          check that the submitted prefix matches its accepted chain head
          and advance that head when committing an extension. A stale
          prefix MUST be rejected for reconciliation against the current
          head. An already signed hop cannot simply be transplanted onto
          another branch; extending the reconciled prefix requires a new
          signature. Retries SHOULD return an already committed result
          when the application identifies the same extension request.
          Deployments that intentionally allow branching MUST retain and
          identify the branches separately and define how their audit
          process accounts for them. HDP v0.1 defines no branch merge
          operation. Issuer serialization is state used for construction,
          not a network dependency of verification.
        </t>
        <t>
          Applications requiring evidence of a particular observed or
          final record SHOULD retain an authenticated receipt or
          settlement record binding the <tt>token_id</tt>,
          <tt>session_id</tt>, complete token digest as defined in
          <xref target="token-by-reference"/>, observation time, and
          observing party. It MUST distinguish an observed snapshot from
          a claimed final record. A verifier relying on that receipt MUST
          validate its authenticity and compare the token digest. A hop
          count MAY be included for diagnostics but MUST NOT be treated
          as a substitute for the digest. The receipt establishes which
          branch was observed or finalized under the application's policy;
          it does not prove that no unrecorded action or undisclosed
          branch exists. Off-record delegation remains a separate
          limitation (<xref target="security-max-hops"/>). These
          receipts are application-layer artifacts, not new token fields.
        </t>
      </section>

      <section anchor="security-replay" numbered="true" toc="default">
        <name>Replay Attack Defense</name>
        <t>
          HDP provides two orthogonal replay defenses:
        </t>
        <ol spacing="normal" type="1">
          <li><strong>Expiry.</strong> Every token carries an
          <tt>expires_at</tt>. An expired token is rejected at Step 2
          regardless of network conditions.</li>
          <li><strong>Session binding.</strong> The token carries the
          <tt>session_id</tt> established out-of-band between issuer
          and verifier. A token is valid only within the session for
          which it was issued. Even a non-expired token cannot be
          replayed across sessions.</li>
        </ol>
        <t>
          Together, these defenses ensure that a stolen token is useful
          to an attacker only within the original session and only until
          it expires or is revoked (<xref target="security-revocation"/>).
        </t>
        <t>
          HDP specifies no default lifetime, deliberately. Expiry alone
          forces a choice between tokens that lapse just before they are
          needed and tokens that outlive a detected compromise, and the
          tendency in deployed systems is for lifetimes to lengthen over
          time as the first kind of failure accumulates operational
          friction. Issuers SHOULD choose the shortest lifetime the task
          permits, and SHOULD rely on revocation rather than on long
          lifetimes to avoid disruption, since revocation is what bounds
          the exposure of a compromised token regardless of the lifetime
          it was issued with.
        </t>
        <t>
          Session binding says nothing about replay of the same token
          within its session. Whether a presenter may present one token
          for two requests is an application-layer question on which
          HDP takes no position. Applications for which it matters
          SHOULD record the requests each token has accompanied, for
          example by retaining a hash of each request until the token
          expires, and reject repeats.
        </t>
        <t>
          Because <tt>session_id</tt> anchors the session-binding defense,
          it SHOULD be unguessable: issuers SHOULD generate
          <tt>session_id</tt> values with at least 128 bits of entropy from
          a cryptographically secure random source. A predictable
          <tt>session_id</tt> weakens replay protection.
        </t>
      </section>

      <section anchor="security-revocation" numbered="true" toc="default">
        <name>Revocation</name>
        <t>
          A verifier MUST support being instructed to stop honouring a
          token. The instruction identifies the token by
          <tt>header.token_id</tt>; the verifier records that identifier
          in local revocation state and thereafter rejects the token at
          Step 2 of the live acceptance pipeline
          (<xref target="verification"/>). Revocation MUST NOT prevent
          separate historical integrity verification
          (<xref target="historical-audit"/>). No central registry, no
          publication mechanism, and no network access at verification
          time are involved. The revocation state is held by the
          verifier, as the <tt>session_id</tt> already is, and
          verification remains fully offline
          (<xref target="security-offline"/>).
        </t>
        <t>
          HDP does not specify who may revoke, how the instruction
          reaches the verifier, or the retention period for revocation
          evidence; these are verifier policy. Retaining an entry until
          the corresponding token's <tt>expires_at</tt> is sufficient
          for live rejection, since the token is rejected on expiry
          thereafter. Historical audit may require longer retention of
          revocation events and effective times, as described in
          <xref target="historical-audit"/>. The range of
          reasonable policies is illustrated by existing capability
          systems: UCAN allows a delegator to revoke and makes the right
          to revoke itself delegable, and ZCAP-LD allows any delegator in
          a chain to revoke what it delegated.
        </t>
        <t>
          Some designs obtain bounded revocation freshness differently,
          by requiring the verifier to fetch a short-lived status
          assertion from the issuer before honouring a token. HDP does
          not, because that makes every verification depend on the
          issuer being reachable. The trade is deliberate: HDP keeps
          verification offline and leaves the freshness of revocation
          state to whoever populates it.
        </t>
        <t>
          Revocation is per token, not per hop. There is no mechanism to
          revoke authorization for a single delegate in the middle of an
          otherwise valid chain while leaving the token valid; the token
          is revoked and, if the task is to continue, re-authorized
          (<xref target="reauthorization"/>). Deployments that require
          per-delegate revocation SHOULD layer a capability system that
          supports cascade revocation at the application layer.
          Retaining accountability for each delegate (for example
          through distinct per-hop identifiers,
          <xref target="minimum-disclosure"/>) is what makes such
          application-layer revocation actionable.
        </t>
        <t>
          A consequence of any revocation mechanism is that proof an
          action was authorized is not, by itself, proof that the
          authorization was still current when the action was taken. An
          auditor reading a token after the fact cannot tell from the
          token whether it had been revoked at a verifier; that
          information lives in the verifier's state and SHOULD be
          retained alongside stored tokens where audit requires it.
        </t>
      </section>

      <section anchor="security-max-hops" numbered="true" toc="default">
        <name>Delegation Budgets and Off-Record Delegation</name>
        <t>
          The <tt>scope.max_hops</tt> field (<xref target="scope"/>)
          creates an incentive that works against the purpose of this
          protocol, and issuers need to understand it before setting the
          field. When an application gates actions on a valid chain and
          the hop budget is exhausted, an agent that still needs to
          delegate has two options: seek re-authorization
          (<xref target="reauthorization"/>), or delegate without
          appending a hop. The second is off-record delegation. It
          produces a chain that verifies, an action that occurred, and no
          record connecting them, which is the worst outcome a
          provenance protocol can produce. A limit meant to constrain
          delegation instead constrains the recording of it.
        </t>
        <t>
          The usual motivation for limiting delegation depth is to bound
          the cost of verifying, storing, or reasoning about long chains.
          That is a verifier concern and belongs at the verifier: a
          verifier MAY reject or flag chains longer than a locally
          configured limit, as a heuristic it controls and can adjust
          without reissuing tokens. Placing the limit in the token binds
          every verifier to a number chosen at issuance and hands the
          incentive above to every agent that carries the token.
        </t>
        <t>
          Accordingly, issuers SHOULD omit <tt>max_hops</tt> unless the
          delegation budget is itself part of what the human declared
          and recording it has evidentiary value. Where the field is set,
          applications SHOULD make re-authorization readily available to
          agents that exhaust it, so that the honest path is not more
          costly than the off-record one. The field is retained in v0.1
          because it is optional and because, where a human did declare
          a budget, the declaration is provenance.
        </t>
      </section>

      <section anchor="security-attribution" numbered="true" toc="default">
        <name>Attribution Across Concurrent Tokens</name>
        <t>
          An agent may hold more than one valid HDP token whose
          <tt>scope</tt> covers the same resource: for example, one
          issued for Alice authorizing a read of a dataset and one issued
          for Carol authorizing an update to it. Applications MUST bind
          an action or attempted action to the task and token that
          actually triggered it, and agents MUST record it under that
          context. They MUST NOT select a different token merely because
          its scope would make the action appear authorized. A deviation
          from the triggering token's scope SHOULD be recorded
          under that token, explicitly identified as an attempted,
          blocked, or observed violation in <tt>action_summary</tt>.
          Recording the deviation does not amend scope or assert that
          the principal approved it. If the triggering context is unknown,
          the application MUST preserve that uncertainty in its audit
          record rather than assign an unrelated principal.
        </t>
        <t>
          HDP cannot detect a violation of this rule. A hop appended to
          the wrong token verifies at every step of the pipeline, because
          the pipeline establishes that the hop was recorded, not that it
          was recorded in the right place. The consequence is borne at
          audit: an update performed in Carol's task but recorded under
          Alice's token misattributes the triggering context and leaves
          Carol's token silent. Conversely, an update that actually
          occurred in Alice's read-only task belongs in Alice's task
          record as a violation; it MUST NOT be moved to Carol's token
          to make it appear permitted. A signed record alone cannot prove
          correct task attribution, and inclusion of an action MUST NOT
          be interpreted as proof that the principal approved it.
        </t>
        <t>
          Where more than one task could legitimately initiate an
          action, selecting the initiating task is application policy.
          Applications SHOULD define and record that choice before
          execution, together with a request or event identifier. Once
          selected, the triggering context governs provenance even if
          the action deviates from its scope. Multi-principal
          delegation (<xref target="multi-principal"/>) does not address
          this case: it covers tokens linked by <tt>parent_token_id</tt>
          that share a <tt>session_id</tt>, and the tokens here are
          unrelated. The neighbouring question of how a service decides
          which of several grants applies to a request is an
          authorization-layer question and is outside HDP
          (<xref target="what-hdp-is-not"/>).
        </t>
      </section>

      <section anchor="security-prompt-injection" numbered="true" toc="default">
        <name>Prompt Injection</name>
        <t>
          Prompt injection attacks attempt to cause an agent to act as if
          it received instructions from a legitimate principal, when in
          fact the instructions originate from adversarial content in the
          agent's environment (e.g., a malicious web page or document).
          HDP mitigates but does not fully prevent this attack.
        </t>
        <t>
          Applications SHOULD detect and block actions that contradict
          the human's declared scope using their own enforcement
          mechanisms. The semantic comparison is application-defined.
          Blocking an action MUST NOT require suppressing its evidence:
          an HDP-aware agent SHOULD record the attempted action, the
          detected scope deviation, and whether it was blocked in
          <tt>action_summary</tt> under the triggering task's token.
          If a violation is observed after execution, it SHOULD likewise
          be recorded as an observed violation, without claiming that
          the principal approved it or that the signature proves execution.
          The hop timestamp remains the extension time, not a backdated
          event time. If the token cannot be extended, for example because
          its hop budget is exhausted, the application SHOULD retain an
          integrity-protected incident record linked to the token digest
          and triggering request. HDP v0.1 adds no status field for this
          purpose; the distinction is explicit in the declaration.
        </t>
        <t>
          The mitigation HDP provides is evidentiary: an HDP-aware agent
          records each delegation action it takes as a signed hop, so an
          action carried out under a legitimately issued token leaves an
          auditable record, supporting post-hoc detection of prompt
          injection. This mitigation depends on agents actually recording
          their actions; an agent that omits a hop is discussed in
          <xref target="security-truncation"/>.
        </t>
      </section>

      <section anchor="security-key-management" numbered="true" toc="default">
        <name>Key Management</name>
        <t>
          The security of all HDP guarantees depends on the confidentiality
          of the issuer's Ed25519 private key. Implementations MUST:
        </t>
        <ul spacing="normal">
          <li>Store private keys in a secrets manager, HSM, or equivalent
          secure enclave. Private keys MUST NOT be stored in source code,
          configuration files, or environment variables in production.</li>
          <li>Use distinct key pairs per environment (development, staging,
          production).</li>
          <li>Support key rotation by issuing new tokens with a new
          <tt>kid</tt> while maintaining the old public key in the
          verifier's registry until all tokens signed with it have
          expired. Applications requiring historical audit SHOULD retain
          trusted public keys and relevant compromise history for the
          audit retention period (<xref target="historical-audit"/>).
          This does not require retaining retired private keys.</li>
        </ul>
      </section>

      <section anchor="security-offline" numbered="true" toc="default">
        <name>Offline Verification Guarantee</name>
        <t>
          HDP makes a strong architectural guarantee: a correct
          implementation of the 7-step verification pipeline requires no
          network calls, no registry lookups, and no third-party contact.
          The complete trust state required for verification is:
        </t>
        <ul spacing="normal">
          <li>The issuer's Ed25519 public key (32 bytes).</li>
          <li>The current session identifier (string).</li>
          <li>The current time (for expiry checking).</li>
          <li>The verifier's own revocation state: a set of
          <tt>token_id</tt> values, possibly empty
          (<xref target="security-revocation"/>).</li>
        </ul>
        <t>
          This guarantee is a property of the verification procedure,
          not of the single-key signing model of v0.1. Per-agent hop
          signing on the pattern described in
          <xref target="hop-signing"/> would preserve it, since the
          verifier would still resolve only the issuer's key out of
          band.
        </t>
        <t>
          This guarantee enables HDP verification in air-gapped
          environments, edge deployments with intermittent connectivity,
          and latency-sensitive contexts where a network round-trip before
          every action is unacceptable.
        </t>
      </section>
    </section>

    <!-- ================================================================ -->
    <section anchor="iana" numbered="true" toc="default">
      <name>IANA Considerations</name>

      <section anchor="iana-headers" numbered="true" toc="default">
        <name>HTTP Header Field Registration</name>
        <t>
          This document requests registration of the following HTTP header
          fields in the "Hypertext Transfer Protocol (HTTP) Field Name
          Registry" maintained at
          &lt;https://www.iana.org/assignments/http-fields/&gt;.
        </t>

        <dl spacing="normal" newline="false">
          <dt>Header Field Name:</dt><dd>HDP-Token</dd>
          <dt>Status:</dt><dd>provisional</dd>
          <dt>Reference:</dt><dd>This document, <xref target="http-header"/></dd>
          <dt>Comments:</dt><dd>Carries a base64url-encoded HDP token for
          agentic delegation provenance.</dd>
        </dl>

        <dl spacing="normal" newline="false">
          <dt>Header Field Name:</dt><dd>HDP-Token-Ref</dd>
          <dt>Status:</dt><dd>provisional</dd>
          <dt>Reference:</dt><dd>This document, <xref target="token-by-reference"/></dd>
          <dt>Comments:</dt><dd>Carries a UUID token_id identifying an
          immutable token snapshot, or a sha256 content-addressed reference
          to a complete HDP token.</dd>
        </dl>
      </section>

      <section anchor="iana-media-type" numbered="true" toc="default">
        <name>Media Type Registration</name>
        <t>
          This document requests registration of the
          <tt>application/hdp-token+json</tt> media type in the "Media
          Types" registry, following the procedures of
          <xref target="RFC6838"/>.
        </t>
        <dl spacing="normal" newline="false">
          <dt>Type name:</dt><dd>application</dd>
          <dt>Subtype name:</dt><dd>hdp-token+json</dd>
          <dt>Required parameters:</dt><dd>N/A</dd>
          <dt>Optional parameters:</dt><dd>N/A</dd>
          <dt>Encoding considerations:</dt><dd>binary; the token is a UTF-8
          JSON object <xref target="RFC8259"/>.</dd>
          <dt>Security considerations:</dt><dd>See
          <xref target="security-considerations"/> of this document.</dd>
          <dt>Interoperability considerations:</dt><dd>The token uses the
          "+json" structured syntax suffix <xref target="RFC6839"/>;
          generic JSON processors can parse it. HDP-specific semantics are
          defined in this document.</dd>
          <dt>Published specification:</dt><dd>This document.</dd>
          <dt>Applications that use this media type:</dt><dd>Agentic AI
          frameworks and services that exchange HDP delegation-provenance
          tokens.</dd>
          <dt>Fragment identifier considerations:</dt><dd>N/A</dd>
          <dt>Additional information:</dt>
          <dd>Deprecated alias names: none. Magic number(s): none. File
          extension(s): none. Macintosh file type code(s): none.</dd>
          <dt>Person &amp; email address to contact for further
          information:</dt>
          <dd>Asiri Dalugoda &lt;protocol@helixar.ai&gt;</dd>
          <dt>Intended usage:</dt><dd>COMMON</dd>
          <dt>Restrictions on usage:</dt><dd>None</dd>
          <dt>Author:</dt><dd>Asiri Dalugoda</dd>
          <dt>Change controller:</dt><dd>IETF</dd>
        </dl>
      </section>

      <section anchor="iana-well-known" numbered="true" toc="default">
        <name>Well-Known URI Registration</name>
        <t>
          This document requests registration of the following entry in the
          "Well-Known URIs" registry, per <xref target="RFC8615"/>.
        </t>
        <dl spacing="normal" newline="false">
          <dt>URI suffix:</dt><dd>hdp-keys.json</dd>
          <dt>Change controller:</dt><dd>IETF</dd>
          <dt>Specification document:</dt><dd>This document,
          <xref target="key-distribution"/></dd>
          <dt>Status:</dt><dd>provisional</dd>
          <dt>Related information:</dt><dd>Serves a JSON document listing an
          issuer's Ed25519 public keys for HDP token verification.</dd>
        </dl>
      </section>
    </section>

    <!-- ================================================================ -->
    <section anchor="comparison" numbered="true" toc="default">
      <name>Comparison with Related Work</name>

      <section anchor="comparison-ipp" numbered="true" toc="default">
        <name>IPP (draft-haberkamp-ipp-01)</name>
        <t>
          The Intent Provenance Protocol
          <xref target="I-D.haberkamp-ipp"/> and HDP address the same
          root problem with different architectural trade-offs. The key
          differences are:
        </t>
        <ol spacing="normal" type="1">
          <li>
            <strong>Revocation model.</strong>
            IPP -01 Section 8 describes its revocation registry as a
            distributed service at an endpoint specified by the token.
            IPP requires agents to poll at the configured interval, with a
            recommended default of 5,000 milliseconds; for high-stakes
            actions IPP recommends an additional check immediately before
            acting. When the registry is unreachable, IPP permits action
            only if the token supplies <tt>offline_grace_period_ms</tt>
            and the offline duration remains within that period.
            Otherwise IPP prohibits proceeding. HDP instead consults
            verifier-local revocation state at verification time
            (<xref target="security-revocation"/>). HDP does not require
            polling, but it also provides no protocol-defined bound on
            the freshness of that local state.
          </li>
          <li>
            <strong>Trust anchor.</strong>
            IPP tokens contain a <tt>genesis</tt> object (the Genesis
            Seal), a cryptographic
            artifact linking every token to the specification author's
            public key at
            <tt>https://ipp.khsovereign.com/keys/founding_public.pem</tt>.
            Self-hosted IPP deployments are cryptographically bound to
            this third-party key. HDP tokens carry no genesis seal and no
            spec-level attribution; any organization can issue and verify
            HDP tokens without anchoring to a third party.
          </li>
          <li>
            <strong>Identity model.</strong>
            IPP mandates W3C DID Core-conformant principal identifiers.
            HDP supports <tt>id_type: "opaque"</tt> as a first-class
            option, making DID infrastructure optional rather than
            required.
          </li>
        </ol>
        <t>
          These are design choices, not defects. Deployments with reliable
          connectivity to a revocation service, existing DID infrastructure,
          and a requirement for revocation across token ancestry may
          prefer IPP.
          Deployments that prioritize offline operability, self-sovereignty,
          and minimal infrastructure may prefer HDP.
        </t>
      </section>

      <section anchor="comparison-rfc8693" numbered="true" toc="default">
        <name>OAuth 2.0 Token Exchange (RFC 8693)</name>
        <t>
          OAuth 2.0 Token Exchange <xref target="RFC8693"/> defines a
          mechanism for exchanging one security token for another,
          including delegation and impersonation use cases. HDP and
          RFC 8693 are complementary rather than competing: RFC 8693
          governs access token issuance and delegation in an OAuth 2.0
          authorization server context, while HDP governs the
          provenance record that travels with an agentic task regardless
          of the authentication mechanism used.
        </t>
        <t>
          HDP tokens do not replace OAuth access tokens. An agent
          framework MAY use OAuth 2.0 for resource authorization and
          HDP for delegation provenance simultaneously.
        </t>
      </section>

      <section anchor="comparison-jwt" numbered="true" toc="default">
        <name>JSON Web Token (RFC 7519)</name>
        <t>
          JSON Web Token <xref target="RFC7519"/> provides a general-purpose
          signed claims format. HDP differs from JWT in three respects:
        </t>
        <ul spacing="normal">
          <li>HDP tokens carry an append-only, per-hop-signed
          delegation chain (<tt>chain</tt>) that has no equivalent in the
          JWT standard claims set.</li>
          <li>HDP uses RFC 8785 canonical JSON for signing payloads,
          rather than the base64url-encoded header.payload convention
          used by JWS <xref target="RFC7515"/>. This allows direct JSON
          manipulation
          without base64 decoding.</li>
          <li>HDP's verification pipeline is domain-specific to agentic
          delegation (session binding, hop verification, max_hops) rather
          than general-purpose.</li>
        </ul>
      </section>

      <section anchor="comparison-ucan" numbered="true" toc="default">
        <name>UCAN (User Controlled Authorization Networks)</name>
        <t>
          UCAN <xref target="UCAN"/> defines a capability-based
          authorization token system with chained delegation.
          HDP and UCAN share the concept of delegation chains but differ
          significantly in scope: UCAN is a general capability
          authorization system, while HDP is specifically a provenance
          record for human-authorized agentic tasks. HDP makes no claims
          about capability enforcement; UCAN tokens carry executable
          capabilities that are enforced by receiving systems.
        </t>
        <t>
          A UCAN delegation records the authorization provenance of a
          capability: who delegated what to whom. UCAN's separate Invocation
          and Receipt objects can record individual invocations and their
          results; HDP instead keeps the execution record inline in the
          delegation chain itself, as the signed <tt>action_summary</tt>
          declared at each hop, so that the human authorization and the
          subsequent declared actions travel together in a single
          offline-verifiable record. In this
          sense HDP complements capability systems rather than competing
          with them: a deployment MAY use UCAN (or ZCAP-LD, below) for
          capability delegation and HDP alongside it for the
          tamper-evident execution record.
        </t>
      </section>

      <section anchor="comparison-zcap" numbered="true" toc="default">
        <name>ZCAP-LD (Authorization Capabilities for Linked Data)</name>
        <t>
          ZCAP-LD <xref target="W3C.ZCAP-LD"/> expresses delegated
          authorization capabilities as Linked Data, with invocation and
          delegation rooted in a controller's key. As with UCAN, a ZCAP-LD
          delegation chain captures the authorization provenance of a
          capability but not a record of the delegate's subsequent actions.
          HDP neither defines nor enforces capabilities; it records the
          human authorization event and the subsequent execution history.
          Deployments that already use ZCAP-LD MAY use HDP alongside it to
          supply the execution audit trail ZCAP-LD does not itself provide.
        </t>
      </section>

      <section anchor="comparison-odrl" numbered="true" toc="default">
        <name>ODRL and the Verifiable Credentials Data Model</name>
        <t>
          The Open Digital Rights Language (ODRL)
          <xref target="W3C.ODRL"/> is a W3C Recommendation for expressing
          permissions, prohibitions, and constraints. Several fields in
          HDP's <tt>scope</tt> object (<xref target="scope"/>) overlap with
          concepts ODRL already defines: <tt>authorized_tools</tt> and
          <tt>authorized_resources</tt> correspond to ODRL actions and
          targets, <tt>network_egress</tt> and <tt>persistence</tt> map to
          ODRL permissions or prohibitions, and quantitative limits such as
          <tt>max_hops</tt> map to ODRL constraints.
        </t>
        <t>
          HDP v0.1 deliberately retains a small, self-contained
          <tt>scope</tt> object rather than embedding an ODRL policy. The
          trade-off is explicit: the minimal object keeps tokens compact
          and implementable with only JSON and Ed25519, at the cost of the
          vocabulary reuse, policy composability, and tooling
          interoperability that ODRL provides. Deployments that already
          reason over ODRL policies will require a separate mapping to
          interpret HDP scopes.
        </t>
        <t>
          A further limitation of the v0.1 <tt>scope</tt> object is that
          it is fixed at issuance. HDP has no attenuation: a delegate
          cannot narrow the scope at its own hop, because hops record
          actions rather than grants and a hop record has no field in
          which a narrower scope could be expressed. A delegate that
          wishes to pass on less than it received must obtain a new
          token from the issuer with a narrower <tt>scope</tt>. Per-hop
          caveats, which only the verifier and any attenuating agent
          would need to interpret, are planned for a future version.
        </t>
        <t>
          Because the chain-of-custody mechanism is payload-agnostic
          (<xref target="generality"/>), a future HDP profile MAY carry an
          ODRL policy as its payload in place of the native <tt>scope</tt>
          object. Such a profile would gain a natural binding to the
          Verifiable Credentials Data Model 2.0
          <xref target="W3C.VC-DATA-MODEL-2.0"/>, whose <tt>termsOfUse</tt>
          property can carry ODRL policies.
          This binding is identified as future work and is not specified in
          this document.
        </t>
      </section>
    </section>

  </middle>

  <back>

    <references>
        <name>Normative References</name>

        <reference anchor="RFC2119">
          <front>
            <title>Key words for use in RFCs to Indicate Requirement Levels</title>
            <author initials="S." surname="Bradner" fullname="Scott Bradner">
              <organization>Harvard University</organization>
            </author>
            <date year="1997" month="March"/>
          </front>
          <seriesInfo name="BCP" value="14"/>
          <seriesInfo name="RFC" value="2119"/>
          <seriesInfo name="DOI" value="10.17487/RFC2119"/>
        </reference>

        <reference anchor="RFC8174">
          <front>
            <title>Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words</title>
            <author initials="B." surname="Leiba" fullname="Barry Leiba">
              <organization>Huawei Technologies</organization>
            </author>
            <date year="2017" month="May"/>
          </front>
          <seriesInfo name="BCP" value="14"/>
          <seriesInfo name="RFC" value="8174"/>
          <seriesInfo name="DOI" value="10.17487/RFC8174"/>
        </reference>

        <reference anchor="RFC8032">
          <front>
            <title>Edwards-Curve Digital Signature Algorithm (EdDSA)</title>
            <author initials="S." surname="Josefsson" fullname="Simon Josefsson"/>
            <author initials="I." surname="Liusvaara" fullname="Ilari Liusvaara"/>
            <date year="2017" month="January"/>
          </front>
          <seriesInfo name="RFC" value="8032"/>
          <seriesInfo name="DOI" value="10.17487/RFC8032"/>
        </reference>

        <reference anchor="RFC8785">
          <front>
            <title>JSON Canonicalization Scheme (JCS)</title>
            <author initials="A." surname="Rundgren" fullname="Anders Rundgren"/>
            <author initials="B." surname="Jordan" fullname="Bret Jordan"/>
            <author initials="S." surname="Erdtman" fullname="Samuel Erdtman"/>
            <date year="2020" month="June"/>
          </front>
          <seriesInfo name="RFC" value="8785"/>
          <seriesInfo name="DOI" value="10.17487/RFC8785"/>
        </reference>

        <reference anchor="RFC4648">
          <front>
            <title>The Base16, Base32, and Base64 Data Encodings</title>
            <author initials="S." surname="Josefsson" fullname="Simon Josefsson"/>
            <date year="2006" month="October"/>
          </front>
          <seriesInfo name="RFC" value="4648"/>
          <seriesInfo name="DOI" value="10.17487/RFC4648"/>
        </reference>

        <reference anchor="RFC8259">
          <front>
            <title>The JavaScript Object Notation (JSON) Data Interchange Format</title>
            <author initials="T." surname="Bray" fullname="Tim Bray" role="editor"/>
            <date year="2017" month="December"/>
          </front>
          <seriesInfo name="STD" value="90"/>
          <seriesInfo name="RFC" value="8259"/>
          <seriesInfo name="DOI" value="10.17487/RFC8259"/>
        </reference>

        <reference anchor="RFC9562">
          <front>
            <title>Universally Unique IDentifiers (UUIDs)</title>
            <author initials="K." surname="Davis" fullname="Kyzer Davis"/>
            <author initials="B." surname="Peabody" fullname="Brad Peabody"/>
            <author initials="P." surname="Leach" fullname="Paul Leach"/>
            <date year="2024" month="May"/>
          </front>
          <seriesInfo name="RFC" value="9562"/>
          <seriesInfo name="DOI" value="10.17487/RFC9562"/>
        </reference>

        <reference anchor="RFC6234">
          <front>
            <title>US Secure Hash Algorithms (SHA and SHA-based HMAC and HKDF)</title>
            <author initials="D." surname="Eastlake 3rd" fullname="Donald Eastlake 3rd"/>
            <author initials="T." surname="Hansen" fullname="Tony Hansen"/>
            <date year="2011" month="May"/>
          </front>
          <seriesInfo name="RFC" value="6234"/>
          <seriesInfo name="DOI" value="10.17487/RFC6234"/>
        </reference>
        <reference anchor="RFC6838">
          <front>
            <title>Media Type Specifications and Registration Procedures</title>
            <author initials="N." surname="Freed" fullname="Ned Freed"/>
            <author initials="J." surname="Klensin" fullname="John Klensin"/>
            <author initials="T." surname="Hansen" fullname="Tony Hansen"/>
            <date year="2013" month="January"/>
          </front>
          <seriesInfo name="BCP" value="13"/>
          <seriesInfo name="RFC" value="6838"/>
          <seriesInfo name="DOI" value="10.17487/RFC6838"/>
        </reference>

    </references>

    <references>
        <name>Informative References</name>

        <reference anchor="I-D.haberkamp-ipp"
                   target="https://datatracker.ietf.org/doc/html/draft-haberkamp-ipp-01">
          <front>
            <title>Intent Provenance Protocol (IPP)</title>
            <author initials="A." surname="Haberkamp" fullname="A. Haberkamp"/>
            <date year="2026" month="July"/>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-haberkamp-ipp-01"/>
        </reference>

        <reference anchor="RFC8693">
          <front>
            <title>OAuth 2.0 Token Exchange</title>
            <author initials="M." surname="Jones" fullname="Michael Jones"/>
            <author initials="A." surname="Nadalin" fullname="Anthony Nadalin"/>
            <author initials="B." surname="Campbell" fullname="Brian Campbell"/>
            <author initials="J." surname="Bradley" fullname="John Bradley"/>
            <author initials="C." surname="Liu" fullname="Chuck Liu"/>
            <date year="2020" month="January"/>
          </front>
          <seriesInfo name="RFC" value="8693"/>
          <seriesInfo name="DOI" value="10.17487/RFC8693"/>
        </reference>

        <reference anchor="RFC7519">
          <front>
            <title>JSON Web Token (JWT)</title>
            <author initials="M." surname="Jones" fullname="Michael B. Jones"/>
            <author initials="J." surname="Bradley" fullname="John Bradley"/>
            <author initials="N." surname="Sakimura" fullname="Nat Sakimura"/>
            <date year="2015" month="May"/>
          </front>
          <seriesInfo name="RFC" value="7519"/>
          <seriesInfo name="DOI" value="10.17487/RFC7519"/>
        </reference>

        <reference anchor="W3C.DID"
                   target="https://www.w3.org/TR/did-core/">
          <front>
            <title>Decentralized Identifiers (DIDs) v1.0</title>
            <author initials="M." surname="Sporny" fullname="Manu Sporny"/>
            <author initials="D." surname="Longley" fullname="Dave Longley"/>
            <author initials="M." surname="Sabadello" fullname="Markus Sabadello"/>
            <author initials="D." surname="Reed" fullname="Drummond Reed"/>
            <author initials="O." surname="Steele" fullname="Orie Steele"/>
            <author initials="C." surname="Allen" fullname="Christopher Allen"/>
            <date year="2022" month="July"/>
          </front>
          <seriesInfo name="W3C Recommendation" value="did-core"/>
        </reference>

        <reference anchor="HDP-SPEC"
                   target="https://helixar.ai/about/labs/hdp/">
          <front>
            <title>Human Delegation Provenance Protocol v0.1 Specification</title>
            <author>
              <organization>Helixar Limited</organization>
            </author>
            <date year="2026"/>
          </front>
        </reference>

        <reference anchor="HDP-IMPL"
                   target="https://github.com/Helixar-AI/HDP">
          <front>
            <title>HDP TypeScript Reference Implementation</title>
            <author>
              <organization>Helixar Limited</organization>
            </author>
            <date year="2026"/>
          </front>
        </reference>

        <reference anchor="W3C.ODRL"
                   target="https://www.w3.org/TR/odrl-model/">
          <front>
            <title>ODRL Information Model 2.2</title>
            <author initials="R." surname="Iannella" fullname="Renato Iannella"/>
            <author initials="S." surname="Villata" fullname="Serena Villata"/>
            <date year="2018" month="February"/>
          </front>
          <seriesInfo name="W3C Recommendation" value="odrl-model"/>
        </reference>

        <reference anchor="W3C.VC-DATA-MODEL-2.0"
                   target="https://www.w3.org/TR/vc-data-model-2.0/">
          <front>
            <title>Verifiable Credentials Data Model v2.0</title>
            <author initials="M." surname="Sporny" fullname="Manu Sporny"/>
            <author initials="T." surname="Thibodeau" fullname="Ted Thibodeau Jr."/>
            <author initials="I." surname="Herman" fullname="Ivan Herman"/>
            <author initials="M." surname="Jones" fullname="Michael B. Jones"/>
            <author initials="G." surname="Cohen" fullname="Gabe Cohen"/>
            <date year="2025" month="May"/>
          </front>
          <seriesInfo name="W3C Recommendation" value="vc-data-model-2.0"/>
        </reference>

        <reference anchor="W3C.ZCAP-LD"
                   target="https://w3c-ccg.github.io/zcap-spec/">
          <front>
            <title>Authorization Capabilities for Linked Data</title>
            <author initials="C." surname="Lemmer Webber" fullname="Christopher Lemmer Webber"/>
            <author initials="M." surname="Miller" fullname="Mark S. Miller"/>
            <date year="2023"/>
          </front>
          <seriesInfo name="W3C Community Group Report" value="zcap-ld"/>
        </reference>

        <reference anchor="UCAN"
                   target="https://github.com/ucan-wg/spec">
          <front>
            <title>User Controlled Authorization Networks (UCAN) Specification</title>
            <author>
              <organization>UCAN Working Group</organization>
            </author>
            <date year="2024"/>
          </front>
        </reference>

        <reference anchor="RFC5321">
          <front>
            <title>Simple Mail Transfer Protocol</title>
            <author initials="J." surname="Klensin" fullname="John Klensin"/>
            <date year="2008" month="October"/>
          </front>
          <seriesInfo name="RFC" value="5321"/>
          <seriesInfo name="DOI" value="10.17487/RFC5321"/>
        </reference>

        <reference anchor="RFC7515">
          <front>
            <title>JSON Web Signature (JWS)</title>
            <author initials="M." surname="Jones" fullname="Michael B. Jones"/>
            <author initials="J." surname="Bradley" fullname="John Bradley"/>
            <author initials="N." surname="Sakimura" fullname="Nat Sakimura"/>
            <date year="2015" month="May"/>
          </front>
          <seriesInfo name="RFC" value="7515"/>
          <seriesInfo name="DOI" value="10.17487/RFC7515"/>
        </reference>

        <reference anchor="RFC6839">
          <front>
            <title>Additional Media Type Structured Syntax Suffixes</title>
            <author initials="T." surname="Hansen" fullname="Tony Hansen"/>
            <author initials="A." surname="Melnikov" fullname="Alexey Melnikov"/>
            <date year="2013" month="January"/>
          </front>
          <seriesInfo name="RFC" value="6839"/>
          <seriesInfo name="DOI" value="10.17487/RFC6839"/>
        </reference>

        <reference anchor="RFC8615">
          <front>
            <title>Well-Known Uniform Resource Identifiers (URIs)</title>
            <author initials="M." surname="Nottingham" fullname="Mark Nottingham"/>
            <date year="2019" month="May"/>
          </front>
          <seriesInfo name="RFC" value="8615"/>
          <seriesInfo name="DOI" value="10.17487/RFC8615"/>
        </reference>

        <reference anchor="RFC6648">
          <front>
            <title>Deprecating the "X-" Prefix and Similar Constructs in Application Protocols</title>
            <author initials="P." surname="Saint-Andre" fullname="Peter Saint-Andre"/>
            <author initials="D." surname="Crocker" fullname="Dave Crocker"/>
            <author initials="M." surname="Nottingham" fullname="Mark Nottingham"/>
            <date year="2012" month="June"/>
          </front>
          <seriesInfo name="BCP" value="178"/>
          <seriesInfo name="RFC" value="6648"/>
          <seriesInfo name="DOI" value="10.17487/RFC6648"/>
        </reference>

    </references>

    <section anchor="complete-token-example" numbered="true" toc="default">
      <name>Complete Token Example</name>
      <t>
        The following is a complete HDP token with a two-hop delegation
        chain, for illustrative purposes. Signature values are truncated.
        The <tt>scope</tt> lists a resource for each tool that acts on
        one, and each hop names the resource it declares acting on;
        <xref target="scope"/> explains why v0.1 cannot bind tools to
        resources structurally.
      </t>
      <sourcecode type="json"><![CDATA[
{
  "hdp": "0.1",
  "header": {
    "token_id"   : "550e8400-e29b-41d4-a716-446655440000",
    "issued_at"  : 1711483200000,
    "expires_at" : 1711569600000,
    "session_id" : "sess-20260326-abc123",
    "version"    : "0.1"
  },
  "principal": {
    "id"           : "usr_alice_opaque",
    "id_type"      : "opaque",
    "display_name" : "Alice Chen"
  },
  "scope": {
    "intent"              : "Analyze Q1 sales data and report.",
    "authorized_tools"    : ["database_read", "file_write"],
    "authorized_resources": ["db://sales/q1-2026",
                             "file://reports/"],
    "data_classification" : "confidential",
    "network_egress"      : false,
    "persistence"         : true,
    "max_hops"            : 10
  },
  "chain": [
    {
      "seq"            : 1,
      "agent_id"       : "orchestrator-v2",
      "agent_type"     : "orchestrator",
      "timestamp"      : 1711483260000,
      "action_summary" : "Decompose task; delegate to sub-agents.",
      "parent_hop"     : 0,
      "hop_signature"  : "base64url-sig-1..."
    },
    {
      "seq"            : 2,
      "agent_id"       : "sql-agent-v1",
      "agent_type"     : "sub-agent",
      "timestamp"      : 1711483320000,
      "action_summary" : "Execute read query on db://sales/q1-2026.",
      "parent_hop"     : 1,
      "hop_signature"  : "base64url-sig-2..."
    }
  ],
  "signature": {
    "kid"   : "alice-signing-key-v1",
    "alg"   : "Ed25519",
    "value" : "base64url-root-sig..."
  }
}
      ]]></sourcecode>
    </section>

    <section anchor="acknowledgments" numbered="false" toc="default">
      <name>Acknowledgments</name>
      <t>
        Alan Karp reviewed successive revisions of this document in
        detail. The verifier-local revocation model
        (<xref target="security-revocation"/>), the treatment of
        delegation budgets (<xref target="security-max-hops"/>), the
        recursive accountability argument and the guidance on delegate
        identifiers (<xref target="minimum-disclosure"/>), the
        correction to the stated cost of single-key signing
        (<xref target="hop-signing"/>), and the insistence that this
        document say plainly what HDP is not
        (<xref target="what-hdp-is-not"/>) all result from those
        reviews.
      </t>
      <t>
        Brigitte Qirong LI supplied the characterization of a
        single-key hop signature as recording a delegation rather than
        evidencing consent to it (<xref target="hop-signing"/>), and the
        exchange on the W3C Credentials Community Group list sharpened
        the analysis of chain truncation
        (<xref target="security-truncation"/>).
      </t>
      <t>
        Bob Wyman and sankarshan mukhopadhyay reviewed the initial
        revision on the same list; their comments shaped
        <xref target="generality"/> and <xref target="comparison-odrl"/>.
      </t>
    </section>

    <section anchor="changelog" numbered="false" toc="default">
      <name>Change Log</name>
      <t>
        This section will be removed before publication as an RFC.
      </t>
      <dl spacing="normal" newline="false">
        <dt>draft-helixar-hdp-agentic-delegation-02:</dt>
        <dd>Incorporates a further round of review. Added
        <xref target="what-hdp-is-not"/>, stating that HDP is not an
        authorization protocol, and aligned the abstract, the
        <tt>scope</tt> field descriptions, the verification pipeline,
        and the transport text with it. Revocation is now normative: a
        verifier MUST support verifier-local revocation by
        <tt>token_id</tt>, checked at Step 2
        (<xref target="security-revocation"/>); re-authorization is
        described as lineage rather than revocation
        (<xref target="reauthorization"/>); the 24-hour default lifetime
        is removed (<xref target="security-replay"/>). Corrected the
        stated cost of single-key hop signing and described what a v0.1
        hop signature does and does not attest
        (<xref target="hop-signing"/>). Hop timestamp monotonicity is
        now a MUST (<xref target="chain-rules"/>). Added
        <xref target="security-max-hops"/> (delegation budgets and
        off-record delegation), <xref target="security-attribution"/>
        (attribution across concurrent tokens), a presenter check and a
        completeness analysis in <xref target="security-truncation"/>,
        recursive accountability and delegate-identifier guidance in
        <xref target="minimum-disclosure"/>, a content-addressed
        token-by-reference option with a write-once requirement
        (<xref target="token-by-reference"/>), a composition-versus-
        chaining rationale (<xref target="multi-principal"/>), and an
        attenuation limitation (<xref target="comparison-odrl"/>).
        Noted that <tt>authorized_tools</tt> and
        <tt>authorized_resources</tt> are unbound lists
        (<xref target="scope"/>) and corrected the Appendix A example
        accordingly. Retargeted <xref target="HDP-SPEC"/>. Added an
        Acknowledgments section. A subsequent consistency review added
        historical audit verification distinct from live acceptance;
        explicit recording of out-of-scope attempts and observed violations;
        issuer serialization and digest-bound receipt guidance for forks;
        mandatory reference integrity checks and immutable UUID snapshots;
        explicit retained context for parent-link meaning; exact integer
        bounds and input validation; and corrections to the IPP revocation
        comparison. The token structure and signature payloads are
        unchanged and remain HDP v0.1; input constraints and verifier
        requirements have been tightened.</dd>
        <dt>draft-helixar-hdp-agentic-delegation-01:</dt>
        <dd>Incorporates review feedback from the W3C Credentials Community
        Group and a specification-consistency pass. Related Work
        (<xref target="comparison"/>) expanded with ODRL, a Verifiable
        Credentials Data Model 2.0 <tt>termsOfUse</tt> alignment note, and
        ZCAP-LD; the UCAN comparison identifies the execution audit trail as
        HDP's distinguishing contribution. Added <xref target="generality"/>
        (payload-agnostic chain-of-custody with agentic delegation as the
        reference profile). Corrected root signature verification to reset
        <tt>chain</tt> to empty before canonicalization, matching the
        signing procedure, and clarified that in v0.1 the issuer produces
        all root and hop signatures with a single key. Added
        <xref target="security-truncation"/> (chain truncation and
        completeness), <xref target="security-revocation"/> (revocation),
        <tt>session_id</tt> entropy guidance, and per-hop opaque-identifier
        privacy guidance (<xref target="minimum-disclosure"/>). The
        verification pipeline now also checks <tt>header.version</tt>,
        <tt>signature.alg</tt>, and <tt>parent_hop</tt> validity. Completed
        the IANA media-type registration template and added a Well-Known URI
        registration. Added missing normative and informative references.
        Renamed the HTTP header fields from <tt>X-HDP-Token</tt> and
        <tt>X-HDP-Token-Ref</tt> to <tt>HDP-Token</tt> and
        <tt>HDP-Token-Ref</tt> (<xref target="RFC6648"/>). Editorial
        corrections. The token wire format is unchanged and remains HDP
        v0.1; the HTTP header field names changed.</dd>
        <dt>draft-helixar-hdp-agentic-delegation-00:</dt>
        <dd>Initial submission. Specifies HDP v0.1 token structure,
        signing, verification pipeline, re-authorization, multi-principal
        delegation, transport, privacy considerations, and security
        analysis.</dd>
      </dl>
    </section>

  </back>
</rfc>
