HDP
Human Delegation Provenance Protocol
The normative v0.1 specification of the Human Delegation Provenance Protocol, aligned with IETF draft-03. HDP is a signed record of what the human asked for and how each agent read it, never an input to access decisions. It defines the token structure, Ed25519 signing procedures, offline integrity verification, audit results, the HTTP transport bindings, and carrying HDP content in UCAN and ZCAP-LD.
- Status
- Draft · open for comment
- Version
- v0.1
- Revision
- IETF draft-03
- Updated
- 6 October 2026
- Signing
- Ed25519 · RFC 8032
- Canonicalization
- RFC 8785
- License
- Apache 2.0
- arXiv
- 2604.04522
Contents
Contents
Status of this document
This document is the v0.1 specification of the Human Delegation Provenance Protocol, and is the reference cited as [HDP-SPEC] by the IETF Internet-Draft draft-helixar-hdp-agentic-delegation-03. It is aligned with revision -03 and serves as the standing normative text for that citation.
HDP v0.1 is published for comment and interoperability testing. It is not an IETF standard, and publication of the Internet-Draft does not imply IETF endorsement. The field names, signing procedures, and integrity verification described here are implemented by the reference libraries, which follow revision -03 as of HDP 0.2.0.
1Overview#
Autonomous AI agents increasingly execute consequential actions: sending email, modifying files, running code, calling APIs, and transacting on behalf of people. When a human authorizes an orchestrator agent, which delegates to sub-agents, which delegate again to tool-execution agents, the originating human authorization becomes disconnected from the terminal action. There is no standard record of the authorization chain.
That gap creates accountability and auditability problems:
- Post-hoc audits cannot reconstruct who approved what, and when.
- 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.
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 (§3.4).
HDP addresses this by defining a token that:
- Records the human principal, their request and declared scope, and the session in which they gave it.
- Accumulates a cryptographically signed hop record for each agent that handles the token.
- Allows an auditor to verify the entire chain, root signature plus all hop signatures, using only the issuer’s Ed25519 public key.
1.1What HDP is not#
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 (§13.2), a capability system such as UCAN or ZCAP-LD (§13.4, §13.5), or something else. HDP is designed to travel alongside such mechanisms, not to replace them, and not to be an input to them.
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.
Several parts of this document can be misread as authorization if this distinction is not kept in view. The scope object (§3.3) records what the human declared, in fields named authorized_tools and authorized_resources among others; it is a signed record of the authorization event, not a grant. Integrity verification (§5) establishes that a record is authentic and intact, not that anyone may act. The HTTP transport (§8) 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.
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.
1.2Motivation#
The need for agentic delegation provenance is not hypothetical. Production deployments of AI orchestration systems, including LangChain, AutoGPT, CrewAI, and similar frameworks, 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 receive access to higher-consequence tools.
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.
1.3Design goals#
HDP is designed with the following goals in order of priority:
- 1.Offline verifiability. Verifying a record’s integrity MUST require only the issuer’s public key. No network call, registry lookup, or third-party endpoint is required.
- 2.Self-sovereignty. Any organization MUST be able to issue and verify HDP tokens without registering with a central authority or anchoring to a third-party key.
- 3.Tamper evidence. 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 §10.4.
- 4.Minimal footprint. The protocol MUST be implementable in any language with Ed25519 and JSON support. No mandatory infrastructure beyond key management is required.
- 5.Privacy by design. Principal identity fields MUST be separable from the audit-relevant parts of the token, so tokens can be transmitted to agents without exposing PII.
1.4Relationship to IPP (draft-haberkamp-ipp-01)#
The Intent Provenance Protocol (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 §13. The two protocols are not interoperable. HDP is offered as a distinct design point, not a revision of IPP.
The full HDP protocol specification is available at [HDP-SPEC]. A TypeScript reference implementation is available at [HDP-IMPL]. At the time of writing it implements -02 of this document, including the checks before an action that this revision removes (§1.1), and is being updated to match.
1.5Generality of the chain-of-custody mechanism#
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.
This document profiles that mechanism for one application: human-authorized agentic delegation. In this profile the carried payload is the scope object (§3.3) 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 (§4, §4.1, §4.2) and verification (§5) procedures are described in a payload-agnostic way so future profiles can reuse them unchanged.
2Terminology#
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 RFC 2119 and RFC 8174 when, and only when, they appear in all capitals.
- Issuer
- The system or person that creates and signs an HDP token on behalf of a human principal.
- Principal
- The human who authorized the agentic task. Represented in the token’s
principalobject. - Agent
- Any AI system, model, or automated process that receives and acts upon an HDP token.
- Hop
- A single delegation event, recorded as a signed entry in the token’s
chainarray. - Root signature
- The Ed25519 signature over the header, principal, and scope, computed by the issuer at token creation time.
- Hop signature
- 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.
- Session
- A logical unit of work identified by a
session_idstring, established between the issuer and the agent framework before the token is issued. - Verifier
- Any party that checks the integrity of an HDP token (§5). In practice the verifier is an audit system or a human reviewer’s tooling (§1.1).
- Presenter
- The agent that transmits a token with a task. In a complete chain the presenter is the agent that appended the final hop.
- Recording component
- A component outside an agent’s control, such as a virtual machine sidecar, tool gateway, or MCP proxy, that records hops for the agent (§3.4).
3Token structure#
An HDP token is a JSON object with six top-level fields. The token MUST conform to the structure below. All integer timestamps are Unix milliseconds, that is, milliseconds since 1970-01-01T00:00:00Z.
{
"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
}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.
The integer fields header.issued_at, header.expires_at, and each hop’s timestamp and parent_hop MUST be in the inclusive range 0 through 9007199254740991, that is 253 − 1. Each hop’s seq, and scope.max_hops where present, MUST be in the inclusive range 1 through 9007199254740991. These are JSON numbers, not strings. Implementations MUST check the numeric value 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 insideprincipal.metadata, remain subject to RFC 8785.
3.1Header#
The header object carries the record’s identifier, its timing, and the session in which the human authorized the task.
{
"token_id" : "550e8400-e29b-41d4-a716-446655440000",
"issued_at" : 1711483200000,
"expires_at" : 1711569600000,
"session_id" : "sess-20260326-abc123",
"version" : "0.1",
"parent_token_id" : "..."
}token_idREQUIRED- A version 4 UUID (RFC 9562). Unique identifier for this token.
issued_atREQUIRED- Unix milliseconds. Time of issuance.
expires_atREQUIRED- Unix milliseconds. MUST be greater than
issued_at. Records the end of the period for which the principal authorized the task. It has no effect on integrity verification (§5), and a service treats a token received after this time no differently from any other (§1.1). A hop whose timestamp is at or afterexpires_atis recorded like any other, and an auditor reports it as recorded after the authorization period ended (§5.1). HDP defines no default lifetime. session_idREQUIRED- 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 (§6, §7).
versionREQUIRED- MUST equal the value of the top-level
hdpfield.
3.2Principal#
The principal object identifies the authorizing human. It MUST contain id and id_type. All other fields are OPTIONAL.
{
"id" : "usr_alice_opaque",
"id_type" : "opaque",
"display_name" : "Alice Chen",
"poh_credential" : "...",
"metadata" : {}
}idREQUIRED- Identifier for the principal, interpreted according to
id_type. id_typeREQUIRED- One of the defined values below, or a custom string prefixed with
x-. display_nameOPTIONAL- Human-readable name. Omit where the receiving agent does not require a human-readable identity.
poh_credentialOPTIONAL- A Proof-of-Humanity credential. Verification semantics are application-defined. See §9.
metadataOPTIONAL- Application-defined object. Not interpreted by the protocol.
Defined id_type values:
opaque- Application-defined identifier. No resolution semantics are implied.
email- An email address as defined in RFC 5321.
uuid- A UUID as defined in RFC 9562.
did- W3C Decentralized Identifier. DID resolution is application-defined and not required by this protocol.
poh- A Proof-of-Humanity credential identifier. Verification semantics are application-defined; see §9.3.
3.3Scope#
The scope object records what the human authorized. It is signed as part of the root signature and MUST NOT be modified after issuance.
The scope 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. See §1.1.
{
"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
}The values above are illustrative. In particular, the max_hops value shown is an issuer choice for this example, not a protocol limit.
intentREQUIRED- The principal’s request, in natural language. Free-form string. It is what an auditor compares each hop’s action_summary against, and SHOULD be written to be both human- and agent-readable. Where practical it SHOULD be the principal’s own words.
data_classificationREQUIRED- One of
public,internal,confidential, orrestricted. Records the sensitivity level of data the principal declared the agent may access. network_egressREQUIRED- Boolean. Records whether the principal declared that the agent may make outbound network requests.
persistenceREQUIRED- Boolean. Records whether the principal declared that the agent may write persistent state.
authorized_toolsOPTIONAL- Array of tool identifiers the principal declared as authorized. The field records the declaration; it does not grant access to the tools named.
authorized_resourcesOPTIONAL- Array of resource identifiers, such as URIs or paths, the principal declared as authorized. As with authorized_tools, this records the declaration and grants nothing.
max_hopsOPTIONAL- Positive integer, chosen by the issuer: the number of hops this record holds. Once the chain holds
max_hopshops it is not extended (§4.3, rule 4). 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 (§10.5). An issuer MAY choose any value within the representation bounds in §3. Ifmax_hopsis absent, HDP places no limit on the depth recorded.
The fixed values are also too coarse. The four data_classification levels are not the ones every issuer uses, and a single persistence flag cannot record that a principal let an agent write log records but nothing else.
The next token version is planned to replace authorized_tools, authorized_resources, data_classification, network_egress, and persistence 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.
{
"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"] }
}
}3.4Chain#
The chain array is append-only. Each element records a single delegation event, called a hop. The array is empty at issuance and grows as the token passes between agents. Agents MUST NOT remove or modify existing entries.
{
"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>"
}seqREQUIRED- Positive integer, starting at 1. MUST be exactly one greater than the previous hop’s
seq. Gaps are a protocol violation. agent_idREQUIRED- Identifier of the agent adding this hop. The identifier need not be globally meaningful; it is sufficient that the delegator that assigned it can interpret it (§9.1).
agent_typeREQUIRED- String. A descriptive label for the agent’s role, such as
orchestrator,sub-agent, ortool-executor. 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 stringcustom; tokens using those values remain valid. agent_fingerprintOPTIONAL- Model or binary fingerprint for the acting agent.
timestampREQUIRED- 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 timestamp (§4.3, rule 5).
action_summaryREQUIRED- 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 (§10.1).
parent_hopREQUIRED- Non-negative integer. Index of the hop that triggered this delegation, where
0indicates the root human authorization.
3.5Signature#
The signature object carries the root signature computed by the issuer.
{
"kid" : "alice-signing-key-v1",
"alg" : "Ed25519",
"value" : "<base64url Ed25519 signature over canonical JSON>"
}algREQUIRED- MUST be
Ed25519for HDP v0.1. Verifiers MUST reject any other value. kidOPTIONAL- Key identifier. SHOULD be used by verifiers to select the correct public key when multiple keys are in circulation.
valueREQUIRED- Base64url-encoded, no padding, Ed25519 signature over the canonical JSON payload. See §4.1.
4Cryptographic signing#
4.1Root signature#
The root signature is computed by the issuer at token creation time. It covers the fields that constitute the human authorization event: the header, principal, and scope.
- 1.Construct the unsigned token object containing the
hdp,header,principal,scope, andchainfields, wherechainis an empty array at issuance. - 2.Serialize the object to canonical JSON per RFC 8785.
- 3.Compute the Ed25519 signature over the canonical JSON bytes using the issuer’s secret key.
- 4.Encode the signature bytes as base64url with no padding.
- 5.Attach the
signatureobject, carryingkid,alg, andvalue, to the token.
4.2Hop signature#
Each hop MUST carry a hop_signature. It binds the new hop record to the entire accumulated delegation history and to the root signature, which makes retroactive chain modification detectable.
- 1.Construct the new hop record, with all fields except
hop_signature. - 2.Build the signing payload as a JSON array of the previously signed hops, each WITH its
hop_signature, followed by the new hop WITHOUT itshop_signature. - 3.Prepend the root signature value, a base64url string, as the array’s first element. This chains the hop signature to the root.
- 4.Serialize the array to canonical JSON per RFC 8785.
- 5.Compute the Ed25519 signature over the canonical JSON bytes using the issuer’s secret key.
- 6.Encode as base64url and attach as the
hop_signaturefield on the new hop record. - 7.Append the signed hop to the token’s
chainarray.
[ root_signature_value, // base64url string, chains this hop to the root hop_1, // WITH its hop_signature hop_2, // WITH its hop_signature ... new_hop_unsigned // WITHOUT its hop_signature ]
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.
First, a v0.1 hop signature attests that the issuer recorded a delegation claim naming the agent in agent_id. 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.
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.
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.
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 (RFC 5849) required every client to sign its requests, which developers found hard to get right, and OAuth 2.0 (RFC 6749) 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.
4.3Chain integrity rules#
These rules govern chain construction and MUST be enforced by both extenders and verifiers.
- 1.Hop
seqvalues MUST start at 1 and increment by exactly 1. No gaps are permitted. - 2.Existing hop records MUST NOT be modified or removed.
- 3.A hop’s
parent_hopMUST reference a valid prior hop index:0for the root human authorization, or theseqvalue of a prior hop. - 4.If
scope.max_hopsis 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 (§10.5). - 5.Each hop’s
timestampMUST be greater than or equal to the timestamp of the hop before it. A chain in which a hop’s timestamp is less than its predecessor’s fails integrity verification (§5, step 3). Because the issuer signs every hop in v0.1, all hop timestamps pass through one clock domain, which is what makes this rule enforceable. - 6.The
hop_signaturefield MUST be present on every hop. A hop without one is a protocol violation and is a verification failure.
5Integrity verification#
Integrity verification establishes that a record is as the issuer signed it. A verifier MUST first validate the input as specified in §3, 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.
- 1.Version check. The
hdpfield MUST contain a recognized protocol version string. For this specification the only recognized value is0.1. Theheader.versionfield MUST equal thehdpfield; a mismatch is a failure. - 2.Root signature verification. Reconstruct the canonical JSON payload by removing the
signaturefield and resettingchainto an empty array, its value when the root signature was computed, then serializing the remaining token object per RFC 8785. Verify thatsignature.algisEd25519, then verifysignature.valueagainst this payload using the issuer’s public key. A failure indicates tampering with the header, principal, or scope. - 3.Hop sequence and structure integrity. For each hop, verify that
seqequals its index plus one; any gap or duplication is a failure. Verify that eachparent_hopreferences either0, the root authorization, or theseqof a prior hop; an out-of-range value is a failure (§4.3, rule 3). Verify that each hop’stimestampis greater than or equal to that of the hop before it; a decrease is a failure (rule 5). - 4.Hop signature verification. For each hop at index
i: confirmhop_signatureis present, where absence is a failure; reconstruct the signing payload described in §4.2 using hops0throughi-1with their signatures, plus the hop atiwithout its own, prepended by the root signature value; then serialize per RFC 8785 and verify against the issuer’s public key, the same key used for the root signature in HDP v0.1. - 5.Recorded depth check. If
scope.max_hopsis defined, the length ofchainMUST NOT exceed it.
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 (§1.1).
If principal.poh_credential is present, an auditor MAY check it with an application-defined verifier and report the result separately from record integrity (§9.3).
5.1Audit results#
Audit tooling MUST report the following results separately. They are results of examining a record, not new fields in an HDP token.
- Record integrity
- Whether the record conforms to the format and passes the steps of §5, using a trusted archived issuer key. If the key or a supported verification algorithm is unavailable, integrity is unverified rather than valid.
- Recording period
- Whether any hop’s
timestampis at or afterheader.expires_at. Such hops are reported as recorded after the authorization period ended, not discarded. Hop timestamps are declared values (§3.4). - Session
- Where the audit concerns a particular session, whether
header.session_idmatches it. A mismatch means the record belongs to another session; it does not make the record invalid. - Linked records
- For a record with
parent_token_id, its relationship to the parent: supersession, joint approval, or unknown, determined as described in §7.
6Superseding records#
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 max_hops and the deployment wants recording to continue. The issuer then issues a new token that supersedes the original.
Supersession is recorded by setting header.parent_token_id to the token_id 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.
A superseding token:
- Has a new
token_id,issued_at, andexpires_at. - Inherits
session_id,principal, andscopefrom the original unless explicitly overridden. - Starts with an empty chain.
- Records
parent_token_idpointing to the original, so that an auditor can follow how the task’s authorization changed.
7Joint approval by several principals#
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 parent_token_id equal to T1’s token_id. Each token is independently signed with its issuer’s key.
To examine a joint approval, an auditor MUST:
- 1.Verify the integrity of each token against its issuer’s public key (§5).
- 2.Verify that
T[i].header.parent_token_idequalsT[i-1].header.token_idfor alligreater than 0. - 3.Verify that all tokens in the chain share the same
session_id. - 4.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.
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.
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.
8Transport#
The HTTP header field names defined below do not use the X- prefix, in accordance with RFC 6648.
8.1HTTP header: HDP-Token#
Tokens MAY be transmitted in HTTP requests and responses using the HDP-Token header. The value is the base64url encoding, no padding, of the UTF-8 JSON serialization of the complete token object.
POST /api/task HTTP/1.1 Host: agent.example.com HDP-Token: eyJoZHAiOiIwLjEiLCJoZWFkZXIiOnsi... Content-Type: application/json
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 (§3.4), 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 (§1.1).
HTTP header values are routinely written to access logs, proxy logs, and error reports, and the HDP-Token value contains the principal object and the full chain. Deployments SHOULD configure logging to treat HDP-Token as sensitive, as they would an Authorization header.
8.2Token by reference: HDP-Token-Ref#
Where token size is a concern, for example with large chains, the token MAY be stored server-side and referenced using the HDP-Token-Ref header. The reference is either the token’s token_id, or a content-addressed reference: the string sha256: followed by the base64url encoding, no padding, of the SHA-256 digest (RFC 6234) of the token’s canonical JSON serialization per RFC 8785.
POST /api/task HTTP/1.1 Host: agent.example.com HDP-Token-Ref: 550e8400-e29b-41d4-a716-446655440000
A recipient resolving a content-addressed reference MUST validate the resolved token’s input representation, serialize the complete token, including signature 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 MUST be exactly 32 bytes encoded as canonical unpadded base64url; a malformed encoding 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 header.token_id MUST identify the same UUID, compared by its 128-bit value rather than hexadecimal letter case; a mismatch MUST be rejected.
Successful reference resolution MUST be followed by integrity verification (§5). A valid signature alone does not establish that the requested reference was resolved correctly. Implementations using token-by-reference MUST secure the token store and use TLS for all reference resolution.
8.3Hash-linked snapshots#
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:
- The base entry is the token as issued, with an empty chain.
- Each later entry is a JSON object with two members:
prev, the content-addressed reference (§8.2) of the snapshot it extends, andhop, the one hop appended.
{
"prev" : "sha256:<digest of the snapshot this entry extends>",
"hop" : { "seq": 3, "agent_id": "...", "hop_signature": "..." }
}The store keeps each entry under the content-addressed reference of the complete snapshot it produces: the token that results from appending hop to the snapshot named by prev. 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 prev back to the base entry, appending the hops in order, and checking the digest as §8.2 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.
Hash-linking saves storage, not verification. A hop signature covers every hop before it (§4.2), so an auditor still has to fetch and check every hop up to the snapshot being verified.
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 action_summary SHOULD refer to the other record by content-addressed reference rather than embedding it.
8.4Key distribution#
Issuers that wish to publish their Ed25519 public keys for automated discovery SHOULD serve a JSON document at /.well-known/hdp-keys.json with the following structure.
{
"keys": [
{
"kid" : "alice-signing-key-v1",
"alg" : "Ed25519",
"pub" : "<base64url-encoded 32-byte Ed25519 public key>"
}
]
}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 (§10.9). A verifier that has obtained the key by other means has no reason to consult it.
The format is intentionally minimal and implementations MAY extend it with additional metadata. The alg field MUST be Ed25519 for v0.1 keys. Consumers MUST reject entries with unrecognized alg values, and MUST validate that the decoded public key is exactly 32 bytes.
9Privacy considerations#
9.1Minimum-disclosure principal fields#
The principal object may contain PII, including an email address or display name. Issuers SHOULD apply the principle of minimum disclosure when constructing tokens that will traverse multiple agents.
- Use
id_type: "opaque"with an application-internal identifier rather than embedding the user’s email address in tokens that will be sent to third-party agents. - Omit
display_namewhen the receiving agent does not require a human-readable identity.
The same principle applies to the agent_id field in hop records (§3.4). An agent_id 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 agent_id globally. It needs the delegator at each step to be able to identify the party it delegated to, and the agent_id and its action_summary are bound into the signed chain for exactly that purpose.
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 (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 (§10.5).
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 principal 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 (§1.1), so fields the agents do not need, such as principal 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.
9.2Data retention and the right to erasure#
HDP tokens may constitute personal data under applicable privacy regulations, such as GDPR Article 4(1), when the principal.id or principal.display_name fields contain directly or indirectly identifying information.
Implementations SHOULD:
- Store tokens with explicit retention periods set by the audit purpose they serve.
- Provide deletion mechanisms that remove stored tokens upon erasure requests.
- Use opaque identifiers in
principal.idwhere possible, maintaining a separate mapping that can be destroyed independently of the token audit log.
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.
9.3Proof of humanity#
The optional principal.poh_credential field MAY carry a credential attesting that the principal is a human, for example 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.
An auditor that checks the credential reports the result separately from record integrity (§5). 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.
10Security considerations#
10.1Threat model#
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 (§1.1); 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.
10.2Token forgery#
A forged token, one whose header, principal, or scope fields do not match the original issuance, will fail step 2 of integrity verification (§5), the 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 that does not possess the issuer’s secret key cannot produce a valid root signature for a modified token.
10.3Chain tampering#
Modification, reordering, or removal of any non-trailing hop is detectable: it either breaks the hop sequence check (§5, 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 similarly fails 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 §10.4.
10.4Chain truncation and completeness#
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 chain, 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.
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 (§10.1).
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 agent_id 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.
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 scope. 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.
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 (§11).
Concurrent extensions from the same prefix can produce two valid branches with the same token_id, hop count, and final agent_id, 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.
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.
Applications requiring evidence of a particular observed or final record SHOULD retain an authenticated receipt or settlement record binding the token_id, session_id, complete token digest as defined in §8.2, 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 (§10.5). These receipts are application-layer artifacts, not new token fields.
10.5Recording depth and off-record delegation#
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.
A limit on what a record holds is different, because the record confers no authority. scope.max_hops (§3.3) 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 §9.1. 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 max_hops to bound the size of a record, or to limit how much of an organisation’s structure a record exposes. Opaque identifiers (§9.1) hide who is in a chain but not how deep it goes; max_hops limits the depth shown.
Delegation without appending a hop remains possible whatever max_hops 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 (§3.4) records the hops an agent would leave out.
Independently of max_hops, 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 §8.3 describes how a store can hold them without repeating each chain prefix.
10.6Attribution across concurrent tokens#
An agent may hold more than one valid HDP token whose scope 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 action_summary. 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.
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.
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 (§7) does not address this case: it covers tokens linked by parent_token_id that share a session_id, 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 (§1.1).
10.7Prompt injection#
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, such as a malicious web page or document. HDP does not detect or prevent this attack.
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 (§3.4) SHOULD record each attempted action, any deviation from the declared scope it noticed, and whether the action was blocked, in action_summary 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 max_hops, 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.
The record depends on agents, or recording components, actually recording actions. An agent that omits a hop is discussed in §10.4 and §10.5.
10.8Key management#
The security of all HDP guarantees depends on the confidentiality of the issuer’s Ed25519 secret key. Implementations MUST:
- 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.
- Use distinct key pairs per environment, development, staging, and production.
- Support key rotation by issuing new tokens with a new
kid, and retain every public key an auditor may need, with its compromise history, for the audit retention period (§5.1). This does not require retaining retired secret keys.
10.9Offline verification guarantee#
A correct implementation of integrity verification (§5) 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.
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 §4.2 would preserve it, since the verifier would still resolve only the issuer’s key out of band.
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.
11Carrying HDP content in capability certificates#
On a deployment that already uses a capability system, the certificates presented at a resource are a record of the authority each agent exercised (§10.4). 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.
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.
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.
intent- The principal’s request, as in
scope.intent. 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. principal- OPTIONAL. The principal’s identifier and its type, as in
principal.idandprincipal.id_type, subject to §9.1. Only in that first certificate. session- The session in which the principal made the request, as in
header.session_id, so that the chain can be associated with the session’s other records. Only in that first certificate. limits- OPTIONAL. Anything the principal declared that the capability cannot express, such as the
data_classification,network_egress, andpersistencevalues of the scope. Like the scope, these record a declaration and restrict nothing. Only in that first certificate. summary- The delegating agent’s reading of the task it passes on, as it would appear in
action_summary. An auditor finds drift by comparing the summaries withintent. In that certificate and every delegation below it. agent- The delegating agent’s role, as in
agent_type, and optionally a fingerprint of its model or binary, as inagent_fingerprint. The certificate identifies the delegator by its key, not by what was running behind it. In that certificate and every delegation below it. recorder- OPTIONAL. The component that wrote the summary, when it was not the agent itself (§3.4). In that certificate and every delegation below it.
At invocation, the same summary, agent, and recorder members are carried for the invoking agent, with the summary stating whether the action was attempted, blocked, or observed as a deviation (§3.4). The invocation already records what was asked of the resource, but not the agent’s account of it.
Each item is signed by the party whose certificate carries it. This gives the effect of per-agent signing (§4.2) 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 (§1.1).
11.1UCAN#
UCAN 1.0 delegations (UCAN Delegation) and invocations (UCAN Invocation) each have an optional meta field, a map that the issuer signs with the rest of the payload. The delegation specification describes meta as asserted, signed data that is not delegated authority, which is the status HDP content needs. This profile places HDP content under a single meta key, hdp. The example is shown in JSON for readability; UCAN 1.0 payloads are encoded in DAG-CBOR.
"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" }
}
}The intent, principal, session, and limits members appear only in the first certificate signed by the principal or by the agent the principal prompted. The summary and agent members appear in that certificate and every one below it, including the invocation, as does recorder when present. An invocation’s prf 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.
11.2ZCAP-LD#
A ZCAP-LD (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 capabilityChain 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.
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 caveat 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, hdp, 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.
12IANA considerations#
12.1HTTP header field registration#
This document requests registration of the following HTTP header fields in the Hypertext Transfer Protocol (HTTP) Field Name Registry.
- HDP-Token
HDP-Token
Status: provisional
Reference: this document, §8.1
Comments: Carries a base64url-encoded HDP token for agentic delegation provenance.- HDP-Token-Ref
HDP-Token-Ref
Status: provisional
Reference: this document, §8.2
Comments: Carries a UUIDtoken_ididentifying a fixed token snapshot, or asha256content-addressed reference to a complete HDP token.
12.2Media type registration#
This document requests registration of the application/hdp-token+json media type in the Media Types registry, following the procedures of RFC 6838.
- Type name
application- Subtype name
hdp-token+json- Required parameters
- N/A
- Optional parameters
- N/A
- Encoding considerations
- Binary; the token is a UTF-8 JSON object (RFC 8259).
- Security considerations
- See §10 of this document.
- Interoperability considerations
- The token uses the
+jsonstructured syntax suffix (RFC 6839); generic JSON processors can parse it. HDP-specific semantics are defined in this document. - Published specification
- This document.
- Applications that use this media type
- Agentic AI frameworks and services that exchange HDP delegation-provenance tokens.
- Fragment identifier considerations
- N/A
- Additional information
- Deprecated alias names: none. Magic number(s): none. File extension(s): none. Macintosh file type code(s): none.
- Person and email address to contact
- Asiri Dalugoda <[email protected]>
- Intended usage
- COMMON
- Restrictions on usage
- None
- Author
- Asiri Dalugoda
- Change controller
- IETF
12.3Well-known URI registration#
This document requests registration of the following entry in the Well-Known URIs registry, per RFC 8615.
- URI suffix
hdp-keys.json- Change controller
- IETF
- Specification document
- This document, §8.4.
- Status
- provisional
- Related information
- Serves a JSON document listing an issuer’s Ed25519 public keys for HDP token verification.
13Comparison with related work#
13.1IPP (draft-haberkamp-ipp-01)#
The Intent Provenance Protocol (IPP) and HDP address the same root problem with different architectural trade-offs. The key differences are:
- 1.Revocation model. 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
offline_grace_period_msand 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 (§1.1), so there is nothing to revoke. Withdrawing authority belongs to the access control mechanism HDP travels alongside. - 2.Trust anchor. IPP tokens contain a genesis object, the Genesis Seal, a cryptographic artifact linking every token to the specification author’s public key at the IPP founding public key. Self-hosted IPP deployments are cryptographically bound to this third-party key. HDP tokens carry no genesis seal and no specification-level attribution; any organization can issue and verify HDP tokens without anchoring to a third party.
- 3.Identity model. IPP mandates W3C DID Core-conformant principal identifiers. HDP supports
id_type: "opaque"as a first-class option, making DID infrastructure optional rather than required.
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.
13.2OAuth 2.0 Token Exchange (RFC 8693)#
OAuth 2.0 Token Exchange 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.
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.
13.3JSON Web Token (RFC 7519)#
JSON Web Token provides a general-purpose signed claims format. HDP differs from JWT in three respects:
- HDP tokens carry an append-only, per-hop-signed delegation chain (
chain) that has no equivalent in the JWT standard claims set. - HDP uses RFC 8785 canonical JSON for signing payloads, rather than the base64url-encoded header.payload convention used by JWS (RFC 7515). This allows direct JSON manipulation without base64 decoding.
- HDP’s integrity verification is specific to agentic delegation records, with per-hop signatures chained to the root signature, rather than general-purpose.
13.4UCAN (User Controlled Authorization Networks)#
UCAN (User Controlled Authorization Networks) 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.
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 meta fields (§11.1) 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.
13.5ZCAP-LD (Authorization Capabilities for Linked Data)#
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. §11.2 discusses carrying HDP content in delegated capabilities; the form it takes there is an open question.
13.6ODRL and the Verifiable Credentials Data Model#
The Open Digital Rights Language (ODRL) (W3C ODRL) is a W3C Recommendation for expressing permissions, prohibitions, and constraints. Several fields in HDP’s scope object (§3.3) overlap with concepts ODRL already defines: authorized_tools and authorized_resources correspond to ODRL actions and targets, and network_egress and persistence map to ODRL permissions or prohibitions.
HDP v0.1 deliberately retains a small, self-contained scope 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.
A further limitation of the v0.1 scope 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 scope. Per-hop caveats, which only the verifier and any attenuating agent would need to interpret, are planned for a future version.
Because the chain-of-custody mechanism is payload-agnostic (§1.5), a future HDP profile MAY carry an ODRL policy as its payload in place of the native scope object. Such a profile would gain a natural binding to the Verifiable Credentials Data Model 2.0 (W3C VC Data Model 2.0), whose termsOfUse property can carry ODRL policies. This binding is identified as future work and is not specified in this document.
AAppendix A: complete token example#
A complete token with a two-hop delegation chain. Signature values are truncated for readability. This example validates against the published JSON Schema. The scope lists a resource for each tool that acts on one, and each hop names the resource it declares acting on; §3.3 explains why v0.1 cannot bind tools to resources structurally.
{
"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..."
}
}BAppendix B: revision history#
This document tracks the revisions of the Internet-Draft it is cited by. The token structure and signature payloads have not changed across any revision listed here and remain HDP v0.1: a token issued under revision -00 has the same structure and the same signature payloads as one issued today, and revision -03 only widens agent_type to accept any string, so every earlier token remains valid. What has changed is what implementers and auditors are required to do with a token, and in revision -03, what a token is for. Revisions are listed newest first.
- -03 · 6 October 2026 · current
- 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 (§1.1). Live acceptance, the lifecycle and session binding checks, replay defense, and verifier-local revocation are removed;
expires_atandsession_idremain in the wire format as record metadata (§3.1). Verification is now integrity verification in five steps (§5), and audit tooling reports integrity, the recording period, the session, and linked-record relationships separately (§5.1).max_hopsis kept and redefined as the depth the record holds, with the agent at the last recorded hop accountable for delegation beyond it (§10.5); -02 argued against the field. Adds carrying HDP content in UCAN and ZCAP-LD metadata (§11) and hash-linked snapshots (§8.3). Issuer signing remains the baseline, with per-agent signing planned as an option (§4.2). Re-authorization is recast as superseding records (§6), and multi-principal delegation as joint approval, with the untaggedparent_token_idstated as a known weakness (§7). Recommends that a component outside the agent’s control record hops, and makesagent_typefree-form (§3.4). Describes the planned nested permission structure (§3.3). Revises the rationale for the query-parameter ban (§8.1), the treatment of stripped tokens and field-level encryption (§9.1), the attribution example (§10.6), prompt injection (§10.7), and the UCAN and ZCAP-LD comparisons. Replaces “private key” with “secret key”. Sections are renumbered: IANA considerations move from §11 to §12 and the comparison with related work from §12 to §13. Every section anchor on this page is unchanged; the anchors of the removed replay and revocation sections resolve to the explanation in §1.1. - -02 · 11 September 2026
- Added §1.1, stating that HDP is not an authorization protocol, and aligned the abstract, the scope field descriptions, the verification pipeline, and the transport text with it. Made revocation normative: a verifier had to support verifier-local revocation by
token_id, checked at step 2 of a seven-step live-acceptance pipeline, and re-authorization was described as lineage rather than revocation. Removed the 24-hour default lifetime. Added historical audit verification, separate from live acceptance, reporting record integrity, current acceptance, and historical acceptance separately. Made hop timestamp monotonicity a MUST. Stated what a v0.1 hop signature does and does not attest. Added a presenter check and a completeness analysis for chain truncation, guidance on delegation budgets and off-record delegation, and rules for attribution across concurrent tokens. Added content-addressed token references with a write-once store requirement. Required trusted context before aparent_token_idlink could be read as joint authorization. Noted thatauthorized_toolsandauthorized_resourcesare unbound lists, and corrected the Appendix A example accordingly. Specified input validation and exact integer bounds. Revision -03 removes the live-acceptance pipeline and revocation. - -01 · 3 August 2026
- Incorporated review feedback from the W3C Credentials Community Group. Renamed the HTTP header fields from
X-HDP-TokenandX-HDP-Token-ReftoHDP-TokenandHDP-Token-Refper RFC 6648. Corrected root signature verification to resetchainto 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 the payload-agnostic chain-of-custody framing, chain truncation and revocation as security topics, andsession_identropy guidance. Extended the related-work comparison with ODRL, ZCAP-LD, and a Verifiable Credentials alignment note. The token wire format was unchanged. - -00 · March 2026
- Initial submission. Specified the HDP v0.1 token structure, signing, verification pipeline, re-authorization, multi-principal delegation, transport, privacy considerations, and security analysis.
References and related work
- JSON Schema (token, v0.1)
- Machine-readable token schema.
- draft-helixar-hdp-agentic-delegation-03
- IETF individual Internet-Draft, Informational. Current revision, 6 October 2026.
- draft-helixar-hdp-agentic-delegation-02
- Previous revision, 11 September 2026. Retained for citations that name it.
- draft-helixar-hdp-agentic-delegation-01
- First revision to cite this page as [HDP-SPEC], 3 August 2026. Retained for citations that name it.
- arXiv:2604.04522
- Design rationale and evaluation.
- 10.5281/zenodo.19332023
- Archival DOI.
- Helixar-AI/HDP
- TypeScript and Python reference implementations.
- Google Gemma cookbook
- HDP applied to Gemma 4 function-call security.
- HDP-P
- Companion profile for physical AI systems.
- Announcement
- Background on why HDP was published.
HDP v0.1 is a draft open for comment. This page serves IETF draft-03, dated 6 October 2026. Corrections and implementation reports are welcome at [email protected], or as issues on the reference implementation repository. The full list of changes by revision is in Appendix B.
More from Helixar Labs
All projectsHDP extended to physical AI: robots, vehicles, surgical systems.
Scan, harden, sign and attest build artifacts before they ship.
26-rule security scanner for MCP server infrastructure.