<?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-03"
     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-03"/>

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

    <date year="2026" month="October" day="6"/>

    <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 lets an auditor
        verify the integrity of the full record using only the issuer's
        Ed25519 public key.
        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 what the human asked for and of how each agent read and
        acted on that request. On deployments that use capability-based
        delegation formats such as UCAN and ZCAP-LD, the same content can
        travel in the capability certificates' own metadata instead of a
        separate token. 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 is not an input to any access decision. 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 and auditability problems:
      </t>
      <ul spacing="normal">
        <li>
          Post-hoc audits cannot reconstruct who approved what, and when.
        </li>
        <li>
          Nothing connects what the human asked for with what each agent
          took the task to be. Each agent passes on its own reading of the
          task, and after a few hops the action can drift a long way from
          the request, like an intern sent out for a coffee who comes back
          with a pound of beans. Every hop may have been within the
          authority granted, so nothing was denied, and no record shows
          where the request changed.
        </li>
      </ul>
      <t>
        Recording the human's statement of intent beside each agent's
        reading of it is one approach to drift, and not a complete one:
        the record is only as good as the summaries it holds
        (<xref target="chain"/>).
      </t>
      <t>
        HDP addresses this by defining a token that:
      </t>
      <ul spacing="normal">
        <li>Records the human principal, their request and declared
        scope, and the session in which they gave it.</li>
        <li>Accumulates a cryptographically signed hop record for each
        agent that handles the token.</li>
        <li>Allows an auditor to verify the entire chain (root
        signature plus all hop signatures) using only the issuer's
        Ed25519 public key.</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, and not to be an input to them.
        </t>
        <t>
          An HDP token MUST NOT be used as an input to any access
          decision. A service MUST NOT grant, refuse, or condition an
          action on the presence of an HDP token, on the outcome of
          verifying one, or on its contents. A missing token, or one
          that fails verification, is an audit finding and is recorded
          as one; it is not a reason to deny a request. A check that can
          deny is an access control mechanism whatever it is called, and
          running a second one beside the system's own is a well-known
          hazard: it adds an independent way to attack the system, and
          its denials can look to the base mechanism like failures that
          mechanism was not designed to handle.
        </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. Integrity verification
          (<xref target="verification"/>) establishes that a record is
          authentic and intact, not that anyone may act. The HTTP
          transport (<xref target="transport"/>) shows a token
          accompanying a request because the task travels in the
          request and the receiving side records it, not because the
          token authorizes it.
        </t>
        <t>
          The reader of an HDP token is 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 review of how each agent read the human's request. A token
          is carried with the task and read at audit.
        </t>
        <t>
          Earlier revisions of this document also described a reader
          that relied on the token before an action: expiry checks,
          session binding, replay defense, and verifier-local revocation
          served that reader. This revision removes them. The fields that
          supported them, <tt>header.expires_at</tt> and
          <tt>header.session_id</tt>, remain in the v0.1 wire format and
          are described in <xref target="header"/> as record metadata.
          Whether they belong in a future token version is an open
          question.
        </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> Verifying a record's
          integrity MUST require only the issuer's public key. 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 integrity verification.
          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"/>. At the time of writing
          it implements -02 of this document, including the checks before
          an action that this revision removes
          (<xref target="what-hdp-is-not"/>), and is being updated to
          match.
        </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 the integrity of an HDP token
        (<xref target="verification"/>). In practice the verifier is an
        audit system or a human reviewer's tooling
        (<xref target="what-hdp-is-not"/>).</dd>
        <dt>Presenter:</dt>
        <dd>The agent that transmits a token with a task. In a
        complete chain the presenter is the agent that appended the
        final hop.</dd>
        <dt>Recording component:</dt>
        <dd>A component outside an agent's control, such as a virtual
        machine sidecar, tool gateway, or MCP proxy, that records hops
        for the agent (<xref target="chain"/>).</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 a recommended
        recording depth. 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"     : { ... },        // declared 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 the record's identifier, its
          timing, and the session in which the human authorized the task.
        </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>. Records the end of the period for which the
          principal authorized the task. It has no effect on integrity
          verification (<xref target="verification"/>), and a service
          treats a token received after this time no differently from any
          other (<xref target="what-hdp-is-not"/>). A hop whose
          <tt>timestamp</tt> is at or after <tt>expires_at</tt> is
          recorded like any other, and an auditor reports it as recorded
          after the authorization period ended
          (<xref target="historical-audit"/>). HDP defines no default
          lifetime.</dd>
          <dt>session_id:</dt>
          <dd>REQUIRED. Opaque string identifying the session in which the
          principal authorized the task, established out of band between
          issuer and agent framework before issuance. It lets an auditor
          associate the record with the session's other records,
          including superseding and jointly approved records
          (<xref target="reauthorization"/>,
          <xref target="multi-principal"/>).</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 an earlier record this
          record is linked to: one it supersedes
          (<xref target="reauthorization"/>), or one recording another
          principal's approval of the same task
          (<xref target="multi-principal"/>).</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. The principal's request, in natural language.
          Free-form string. It is what an auditor compares each hop's
          <tt>action_summary</tt> against, and SHOULD be written to be
          both human- and agent-readable. Where practical it SHOULD be
          the principal's own words.</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.</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>. Records the
          sensitivity level of data the principal declared the agent
          may access.</dd>
          <dt>network_egress:</dt>
          <dd>REQUIRED. Boolean. Records whether the principal declared
          that the agent may make outbound network requests.</dd>
          <dt>persistence:</dt>
          <dd>REQUIRED. Boolean. Records whether the principal declared
          that the agent may write persistent state.</dd>
          <dt>max_hops:</dt>
          <dd>OPTIONAL. Positive integer, chosen by the issuer: the number
          of hops this record holds. Once the chain holds
          <tt>max_hops</tt> hops it is not extended (Rule 4 of
          <xref target="chain-rules"/>). Delegation beyond that depth is
          not recorded in this token, and the agent that appended the
          final hop is accountable for everything delegated beyond it
          (<xref target="security-max-hops"/>). An issuer MAY choose any
          value within the representation bounds in
          <xref target="integer-ranges"/>. If <tt>max_hops</tt> is
          absent, HDP places no limit on the depth recorded.</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. Comparing what agents
          declared with the declared scope is an audit 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. If both resources were databases and one tool wrote
          while the other read, the record could not say which tool went
          with which database.
          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.
        </t>
        <t>
          The fixed values are also too coarse. The four
          <tt>data_classification</tt> levels are not the ones every
          issuer uses, and a single <tt>persistence</tt> flag cannot
          record that a principal let an agent write log records but
          nothing else.
        </t>
        <t>
          The next token version is planned to replace
          <tt>authorized_tools</tt>, <tt>authorized_resources</tt>,
          <tt>data_classification</tt>, <tt>network_egress</tt>, and
          <tt>persistence</tt> with one nested structure: a map from each
          resource to what the principal declared for it, with values
          chosen by the issuer. The map will be required but may be empty,
          so that a record declaring nothing can be told apart from one
          that says nothing. The following is illustrative only; member
          names are not yet fixed:
        </t>
        <sourcecode type="json"><![CDATA[
{
  "intent"      : "Analyze Q1 sales data and report.",
  "permissions" : {
    "db://sales/q1-2026" : { "actions": ["read"],
                             "classification": "confidential" },
    "file://reports/"    : { "actions": ["write"] },
    "log://agent-audit"  : { "actions": ["append"] }
  }
}
        ]]></sourcecode>
        <t>
          These are wire-format changes and are 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. String. A descriptive label for the agent's role,
          such as <tt>orchestrator</tt>, <tt>sub-agent</tt>, or
          <tt>tool-executor</tt>. HDP attaches no normative meaning to any
          value, and the delegator MAY use any string. Earlier revisions
          allowed only four values, the fourth being the literal string
          <tt>custom</tt>; tokens using those values remain valid.</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 party 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 the hop's action, recording how
          the agent read the task it was given, 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>
        <t>
          The <tt>action_summary</tt> is supplied by whoever submits the
          hop, and in v0.1 the issuer signs what it is given
          (<xref target="hop-signing"/>). When the agent writes its own
          summary, the record holds the agent's account of what it did and
          is only as reliable as that agent. Where a component outside the
          agent's control observes the agent's actions, such as a virtual
          machine sidecar, a tool gateway, or an MCP proxy, that component
          SHOULD record the hop in place of the agent, and the record
          SHOULD identify which component recorded it. HDP v0.1 has no
          field for the recording component; until one is added, the
          component SHOULD name itself in <tt>action_summary</tt>.
        </t>
      </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 secret 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 secret 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.
        </t>
        <t>
          Issuer signing remains the baseline. Per-agent hop signing on
          that pattern is planned as an option for a future version, for
          deployments that can manage agent keys; it is not planned as a
          replacement. The baseline is kept because it confines signing to
          one party. OAuth 1.0 <xref target="RFC5849"/> required every
          client to sign its requests, which developers found hard to get
          right, and OAuth 2.0 <xref target="RFC6749"/> dropped the
          requirement and relies on TLS instead. Under the
          planned option an agent uses a fresh key for each delegation,
          signed into the chain by its delegator, so an agent key lasts no
          longer than its task and key rotation comes down to rotating the
          issuer's key. That design does not yet handle a key compromised
          during a task, and the extension will have to say how. The
          option 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;
          further delegation is not recorded in it
          (<xref target="security-max-hops"/>).</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 chain in which
          a hop's <tt>timestamp</tt> is less than its predecessor's fails
          integrity verification (Step 3 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 is a verification failure.</li>
        </ol>
      </section>
    </section>

    <!-- ================================================================ -->
    <section anchor="verification" numbered="true" toc="default">
      <name>Integrity Verification</name>
      <t>
        Integrity verification establishes that a record is as the
        issuer signed it. A verifier MUST first validate the input as
        specified in <xref target="token-structure"/>, then execute the
        following five steps in order. A failure at any step means that
        the record's integrity is not established; the verifier MUST
        report the failure and the step at which it occurred, and MUST
        NOT proceed to subsequent steps. Integrity verification does not
        depend on the current time, on a session, or on any state held
        by the verifier other than the issuer's public key, so a record
        verifies the same way on the day it is issued and years later.
      </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 is a failure.
        </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 is a
          failure. 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> is a
          failure (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 is a failure (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
            is a failure.</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>Recorded depth check.</strong>
          If <tt>scope.max_hops</tt> is defined, the length of
          <tt>chain</tt> MUST NOT exceed it.
        </li>
      </ol>

      <t>
        Verification is fully offline. Steps 1 through 5 require only
        the issuer's Ed25519 public key. No network call, registry
        lookup, or third-party contact is required at any step.
      </t>
      <t>
        A record that passes all five 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 any agent was
        permitted to act, and failing it is not grounds for refusing an
        action (<xref target="what-hdp-is-not"/>).
      </t>
      <t>
        If <tt>principal.poh_credential</tt> is present, an auditor MAY
        check it with an application-defined verifier and report the
        result separately from record integrity (<xref target="poh"/>).
      </t>

      <section anchor="historical-audit" numbered="true" toc="default">
        <name>Audit Results</name>
        <t>
          Audit tooling MUST report the following results separately.
          They are results of examining a record, 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 passes the
          steps above, using a trusted archived issuer key. If the key
          or a supported verification algorithm is unavailable,
          integrity is unverified rather than valid.</dd>
          <dt>Recording period:</dt>
          <dd>Whether any hop's <tt>timestamp</tt> is at or after
          <tt>header.expires_at</tt>. Such hops are reported as recorded
          after the authorization period ended, not discarded. Hop
          timestamps are declared values (<xref target="chain"/>).</dd>
          <dt>Session:</dt>
          <dd>Where the audit concerns a particular session, whether
          <tt>header.session_id</tt> matches it. A mismatch means the
          record belongs to another session; it does not make the record
          invalid.</dd>
          <dt>Linked records:</dt>
          <dd>For a record with <tt>parent_token_id</tt>, its
          relationship to the parent: supersession, joint approval, or
          unknown, determined as described in
          <xref target="multi-principal"/>.</dd>
        </dl>
        <t>
          A valid record establishes what the issuer recorded. It does not
          establish that an action occurred, that the recorded chain is
          complete (<xref target="security-truncation"/>), or that the
          human authorized a particular action. Applications requiring
          audit SHOULD retain the tokens, the trusted public keys, and any
          receipts (<xref target="security-truncation"/>) for their audit
          retention period. Key-compromise information MUST qualify any
          conclusion drawn from a mathematically valid signature
          (<xref target="security-key-management"/>).
        </t>
      </section>

    </section>

    <!-- ================================================================ -->
    <section anchor="reauthorization" numbered="true" toc="default">
      <name>Superseding Records</name>
      <t>
        An issuer may need to start a new record for a task already
        under way: the principal changes the request or the scope, a
        high-risk action warrants the principal's fresh confirmation, or
        the chain has reached <tt>max_hops</tt> and the deployment wants
        recording to continue. The issuer then issues a new token that
        supersedes the original.
      </t>
      <t>
        Supersession is recorded 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 link is covered by the new token's
        root signature.
      </t>
      <t>
        A superseding 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>.</li>
        <li>Records <tt>parent_token_id</tt> pointing to the original,
        so that an auditor can follow how the task's authorization
        changed.</li>
      </ul>
      <t>
        Supersession adds a record. It does not alter or invalidate the
        record it supersedes, which remains a valid record of what
        happened under it. Hops appended to the superseded token after
        the superseding one was issued are recorded like any other, and
        an auditor comparing the two sees them. Auditors examining a task
        SHOULD retain all tokens in a session and follow the full
        <tt>parent_token_id</tt> linkage. Withdrawing an agent's authority
        to act is a matter for the access control mechanism, not for HDP
        (<xref target="what-hdp-is-not"/>).
      </t>
    </section>

    <!-- ================================================================ -->
    <section anchor="multi-principal" numbered="true" toc="default">
      <name>Joint Approval by Several Principals</name>
      <t>
        HDP v0.1 supports one principal per token. This section covers
        recording that more than one human approved the same task, as
        under a two-person rule. It is not delegation by several
        principals, and no principal's authority is combined with
        another's. Human A's approval is recorded in token T1; Human B's
        approval is recorded in 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 examine a joint approval, an auditor MUST:
      </t>
      <ol spacing="normal" type="1">
        <li>Verify the integrity of each token against its issuer's
        public key (<xref target="verification"/>).</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 approval, as described
        below. Without that context, report linked records with an
        unknown relationship, not established joint approval.</li>
      </ol>
      <t>
        Each principal's approval is a distinct signed artifact, and no
        threshold signature scheme is needed. A future version of HDP may
        introduce simultaneous multi-signature primitives using threshold
        signature schemes.
      </t>
      <t>
        An alternative to chaining is composition: each principal's
        approval is an independent token, and the application's own
        records bind the tokens to the task. Chaining is specified here
        because T2 signs a reference to T1, which puts the link in the
        record. The link alone does not state that the approvals were for
        the same action; that meaning requires the application context
        below. Composition gives equivalent evidence when an
        authenticated receipt binds both token digests to the task.
        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 purposes:
        supersession, where a new record replaces an earlier one
        (<xref target="reauthorization"/>), and joint approval (this
        section). HDP v0.1 does not tag which relationship a given
        <tt>parent_token_id</tt> expresses. This is a known weakness: an
        audit cannot always determine the relationship from the records
        alone. Applications MUST obtain its meaning from trusted, explicit
        context, such as an authenticated issuance record identifying the
        parent, child, and relationship type. Expiry, principal equality,
        and session equality alone MUST NOT be used to infer that
        meaning. 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. The fix is a
        signed relationship type in the header, planned for the next
        token version. Note also that a superseding token's
        <tt>session_id</tt> MAY differ from that of the token it
        supersedes, whereas the tokens in a joint approval 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.
          The reason is privacy, not secrecy: a token is not a bearer
          secret, but it carries the <tt>principal</tt> object and the
          principal's request, and URLs are written to server logs and
          browser histories.
        </t>
        <t>
          A token accompanies a request because the task it records
          travels in that request, and so that the receiving side, or a
          recording component in front of it (<xref target="chain"/>),
          can record the next hop and keep the record where an auditor
          can find it. Its presence does not authorize the request, and
          the receiving service MUST NOT use it as an input to its
          decision to act (<xref target="what-hdp-is-not"/>).
        </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., long 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 integrity verification
          (<xref target="verification"/>); 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 integrity verification 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="hash-linked-snapshots" numbered="true" toc="default">
        <name>Hash-Linked Snapshots</name>
        <t>
          A store that holds every snapshot of a token in full repeats the
          chain prefix on each extension, so keeping all the snapshots of
          an n-hop chain costs storage on the order of n squared hops. A
          store MAY instead hold a token as hash-linked entries:
        </t>
        <ul spacing="normal">
          <li>The base entry is the token as issued, with an empty
          <tt>chain</tt>.</li>
          <li>Each later entry is a JSON object with two members:
          <tt>prev</tt>, the content-addressed reference
          (<xref target="token-by-reference"/>) of the snapshot it
          extends, and <tt>hop</tt>, the one hop appended.</li>
        </ul>
        <sourcecode type="json"><![CDATA[
{
  "prev" : "sha256:<digest of the snapshot this entry extends>",
  "hop"  : { "seq": 3, "agent_id": "...", "hop_signature": "..." }
}
        ]]></sourcecode>
        <t>
          The store keeps each entry under the content-addressed reference
          of the complete snapshot it produces: the token that results
          from appending <tt>hop</tt> to the snapshot named by
          <tt>prev</tt>. References keep their meaning. A
          content-addressed reference always identifies a complete token,
          and resolving one from a hash-linked store means reconstructing
          that token by following <tt>prev</tt> back to the base entry,
          appending the hops in order, and checking the digest as
          <xref target="token-by-reference"/> requires. A store MAY return
          the entries in place of the complete token; the recipient then
          reconstructs the token and performs the same check. The layout
          of a store's entries is a storage matter and is not part of the
          token wire format.
        </t>
        <t>
          Hash-linking saves storage, not verification. A hop signature
          covers every hop before it (<xref target="hop-signing"/>), so an
          auditor still has to fetch and check every hop up to the
          snapshot being verified.
        </t>
        <t>
          Records also grow in a second direction. An action may take as
          an argument something delegated under another task, and a full
          audit of the action then involves that task's record as well:
          with chains of five hops, an action with k such arguments brings
          on the order of 5 * (1 + k) hops into its audit. Where a hop's
          action takes such an argument, its <tt>action_summary</tt>
          SHOULD refer to the other record by content-addressed reference
          rather than embedding it.
        </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. A stripped
          token is no longer verifiable: its root signature can no longer
          be checked, so nothing binds its header, scope, or chain to the
          principal's authorization. Stripped tokens MUST be marked as no
          longer verifiable and MUST NOT be reported as having valid
          integrity.
        </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; an identifier meaningful only to the audit system suits
          deployments that must hide the organisation's structure from
          everyone else who sees the token; 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. Opaque identifiers hide who is in a chain but not
          its length: a chain of them still shows how many hops a task
          took (<xref target="security-max-hops"/>).
        </t>
        <t>
          HDP v0.1 offers no field-level confidentiality: a token is
          either conveyed whole or stripped, as above. Earlier revisions
          gave two reasons for not specifying encryption of
          <tt>principal</tt> fields: the keys in circulation are Ed25519
          signing keys rather than encryption keys, and the set of
          verifiers was open, so there was no defined party to encrypt
          to. The second reason no longer holds. The reader of a token is
          the audit system (<xref target="what-hdp-is-not"/>), so fields
          the agents do not need, such as <tt>principal</tt> fields, could
          be encrypted to it, much as SAML 2.0 allows individual
          attributes in an assertion to be encrypted. The cost is key management: the
          audit system needs an encryption key pair, distinct from any
          signing key, whose public key issuers can obtain and whose
          secret key is retained for as long as the records are. Field-level
          encryption to the audit system is therefore a candidate for a
          future version. Selective disclosure of principal fields and of
          individual hops, which would allow a token to be verified with
          parts withheld, is also 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 set by the
          audit purpose they serve.</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>
          An auditor that checks the credential reports the result
          separately from record integrity (<xref target="verification"/>).
          A check made at audit shows the credential's status at that
          time, not when the token was issued; evidence of the earlier
          status has to be retained when that earlier check is made. The
          verifier callback SHOULD be idempotent and SHOULD NOT have side
          effects.
        </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 in their own access control mechanism and MUST
          NOT use the HDP token as an input to it. 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 2 of integrity verification (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 secret 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 3) or
          invalidates the hop signatures of all subsequent hops (Step 4),
          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 secret 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 integrity
          verification. 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>
          Where the receiving side can authenticate the presenter (for
          example, because the transport identifies the calling agent),
          it SHOULD record the presenter's identity with the token it
          received, and an auditor SHOULD compare the final hop's
          <tt>agent_id</tt> with that recorded presenter. This is cheap
          and exposes one truncation case: a third party presenting a
          shorter, earlier copy of the token, whose final hop names
          someone else. Capability systems impose the same requirement at
          invocation: 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>
          Where the deployment uses a capability system such as UCAN or
          ZCAP-LD, the certificates presented at the resource are a better
          record of exercised authority than anything HDP carries. The
          resource sees every certificate in each chain presented to it,
          and no intermediate agent can remove one from the resource's
          log. HDP should not duplicate that record. What HDP adds on such
          a deployment is the part that never produces a certificate: what
          the principal asked for and how each hop read it, which can
          travel in the certificates' own metadata
          (<xref target="capability-metadata"/>).
        </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.
          Integrity verification checks 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-max-hops" numbered="true" toc="default">
        <name>Recording Depth and Off-Record Delegation</name>
        <t>
          Limiting delegation depth is an anti-pattern for authorization.
          Nothing can prevent an agent from sharing a credential with
          another, so a limit on how far authority may be delegated does
          not stop delegation; it only stops the delegation from being
          visible. Capability systems rely instead on holding whoever
          shares a credential responsible for everything done with it,
          in the hope that this gives the sharer reason to delegate
          properly.
        </t>
        <t>
          A limit on what a record holds is different, because the record
          confers no authority. <tt>scope.max_hops</tt>
          (<xref target="scope"/>) sets how many hops the record holds.
          Once the chain is full it is not extended, and responsibility
          for anything delegated beyond that depth rests with the agent
          that appended the final hop, by the recursive accountability
          described in <xref target="minimum-disclosure"/>. That agent is
          usually the right one to hold responsible: an agent at the third
          hop that starts a swarm of a hundred sub-agents is accountable
          for all of them, whether or not each has a hop of its own. An
          issuer MAY therefore set <tt>max_hops</tt> to bound the size of
          a record, or to limit how much of an organisation's structure a
          record exposes. Opaque identifiers
          (<xref target="minimum-disclosure"/>) hide who is in a chain but
          not how deep it goes; <tt>max_hops</tt> limits the depth shown.
        </t>
        <t>
          Earlier revisions argued against <tt>max_hops</tt>: where an
          application gated actions on a valid chain, an exhausted budget
          pushed an agent that still needed to delegate to do so without
          appending a hop. That argument depended on the token being an
          input to access decisions. It no longer is
          (<xref target="what-hdp-is-not"/>). A full chain stops no action,
          so reaching <tt>max_hops</tt> gives no agent a reason to hide
          what it does.
        </t>
        <t>
          Delegation without appending a hop remains possible whatever
          <tt>max_hops</tt> says, because nothing in HDP forces an agent to
          extend the token. A planner can hand its token unchanged to a
          sub-agent, or pass the task along in-process, and the
          sub-agent's actions then go unrecorded or are recorded as the
          planner's. The chain still verifies, because verification checks
          only what was recorded. HDP cannot prevent this on its own. Two
          things limit it: the agent that passed the task on without a hop
          answers for what was done with it, and a recording component
          outside the agent's control (<xref target="chain"/>) records the
          hops an agent would leave out.
        </t>
        <t>
          Independently of <tt>max_hops</tt>, an auditor MAY flag chains
          longer than a locally configured limit, as a heuristic it can
          change without reissuing tokens. Chains are expected to grow
          longer as agents start agents, and
          <xref target="hash-linked-snapshots"/> describes how a store can
          hold them without repeating each chain prefix.
        </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 and one issued for Carol, each authorizing an
          update to the same dataset. 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 passes integrity verification, because
          verification 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 fits Alice's scope, so nothing in the record gives
          it away: it implicates Alice and leaves Carol's token silent. An
          action recorded under a token whose scope does not cover it at
          least shows up as a deviation; the harmful case is an action
          both scopes cover. Equally, an action that occurred in Alice's
          task belongs in Alice's record even if it exceeds her scope; 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. Joint approval
          (<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 does not detect or prevent this attack.
        </t>
        <t>
          Knowing whether a particular use of a permission went against
          what the principal wanted is a hard problem, and HDP does not
          attempt it. What HDP does is record every use, including
          attempted and blocked ones, and leave the judgement to the
          principal or an auditor, who can read the principal's request
          and each hop's reading of it side by side. An agent or recording
          component (<xref target="chain"/>) SHOULD record each attempted
          action, any deviation from the declared scope it noticed, and
          whether the action was blocked, in <tt>action_summary</tt> under
          the triggering task's token. Any blocking is done by the
          application's own access control, not by HDP, and blocking an
          action MUST NOT suppress its record. A violation observed after
          execution 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 because its chain has reached <tt>max_hops</tt>, the
          application SHOULD retain an integrity-protected incident record
          linked to the token digest and the triggering request. HDP v0.1
          adds no status field for this purpose; the distinction is
          explicit in the declaration.
        </t>
        <t>
          The record depends on agents, or recording components, actually
          recording actions. An agent that omits a hop is discussed in
          <xref target="security-truncation"/> and
          <xref target="security-max-hops"/>.
        </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 secret key. Implementations MUST:
        </t>
        <ul spacing="normal">
          <li>Store secret keys in a secrets manager, HSM, or equivalent
          secure enclave. Secret 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>, and retain every public key an auditor may need,
          with its compromise history, for the audit retention period
          (<xref target="historical-audit"/>). This does not require
          retaining retired secret keys.</li>
        </ul>
      </section>

      <section anchor="security-offline" numbered="true" toc="default">
        <name>Offline Verification Guarantee</name>
        <t>
          A correct implementation of integrity verification
          (<xref target="verification"/>) requires no network calls, no
          registry lookups, and no third-party contact. The complete trust
          state it requires is the issuer's Ed25519 public key (32 bytes).
        </t>
        <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 lets an auditor verify records long after they
          were made, in an air-gapped environment, and without the
          issuer's cooperation beyond having published its key.
        </t>
      </section>
    </section>

    <!-- ================================================================ -->
    <section anchor="capability-metadata" numbered="true" toc="default">
      <name>Carrying HDP Content in Capability Certificates</name>
      <t>
        On a deployment that already uses a capability system, the
        certificates presented at a resource are a record of the
        authority each agent exercised
        (<xref target="security-truncation"/>). What they do not usually
        record is what the principal asked for and how each agent read
        the task. This section describes carrying that content in the
        certificates' own metadata, in place of a separate HDP token. It
        is a sketch offered for review rather than a complete profile,
        and the member names in it are provisional.
      </t>
      <t>
        The certificates already record who delegated to whom, when,
        what authority was passed on, when it expires, and the chain back
        to the root. The carried content repeats none of that.
      </t>
      <t>
        The principal's request does not usually enter at the root. A
        service that controls a resource typically delegates first to its
        own software, which then delegates to an agent working on the
        principal's behalf. The request enters the chain at that agent,
        the one the principal prompted, and the delegations made before
        it carry no HDP content, since their delegators never saw the
        request. The carried content consists of the following members:
      </t>
      <ul spacing="normal">
        <li>
          <t>Only in the first certificate signed by the principal or
          by the agent the principal prompted, whether a delegation or,
          if that agent acts itself, an invocation:</t>
          <ul spacing="normal">
            <li><tt>intent</tt>: the principal's request, as in
            <tt>scope.intent</tt>.</li>
            <li><tt>principal</tt>: the principal's identifier and its
            type, as in <tt>principal.id</tt> and
            <tt>principal.id_type</tt>, subject to
            <xref target="minimum-disclosure"/>. OPTIONAL.</li>
            <li><tt>session</tt>: the session in which the principal made
            the request, as in <tt>header.session_id</tt>, so that the
            chain can be associated with the session's other
            records.</li>
            <li><tt>limits</tt>: anything the principal declared that the
            capability cannot express, such as the
            <tt>data_classification</tt>, <tt>network_egress</tt>, and
            <tt>persistence</tt> values of the scope. OPTIONAL. Like the
            scope, these record a declaration and restrict nothing.</li>
          </ul>
        </li>
        <li>
          <t>In that certificate and every delegation below it:</t>
          <ul spacing="normal">
            <li><tt>summary</tt>: the delegating agent's reading of the
            task it passes on, as it would appear in
            <tt>action_summary</tt>. An auditor finds drift by comparing
            the summaries with <tt>intent</tt>.</li>
            <li><tt>agent</tt>: the delegating agent's role, as in
            <tt>agent_type</tt>, and optionally a fingerprint of its
            model or binary, as in <tt>agent_fingerprint</tt>. The
            certificate identifies the delegator by its key, not by what
            was running behind it.</li>
            <li><tt>recorder</tt>: the component that wrote the summary,
            when it was not the agent itself (<xref target="chain"/>).
            OPTIONAL.</li>
          </ul>
        </li>
        <li>At invocation: the same <tt>summary</tt>, <tt>agent</tt>, and
        <tt>recorder</tt> members for the invoking agent, with the
        summary stating whether the action was attempted, blocked, or
        observed as a deviation (<xref target="chain"/>). The invocation
        already records what was asked of the resource, but not the
        agent's account of it.</li>
      </ul>
      <t>
        Each item is signed by the party whose certificate carries it.
        This gives the effect of per-agent signing
        (<xref target="hop-signing"/>) with the capability system's
        existing keys, and the chain presented at the resource ends at
        the invoker. Two properties of the standalone token do not carry
        over: a single issuer's signature over the principal's request,
        and a record of delegations that were never invoked, since a
        resource sees only the chains presented to it. As with the
        standalone token, the carried content is a record and MUST NOT
        be used as an input to any access decision
        (<xref target="what-hdp-is-not"/>).
      </t>

      <section anchor="capability-metadata-ucan" numbered="true" toc="default">
        <name>UCAN</name>
        <t>
          UCAN 1.0 delegations <xref target="UCAN-DELEGATION"/> and
          invocations <xref target="UCAN-INVOCATION"/> each have an
          optional <tt>meta</tt> field, a map that the issuer signs with
          the rest of the payload. The delegation specification describes
          <tt>meta</tt> as asserted, signed data that is not delegated
          authority, which is the status HDP content needs. This profile
          places HDP content under a single <tt>meta</tt> key,
          <tt>hdp</tt>. The example is shown in JSON for readability;
          UCAN 1.0 payloads are encoded in DAG-CBOR.
        </t>
        <sourcecode type="json"><![CDATA[
"meta": {
  "hdp": {
    "v"         : "0.1",
    "intent"    : "Analyze Q1 sales data and report.",
    "principal" : { "id": "usr_alice_opaque", "id_type": "opaque" },
    "session"   : "sess-20260326-abc123",
    "summary"   : "Decompose task; delegate the query to sub-agent.",
    "agent"     : { "type": "orchestrator" }
  }
}
        ]]></sourcecode>
        <t>
          The <tt>intent</tt>, <tt>principal</tt>, <tt>session</tt>, and
          <tt>limits</tt> members appear only in the first certificate
          signed by the principal or by the agent the principal prompted.
          The <tt>summary</tt> and <tt>agent</tt> members appear in that
          certificate and every one below it, including the invocation, as
          does <tt>recorder</tt> when present. An invocation's
          <tt>prf</tt> field lists the delegations it relies on, so a
          resource that retains its invocations together with their
          delegations holds the whole record, and UCAN receipts can record
          the result of each invocation alongside it.
        </t>
      </section>

      <section anchor="capability-metadata-zcap" numbered="true" toc="default">
        <name>ZCAP-LD</name>
        <t>
          A ZCAP-LD <xref target="W3C.ZCAP-LD"/> delegated capability is a
          JSON-LD document signed by the delegator with a Data Integrity
          proof. An invocation carries the delegated capability, and its
          <tt>capabilityChain</tt> embeds the parent capability in full,
          so content placed in each delegated capability would be signed
          by its delegator and reach the resource with the chain.
        </t>
        <t>
          The current ZCAP-LD draft does not say where such content
          belongs. It forbids additional fields in a root capability, says
          nothing either way about additional fields in a delegated
          capability, and provides the <tt>caveat</tt> property only for
          restrictions on use. HDP content is not a restriction, and MUST
          NOT be expressed as a caveat, since a caveat is an input to the
          access decision. The candidate this document puts forward is an
          additional property, <tt>hdp</tt>, on each delegated capability,
          with the same members as the UCAN form and defined in a JSON-LD
          context listed after the ZCAP-LD context. A root capability can
          carry no other fields, so a principal who controls the root
          records the request in the first capability the principal
          delegates. Whether ZCAP-LD
          implementations accept a delegated capability with such a
          property, and whether a context is the right way to define it,
          are open questions on which review is sought. So is where the
          invoking agent's content belongs: an invocation made with an
          HTTP signature has no document to carry it.
        </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 has no revocation: an
            HDP token is a record and is never honoured or refused
            (<xref target="what-hdp-is-not"/>), so there is nothing to
            revoke. Withdrawing authority belongs to the access control
            mechanism HDP travels alongside.
          </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 integrity verification is specific to agentic
          delegation records (per-hop signatures chained to the root
          signature) 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 who delegated what to whom, and UCAN's
          Invocation and Receipt objects record individual invocations and
          their results. A resource can retain them, and then holds a
          record of the authority exercised. What those objects do not record by default is the
          principal's request and each agent's reading of the task. A UCAN
          deployment can carry that content in its <tt>meta</tt> fields
          (<xref target="capability-metadata-ucan"/>) rather than in a
          separate HDP token. The standalone HDP token is intended for
          deployments with no capability chain to carry it, such as those
          using bearer tokens or API keys, or handing tasks between agents
          in-process.
        </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
          resource that retains the capability chains presented to it
          holds a record of the authority exercised. What the chain does
          not record is the principal's request or each agent's reading
          of the task. HDP neither defines nor enforces capabilities.
          <xref target="capability-metadata-zcap"/> discusses carrying
          HDP content in delegated capabilities; the form it takes there
          is an open question.
        </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, and <tt>network_egress</tt> and <tt>persistence</tt>
          map to ODRL permissions or prohibitions.
        </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="RFC5849">
          <front>
            <title>The OAuth 1.0 Protocol</title>
            <author initials="E." surname="Hammer-Lahav" fullname="Eran Hammer-Lahav" role="editor"/>
            <date year="2010" month="April"/>
          </front>
          <seriesInfo name="RFC" value="5849"/>
          <seriesInfo name="DOI" value="10.17487/RFC5849"/>
        </reference>

        <reference anchor="RFC6749">
          <front>
            <title>The OAuth 2.0 Authorization Framework</title>
            <author initials="D." surname="Hardt" fullname="Dick Hardt" role="editor"/>
            <date year="2012" month="October"/>
          </front>
          <seriesInfo name="RFC" value="6749"/>
          <seriesInfo name="DOI" value="10.17487/RFC6749"/>
        </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="UCAN-DELEGATION"
                   target="https://github.com/ucan-wg/delegation">
          <front>
            <title>UCAN Delegation Specification v1.0.0</title>
            <author>
              <organization>UCAN Working Group</organization>
            </author>
            <date/>
          </front>
        </reference>

        <reference anchor="UCAN-INVOCATION"
                   target="https://github.com/ucan-wg/invocation">
          <front>
            <title>UCAN Invocation Specification v1.0.0</title>
            <author>
              <organization>UCAN Working Group</organization>
            </author>
            <date/>
          </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, most recently in a section-by-section review of -02 on the
        W3C Credentials Community Group list and the discussion that
        followed. He pointed out that relying on the token before an
        action would add a second access control mechanism, a well-known
        hazard, which led to the removal of live use in this revision
        (<xref target="what-hdp-is-not"/>). His reviews also shaped the
        following: the treatment of recording depth
        (<xref target="security-max-hops"/>); the recursive accountability
        argument, the guidance on delegate identifiers, including
        identifiers known only to the audit system, and the case for
        field-level encryption (<xref target="minimum-disclosure"/>);
        recording by a component outside the agent's control and the
        free-form <tt>agent_type</tt> (<xref target="chain"/>); the
        planned nested permission structure and the critique of the
        coarse <tt>scope</tt> values (<xref target="scope"/>); carrying
        HDP content in capability certificates
        (<xref target="capability-metadata"/>) and the view that such
        certificates are the better record of exercised authority
        (<xref target="security-truncation"/>); the chain-length concern
        behind hash-linked snapshots
        (<xref target="hash-linked-snapshots"/>); the correction to the
        stated cost of single-key signing, the case for keeping issuer
        signing as the baseline, and support for a fresh key per
        delegation (<xref target="hop-signing"/>); the revised
        attribution example (<xref target="security-attribution"/>); the
        position that HDP records every use and leaves the judgement to
        the user (<xref target="security-prompt-injection"/>); the use of
        "secret key" in place of "private key"; and the insistence that
        this document say plainly what HDP is not. Acknowledgment does not
        imply endorsement of the design choices that remain.
      </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-03:</dt>
        <dd>Incorporates a section-by-section review of -02 on the W3C
        Credentials Community Group list and the discussion that
        followed. HDP is now a record only: an HDP token MUST NOT be used
        as an input to any access decision
        (<xref target="what-hdp-is-not"/>). Live acceptance, the lifecycle
        and session binding checks, replay defense, and verifier-local
        revocation are removed. <tt>expires_at</tt> and
        <tt>session_id</tt> remain in the wire format as record metadata
        (<xref target="header"/>). Verification is now integrity
        verification in five steps (<xref target="verification"/>), and
        audit tooling reports integrity, the recording period, the
        session, and linked-record relationships separately
        (<xref target="historical-audit"/>). <tt>max_hops</tt> is kept
        and redefined as the depth the record holds, with the agent at the
        last recorded hop accountable for delegation beyond it
        (<xref target="security-max-hops"/>); -02 argued against the
        field. Added carrying HDP content in UCAN and ZCAP-LD metadata
        (<xref target="capability-metadata"/>) and hash-linked snapshots
        (<xref target="hash-linked-snapshots"/>). Issuer signing remains
        the baseline, with per-agent signing planned as an option
        (<xref target="hop-signing"/>). Re-authorization is recast as
        superseding records (<xref target="reauthorization"/>), and
        multi-principal delegation as joint approval, with the untagged
        <tt>parent_token_id</tt> stated as a known weakness
        (<xref target="multi-principal"/>). Recommended that a component
        outside the agent's control record hops, and made
        <tt>agent_type</tt> free-form (<xref target="chain"/>). Described
        the planned nested permission structure (<xref target="scope"/>).
        Revised the rationale for the query-parameter ban
        (<xref target="http-header"/>), the treatment of stripped tokens
        and field-level encryption (<xref target="minimum-disclosure"/>),
        the attribution example (<xref target="security-attribution"/>),
        prompt injection (<xref target="security-prompt-injection"/>),
        and the UCAN and ZCAP-LD comparisons. Replaced "private key" with
        "secret key". The token structure and signature payloads are
        unchanged and remain HDP v0.1; <tt>agent_type</tt> now accepts any
        string.</dd>
        <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 (Section 10.6 of -02);
        re-authorization is described as lineage rather than revocation
        (<xref target="reauthorization"/>); the 24-hour default lifetime
        is removed (Section 10.5 of -02). 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"/> (then titled 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), a revocation section (removed in -03),
        <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>
