VHCEL v0.1

Verifiable History with Cryptographic Event Log

Unofficial Draft

More details about this document
Latest published version:
none
Latest editor's draft:
https://aviarytech.github.io/vhcel/
History:
Commit history
Editor:
Editor to be confirmed
Feedback:
GitHub aviarytech/vhcel (pull requests, new issue, open issues)

Abstract

This specification defines a processing model for maintaining and verifying the history of an evolving data object using a Cryptographic Event Log. Every history has a self-certifying identifier derived from genesis. The model describes event continuity, authorization, state transitions, pre-rotation, and witnessing, with application-specific behavior defined by profiles.

Status of This Document

This document is a draft of a potential specification. It has no official standing of any kind and does not represent the support or consensus of any standards organization.

This is version 0.1 of an exploratory editor's draft. It is a proposal for discussion, not an adopted DIF or W3C specification. The draft is maintained in the VHCEL repository and published on GitHub Pages. Editors, standards publication venue, and licensing are to be confirmed.

The draft specifies a history processing model. A concrete CEL binding and application profile are still required for interoperable implementations. Examples are conceptual; abbreviated digests and empty proof arrays are not test vectors. Editorial issues identify choices that remain open.

1. Introduction

This specification defines Verifiable History (VH), a mechanism for maintaining and verifying the history of an evolving data object using a Cryptographic Event Log (CEL).

A Verifiable History consists of an ordered sequence of cryptographically linked events. Each event describes an operation against an application-defined state. Each non-genesis event is cryptographically bound to its predecessor.

Verifiers can independently establish that:

Verification alone does not establish that the supplied history is the latest available history or the only valid branch. See 6.3 History Truncation and 4.6 Forks.

This specification defines the processing model necessary to construct and verify a Verifiable History while delegating application-specific state semantics to application specifications.

Verifiable History is independent of any particular identifier system, transport, storage system, or application data model.

DID methods, digital assets, social objects, configuration systems, registries, and other applications MAY define application specifications based on this specification.

VHCEL builds on the history mechanisms of [DID-WEBVH] and the separation of events, operations, and external references in [CEL]. This draft proposes an alignment; it does not establish wire compatibility with either specification.

Many systems publish data whose value changes over time.

Examples include:

Publishing only the latest representation of such an object does not provide cryptographic evidence of how the object reached that state.

A Verifiable History provides that evidence.

Conceptually:

Example 1: Evolution of application state
Genesis Event
      |
      v
   Event 1
      |
      v
   Event 2
      |
      v
   Event 3
      |
      v
 Current State

Each non-genesis event cryptographically commits to its predecessor. Application-defined authorization rules determine whether an operation represented by an event is permitted.

The resulting history can be verified independently of the system from which the history was retrieved.

This distinction is fundamental:

Discovery determines where a history can be found. Verifiable History determines whether that history is authentic.

A Verifiable History therefore does not require a blockchain, distributed ledger, trusted database, or particular network protocol.

1.1 Goals

This section is non-normative.

This specification has the following design goals.

Transport Independence

A Verifiable History MUST NOT depend upon a particular transport or storage system for its integrity.

A conforming history MAY be distributed using HTTPS, local files, content addressed storage, peer-to-peer networks, databases, or other mechanisms.

Application Independence

The core history format MUST NOT depend upon the semantics of the object whose history is being represented.

Applications define how operations modify application state.

Independent Verification

A verifier possessing a history and the required cryptographic material MUST be able to verify that history without trusting the system from which the history was retrieved.

Deterministic Processing

Two conforming processors given the same valid history and application specification MUST derive the same current state.

Cryptographic Agility

The format SHOULD permit cryptographic algorithms to evolve without requiring a new history data model.

1.2 Terminology

Verifiable History

An ordered sequence of cryptographically linked events describing the evolution of an object.

Cryptographic Event Log

The representation containing the events that comprise a Verifiable History.

Event

A record carrying an operation. Each non-genesis event also carries a reference to the cryptographic digest of its immediate predecessor.

Genesis Event

The first event in a Verifiable History.

Event Identifier

A cryptographic digest identifying an event.

Previous Event

The event immediately preceding another event.

Operation

Application-defined information describing a proposed state transition.

State

The application-defined representation resulting from processing zero or more operations.

Controller

An entity authorized according to an application's authorization policy to create an event.

Witness

An entity that produces cryptographic evidence acknowledging an event.

History Identifier

The required Self-Certifying History Identifier (SCID), derived from genesis and stable for the lifetime of a Verifiable History.

Application Specification

A specification defining how a particular application interprets and processes events.

1.3 Architecture

For a concise prototype checklist, see the separate Short Implementation Guide.

Verifiable History separates four concerns:

Example 2: History architecture
+--------------------------------+
| Application State              |
+--------------------------------+
| Application Operations         |
+--------------------------------+
| Verifiable History             |
+--------------------------------+
| Cryptographic Event Log        |
+--------------------------------+

The Cryptographic Event Log establishes event integrity and ordering.

Verifiable History establishes continuity and history verification.

Application specifications establish authorization and state transition semantics.

Transport and discovery are outside the scope of this specification.

1.4 Conformance

As well as sections marked as non-normative, all authoring guidelines, diagrams, examples, and notes in this specification are non-normative. Everything else in this specification is normative.

The key words MAY, MUST, MUST NOT, OPTIONAL, REQUIRED, SHOULD, and SHOULD NOT in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.

A conforming history MUST have a genesis-derived SCID and every non-genesis event MUST reference its immediate predecessor through previousEvent. SCIDs are a core requirement, not an optional application capability.

Conformance is relative to a named binding and application profile. This draft alone does not define a complete interoperable wire protocol.

A conforming Verifiable History processor:

A conforming application specification MUST satisfy the requirements in 5. Application Specifications.

2. Data Model

For the design choices carried forward from related log formats, see 8.1 From did:webvh and 8.2 From CEL.

The data model describes the events, operations, and policies that comprise a verifiable history. Concrete property names and encodings are selected by a CEL binding.

2.1 Event Entry

A history contains one or more events. The following table summarizes the abstract event properties.

Conceptual event properties
PropertyDescription
operationREQUIRED. Describes the application-defined state transition. See 2.3 Operations and State.
previousEventREQUIRED for non-genesis events; absent at genesis. References the cryptographic digest of the immediately preceding event. See 4.2 Event Chaining.
scidREQUIRED in genesis. Identifies the entire history and is immutable. Subsequent events are bound to it through the chain. See 2.4 Self-Certifying History Identifiers.
timeOPTIONAL. An asserted event timestamp. Its interpretation is defined by the application.
Authorization proofsRequired when the application policy requires authorization. Placement and proof coverage are defined by the CEL binding.
External referencesOPTIONAL. Cryptographic commitments to data held outside the event. See 2.2 External References.
Application propertiesOPTIONAL. Additional information defined by the application specification.
Example 3: Conceptual update event
{
  "previousEvent": "<previous-event-digest>",
  "time": "2026-09-12T07:00:00Z",
  "operation": {
    "type": "update",
    "data": {}
  },
  "proof": []
}

The event's identifier is computed from its protected content; it need not be stored in the event. The previousEvent value is part of that content. The history's SCID is established by genesis and is not repeated in this update sketch. Exact placement and encoding MUST be specified by the VHCEL binding; the examples illustrate the selected model, not a finalized wire format.

Issue 1

Select a concrete CEL version and define its mapping to this model, including event envelopes, controller proofs, witness proofs, mandatory SCIDs, predecessor references, and chunk boundaries. [CEL] is the alignment target; this model retains its explicit previousEvent linkage, but compatibility has not yet been demonstrated.

2.2 External References

An event MAY cryptographically commit to data that is not embedded directly in the event.

Conceptually:

Example 4: Conceptual external data reference
{
  "previousEvent": "<previous-event-digest>",
  "operation": {
    "type": "update",
    "dataReference": {
      "digestMultibase": "uEi..."
    }
  }
}

The referenced data MAY be available from one or more locations.

The integrity of externally referenced data MUST be established from its cryptographic digest and MUST NOT depend solely upon the location from which it was retrieved.

This permits:

Example 5: Retrieving committed data
              +--> HTTPS
              |
Event -> Hash +--> IPFS
              |
              +--> P2P
              |
              +--> local storage

without changing the cryptographic identity of the referenced data.

If external data is required to validate or apply an operation, a processor MUST retrieve and verify it before accepting the resulting state. If it is unavailable, the processor MUST report incomplete verification or failure; it MUST NOT report the dependent state as verified. Optional data MAY remain unretrieved only when the application profile permits this, and the result MUST identify that data as unverified.

2.3 Operations and State

An operation describes an application-defined state transition.

Common operation types MAY include:

Example 6: Illustrative operation types
create
update
deactivate

Applications MAY define additional operation types.

The core Verifiable History processor MUST NOT assign semantics to application operations beyond those required by this specification.

An application specification MUST define:

  1. valid operation types;

  2. operation syntax;

  3. the initial state construction algorithm;

  4. the state transition algorithm; and

  5. conditions under which an operation MUST be rejected.

Given:

Example 7: State and operation notation
S(n) = application state after event n
O(n) = operation contained in event n

state processing is conceptually:

Example 8: State transition model
S(0) = CREATE(O(0))

S(n) = APPLY(S(n-1), O(n))

2.4 Self-Certifying History Identifiers

Every Verifiable History MUST have a Self-Certifying History Identifier (SCID) derived from its genesis commitment. Genesis MUST carry this value. The SCID identifies the history as a whole; an event identifier identifies a particular event within that history.

The SCID MUST remain unchanged throughout the history, including when its storage or discovery location changes. A successor MUST NOT establish a different SCID for the same history. The chain binds subsequent events to the genesis SCID; it does not require every event to repeat the value.

SCID derivation and event chaining are separate procedures. The SCID commits to genesis. Each successor's previousEvent commits to the digest of the completed preceding event. A stored current-event identifier and an identifier-substitution procedure are not required.

Example 9: SCID and predecessor linkage
SCID = DERIVE_SCID(genesisTemplate)
E[0].scid = SCID
E[1].previousEvent = EVENT_DIGEST(E[0])
E[2].previousEvent = EVENT_DIGEST(E[1])
Note

The stable SCID and the digest of the completed genesis event serve different roles and are not assumed to be equal. The functions above describe the processing relationship, not concrete cryptographic algorithms.

Example 10: Genesis with a required SCID (conceptual)
{
  "scid": "<self-certifying-history-id>",
  "operation": {
    "type": "create",
    "data": { "name": "Example object" }
  },
  "proof": [{ "proofValue": "<controller-proof>" }]
}

A processor verifying from genesis MUST recompute the SCID and compare it with the value carried by genesis. It MUST reject a missing or mismatched SCID. If the caller supplies an expected SCID, the processor MUST also compare against that value. Internal consistency alone does not establish that a supplied history is the history the caller intended. See 6.15 Genesis and Whole-History Substitution for concrete attacks this expected-identity check addresses and its limits.

Issue 2

SCIDs are mandatory. Finalize the common genesis commitment procedure, including coverage of initial state, authorization material, and bootstrap policies; domain separation; canonicalization; encoding; and deterministic treatment of the SCID field and any embedded SCID references to avoid circular hash input. Placeholder processing is one candidate for genesis derivation; it does not require replacing CEL's previousEvent linkage. The exact derivation algorithm remains to be specified by the binding.

Example 11: One history at multiple locations
SCID
 |
 +--> HTTPS location A
 |
 +--> HTTPS location B
 |
 +--> content-addressed network
 |
 +--> local archive

The same SCID can be verified regardless of where the history is retrieved.

2.5 Authorization

Applications MAY require events to be authorized.

An application specification using authorization MUST define:

For non-genesis events, authorization MUST be evaluated under the policy established by previously verified state. New keys in an event MUST NOT grant that event authority unless the prior policy explicitly permits their use, for example through a previously established pre-rotation commitment. Genesis authorization MUST follow the application specification's bootstrap rules.

Conceptually:

Example 12: Authorization from the previous state
State N
   |
   +-- authorized keys: A, B
   |
   v
Event N+1
   |
   +-- proof from A

The event is valid only if the authorization policy established by State N permits A to authorize the operation.

This prevents an event from granting itself authority.

2.6 Authorization Transitions

An operation MAY change the authorization policy governing subsequent events.

For example:

Example 13: Changing the active authorization key
Event N

Authorized:
  Key A

        |
        | signed by A
        v

Event N+1

Authorized:
  Key B

Event N+1 MUST be authorized according to the policy established before the transition.

The new policy becomes effective only after Event N+1 has been successfully verified. An application MAY permit Key B to authorize this transition when the prior policy already authorizes its use through a verified commitment.

2.7 Pre-Rotation

Issue 3

Specify the exact committed key bytes, commitment lifecycle, activation policy, and recovery behavior. Decide when prior commitments authorize a revealing key to sign the transition.

A Verifiable History MAY support pre-rotation.

Pre-rotation allows a controller to commit to future authorization keys before those keys become active.

For example:

Example 14: Committing to a future authorization key
Event N

Active:
  Key A

Commitment:
  HASH(Key B)

        |
        v

Event N+1

Reveal:
  Key B

A processor implementing pre-rotation MUST verify that newly activated cryptographic material satisfies a commitment established by an earlier valid event.

An application specification using pre-rotation MUST define:

Pre-rotation enables compromise of an active authorization key to be distinguished from possession of previously committed future key material.

2.8 Witnesses

An event MAY be acknowledged by one or more witnesses.

A witness produces cryptographic evidence committing to an event identifier.

Conceptually:

Example 15: Independent witness acknowledgments
             +--> Witness A
             |
Event ------ +--> Witness B
             |
             +--> Witness C

Witness proofs MUST NOT modify the identifier of the event they witness.

This permits witnesses to independently acknowledge the same immutable event.

2.9 Witness Policies

Applications MAY define witness policies.

A witness policy MAY specify:

For example:

Example 16: Two-of-three witness policy
Witnesses:
  A
  B
  C

Threshold:
  2

In this example, an event is considered sufficiently witnessed when valid proofs from at least two distinct authorized witnesses are present.

Witness policy changes MUST themselves occur through valid history operations.

The application specification MUST define which witness policy applies to a policy-changing event, including any requirement for the old set, the new set, or both. A processor MUST count distinct authorized witnesses, not the number of signatures, when checking a threshold. Witness evidence MUST NOT substitute for required controller authorization or operation validation.

Issue 4

Define a common witness profile: policy activation, rotation handover, receipt representation, threshold counting, and the meaning of a witness acknowledgment remain to be standardized.

3. Serializations

Issue 5

Select the required exchange format, media type, version negotiation, and any log chunking rules. Listing possible formats below does not establish support or cross-format hash equivalence.

A Verifiable History MAY be serialized using any representation defined by a compatible Cryptographic Event Log specification.

Possible serializations include:

Serialization MUST NOT alter the cryptographic meaning of an event.

Applications requiring interoperable exchange MUST identify the serialization formats they support.

4. Algorithms

The following processing rules define event identification, history continuity, and verification. A selected CEL binding supplies the cryptographic procedures referenced by these algorithms.

4.1 Event Identification

Every event MUST have a deterministic cryptographic identifier calculated from its protected content. This identifier is the event's digest; it need not be stored as a property of the event.

Example 17: Conceptual event digest calculation
EVENT_DIGEST(event) = ENCODE(HASH(CANONICALIZE(PROTECTED(event))))

The binding MUST define protected fields, canonicalization, byte encoding, digest algorithms, and identifier encoding. The protected content MUST include the SCID carried by genesis and the previousEvent reference carried by each successor. Witness receipts MUST remain outside the event identity calculation.

Issue 6

CEL-style predecessor references are the selected model. Finalize the event-digest procedure, controller-proof inclusion and coverage, unknown-property handling, and algorithm transitions. The conceptual formula is not yet an implementable hashing algorithm.

A verifier MUST reconstruct the hash input and calculate the identifier of every event, including the final supplied event. It MUST check successor references, required proofs, and any trusted event commitments against the protected content or calculated identifiers as specified by the binding. Calculating a digest alone does not authenticate an event.

Changing cryptographically protected content, including a predecessor reference, MUST change the calculated identifier except with negligible cryptographic probability.

4.2 Event Chaining

Every non-genesis event MUST carry a previousEvent reference to the cryptographic digest of its immediate predecessor.

Example 19: Checking predecessor references
REQUIRE E[1].previousEvent == EVENT_DIGEST(E[0])
REQUIRE E[2].previousEvent == EVENT_DIGEST(E[1])

A verifier compares each previousEvent with the calculated digest of the immediately preceding verified event. A missing reference or a mismatch MUST cause verification to fail.

This detects a broken link within the supplied sequence. An attacker may still serve a valid prefix or an alternative authorized branch. The mandatory SCID binds the history to genesis; it does not by itself establish freshness or uniqueness of succession.

4.3 Genesis

The first event in a Verifiable History is the genesis event. It MUST establish the history's SCID and sufficient information to initialize application state, and MUST satisfy the application's genesis requirements.

Genesis has no preceding event and MUST NOT carry a previousEvent property. Its SCID MUST be verified according to the binding. The digest of the completed genesis event is calculated for use by its successor and any applicable proofs or trusted commitments.

4.4 History Verification

A conforming processor MUST perform the following steps, or an equivalent algorithm producing the same result. Inputs are an ordered sequence E[0..n], the selected binding and application specification, and any independently obtained expected SCID or trusted event commitment.

  1. Reject an empty sequence. Validate profile selection against the caller's permitted configurations. Parse events using the selected binding and reject ambiguous or unsupported representations and prohibited algorithms.
  2. Require the SCID in E[0]. Reconstruct the genesis commitment, calculate the SCID, and compare it with the supplied value. Reject a mismatch. If the caller supplies an expected SCID, also require it to match.
  3. Verify that E[0] satisfies the application's genesis rules. Reject a previousEvent property at genesis. Calculate the digest of the completed genesis event using the binding's event-digest procedure.
  4. Validate the genesis operation and any external data needed to process it. Verify every required genesis authorization proof, pre-rotation constraint, and witness requirement under the application's bootstrap rules. Only then initialize the verified state S[0].
  5. For each event E[i], where i > 0:
    1. Require E[i].previousEvent to match the calculated digest of the verified E[i-1]. Reject a missing reference or a mismatch.
    2. Calculate the digest of E[i], including its previousEvent reference, under the binding and algorithm-transition rules permitted by the previously verified state.
    3. Reject any attempt to change the history's SCID. If the binding permits a repeated SCID, require it to match the genesis SCID.
    4. Check whether S[i-1] permits a successor, including any deactivation restrictions.
    5. Validate the operation and retrieve and verify any external data required to validate or apply it.
    6. Verify required cryptographic proofs, their purpose and context, and authorization using the policy established by S[i-1]. Verify applicable pre-rotation reveals against previously verified commitments.
    7. Verify required witness evidence over this event's calculated identifier using the applicable witness policy and transition rules.
    8. Apply the application state transition to a candidate state. Commit it as S[i] only after all required checks succeed.
  6. Check any other trusted event commitment at the position and under the rules specified by the application. Reject a mismatch or a missing required commitment.
  7. If competing successors are known, apply the application's fork policy. Do not silently select a branch in the absence of such a policy.
  8. Return the verified SCID, verified state, calculated identifier of the last supplied event, verified event count, selected binding and application profile, whether verification began at genesis or a checkpoint, the outcome of any expected-SCID check, and application-defined metadata. Distinguish freshness evidence and witness satisfaction from successful chain verification.

If any required check fails, the processor MUST reject the history as a successfully verified result. It MAY return diagnostics or a verified prefix, but MUST identify the failure and MUST NOT present that prefix as verification of the entire supplied history.

The returned state and metadata describe the scope of verification. They do not prescribe a programming-language API or a serialized result format. A boolean can answer a precisely scoped validation question, but does not by itself communicate the verified state or whether verification began at genesis or a trusted checkpoint.

A successful result describes the supplied sequence. A processor MUST NOT claim global uniqueness, absence of undisclosed forks, or freshness without additional evidence defined by the application.

4.5 Partial Histories

Applications MAY permit verification from a trusted checkpoint rather than from genesis.

An authenticated checkpoint MUST bind:

Checkpoint verification starts with the authenticated checkpoint state and continues with the successor checks in 4.4 History Verification. It does not rerun genesis processing on the first supplied successor. The checkpoint supplies the authenticated SCID and event identifier used to resume verification. Any expected SCID MUST match the checkpoint SCID; accepting a checkpoint does not independently verify the genesis derivation.

A processor MUST NOT represent a history verified only from a checkpoint as having been independently verified from genesis.

4.6 Forks

Two valid events MAY reference the same previous event:

Example 20: Competing successors
             +--> Event B
             |
Event A -----+
             |
             +--> Event C

This condition constitutes a fork.

The core Verifiable History specification does not define a universal mechanism for choosing between competing branches.

An application specification MUST define its fork policy if forks are possible.

A fork policy MAY:

Processors MUST NOT silently select a branch unless the applicable application specification defines how that selection is made.

4.7 Deactivation

An application MAY define an operation that permanently or temporarily prevents further state transitions.

A deactivation operation MUST be authorized according to the state immediately preceding the deactivation event.

An application specification MUST define whether events following deactivation are permitted.

5. Application Specifications

An application specification conforming to this specification MUST define:

  1. the application state model;

  2. valid operations;

  3. genesis processing consistent with the mandatory SCID derivation and event-identifier rules;

  4. state transition processing;

  5. authorization requirements, if applicable;

  6. witness requirements, if applicable;

  7. pre-rotation requirements, if applicable;

  8. fork handling;

  9. deactivation semantics, if applicable;

  10. supported CEL serialization and cryptographic mechanisms; and

  11. discovery mechanisms, if required.

Application specifications SHOULD reuse standardized profiles rather than defining equivalent mechanisms independently.

5.1 Discovery

Discovery is explicitly separate from verification.

An application specification MAY define mechanisms for discovering a Verifiable History.

For example:

Example 21: Discovery mechanisms
identifier
    |
    +--> HTTPS
    +--> DNS
    +--> DHT
    +--> content-addressed network
    +--> peer-to-peer protocol

A discovery mechanism MUST NOT be considered authoritative merely because it returned a history.

The returned history MUST still satisfy Verifiable History verification.

5.2 DID Application Profile

This section is non-normative.

A DID method MAY use Verifiable History to represent changes to a DID Document.

Such a profile could map:

Verifiable History concepts in a DID profile
Verifiable HistoryDID profile
HistoryDID history
GenesisDID creation
StateDID Document
Update operationDID update
AuthorizationDID controller authority
DeactivationDID deactivation
SCIDDID self-certifying identifier

The DID profile SHOULD NOT redefine event chaining, hashing, witnessing, or other mechanisms already defined by this specification or CEL profiles.

5.3 did:webvh Application

This section is non-normative.

Note

This is a proposed decomposition of [DID-WEBVH]. Existing did:webvh logs retain their original hashing and proof semantics. Renaming fields or wrapping an entry in CEL does not preserve its signatures.

A future did:webvh profile could be expressed as a Verifiable History application combining:

Example 22: Proposed did:webvh profile composition
Verifiable History
       |
       +-- CEL event representation
       |
       +-- Self-Certifying History Identifier
       |
       +-- Authorization
       |
       +-- Pre-Rotation
       |
       +-- Witness Policy
       |
       +-- DID state machine
       |
       +-- Web discovery

The did:webvh specification remains responsible for:

Generic history mechanics SHOULD be defined by this specification rather than independently by the DID method.

6. Security Considerations

6.1 Hash Function Security

The integrity of a Verifiable History depends upon the collision and second-preimage resistance of the selected hash function.

Applications MUST define acceptable cryptographic algorithms.

Applications SHOULD provide a migration mechanism for histories that use algorithms that later become unsuitable.

6.2 Authorization Key Compromise

Compromise of an active authorization key may permit unauthorized events to be created.

Applications requiring stronger compromise resistance SHOULD use pre-rotation, witnesses, or both.

Pre-rotation does not prevent an attacker who possesses both the active key and the required future key material from authorizing subsequent transitions.

Applications SHOULD define recovery procedures appropriate to their threat model.

6.3 History Truncation

Hash chaining detects modification of known history but does not inherently prove that a verifier has received the latest event.

Applications requiring freshness guarantees MUST define an additional mechanism.

Such mechanisms MAY include:

A verifier MUST NOT infer that a valid terminal event is the most recent event solely because the supplied history is internally consistent.

6.4 History Suppression

An attacker controlling a discovery or storage mechanism may suppress valid events while continuing to serve an older valid prefix of the history.

Cryptographic event chaining alone does not detect this condition.

Applications concerned with suppression SHOULD permit verifiers to obtain history information from independent sources or require freshness evidence from witnesses or other external mechanisms.

6.5 Fork Attacks

A controller possessing valid authorization material may produce multiple events referencing the same predecessor.

Each branch may be individually cryptographically valid.

Hash chaining therefore provides tamper evidence but does not, by itself, provide consensus or uniqueness of succession.

Applications in which forks are security-significant MUST define a deterministic fork policy or an external mechanism capable of identifying the accepted branch.

Witnessing MAY reduce the ability to present inconsistent branches to different verifiers, but witness behavior and threshold assumptions MUST be considered part of the application's trust model.

6.6 Equivocation

A controller, witness, or publication service may present different valid histories to different parties.

Applications requiring detection of equivocation SHOULD support exchange or publication of event identifiers, witness receipts, checkpoints, or other cryptographic commitments between independent observers.

A witness system does not prevent equivocation unless the witness protocol or policy requires witnesses to detect or refuse conflicting histories.

6.7 Witness Compromise and Collusion

Witnesses are not inherently trusted authorities.

A compromised witness may sign an event it should not have acknowledged.

A set of colluding witnesses may acknowledge conflicting or unreviewed events and satisfy a numerical threshold. This does not make a history that fails authorization, integrity, or state transition checks valid.

Applications MUST select witness thresholds and witness independence assumptions consistent with their threat model.

Where practical, witness sets SHOULD be chosen so that compromise of a single administrative, infrastructure, or cryptographic domain does not satisfy the required threshold.

6.8 Replay

A cryptographically valid event copied from one context into another may remain cryptographically valid unless the signed or hashed event data binds the event to the intended history and application context.

Applications MUST ensure that authorization proofs cannot be replayed across different histories or incompatible application contexts.

This binding SHOULD include sufficient context such as:

6.9 Cross-Protocol and Cross-Application Attacks

Cryptographic material used with multiple protocols may create ambiguity about what was authorized by a signature or proof.

Applications SHOULD use cryptographic domain separation and SHOULD avoid signing representations that could be interpreted as valid events under a different protocol.

Proof verification MUST include any purpose, domain, challenge, context, or equivalent fields required by the selected proof mechanism.

6.10 Canonicalization

Event identifiers depend upon deterministic canonicalization.

Differences in parsing, Unicode handling, number representation, property ordering, omitted values, duplicate properties, or other serialization details can cause processors to calculate different event identifiers.

The applicable CEL serialization MUST define a single deterministic procedure for producing cryptographically protected bytes.

Processors MUST reject inputs that cannot be represented unambiguously by that procedure.

6.11 Algorithm Confusion

A processor MUST NOT select cryptographic algorithms solely from untrusted event content without validating that those algorithms are permitted by the applicable application specification or profile.

Algorithm identifiers MUST be interpreted unambiguously.

Processors MUST reject unsupported or prohibited algorithms rather than silently substituting another algorithm.

6.12 Algorithm Downgrade

An attacker may attempt to transition a history from a strong cryptographic algorithm to a weaker permitted algorithm.

Applications supporting cryptographic agility MUST define who may authorize algorithm changes and which transitions are permitted.

A cryptographic algorithm transition SHOULD be authorized under the security requirements applicable before the transition takes effect.

6.13 Pre-Rotation Commitment Security

The security of pre-rotation depends on the hiding and binding properties required by the selected commitment construction.

A commitment scheme MUST make it computationally infeasible to substitute different future authorization material for the material originally committed.

Applications SHOULD consider whether exposing a hash of predictable public key material permits unwanted correlation or precomputation.

Where this is a concern, the commitment construction MAY incorporate an application-defined nonce or other binding material.

6.14 Compromise of Future Key Material

Pre-rotation protects against some forms of compromise of an active key, but it may introduce security dependencies on future key material that must be protected before activation.

If committed future private key material is compromised before it becomes active, an attacker may be able to assume control when that material is later revealed.

Applications using pre-rotation SHOULD provide a mechanism to supersede unused commitments when the current authorization policy remains uncompromised.

6.15 Genesis and Whole-History Substitution

An attacker controlling a host or discovery service can replace an entire history with a different, internally consistent history. The replacement can contain valid hash links and valid signatures made with the attacker's own keys. Those checks alone do not establish that it is the history the caller intended.

A securely obtained expected SCID binds the requested history to its genesis. The verifier reconstructs the genesis commitment, recomputes the SCID, and compares it with that expected value. This applies the genesis-binding principle used by [DID-WEBVH]; the following scenarios describe its application to VHCEL.

Replacement attacks addressed by an expected SCID
AttackAttemptWhy verification rejects it
Whole-history replacementA compromised server publishes a fresh genesis with attacker-controlled keys and a newly signed history at the same URL.The replacement genesis derives a different SCID. Copying the expected SCID into the replacement does not make its recomputed commitment match.
Genesis key or policy substitutionAn attacker changes initial authorization keys, initial state, or bootstrap witness policy and recomputes the subsequent chain.Changing content protected by the SCID commitment changes the derived identifier. This protection applies only to fields included in that commitment.
Substitution during discovery or relocationA redirect, mirror, or new storage location returns another object's valid history under the expected name or locator.The returned history fails the independently retained SCID check, even if its own proofs and chain are valid.

These are forms of the same substitution attack. For example, a client that has retained SCID A rejects a replacement whose genesis derives B, whether that replacement advertises A or B. The protection depends on the commitment's resistance to substitution, unambiguous encoding, permitted algorithms, and correct verification. The binding must specify which genesis fields are protected before these guarantees can be claimed for an implementation.

Applications MUST define how a verifier obtains or establishes the expected identity of a history when identity matters. The expected SCID must come from a source the caller already trusts, such as an authenticated reference or a previously verified and retained identifier. Taking both the history and the expected SCID from the same untrusted response does not prevent replacement. Remembering a SCID on first use can detect later replacement but does not authenticate that first encounter.

A SCID does not establish the real-world identity or trustworthiness of its controller. It also does not detect an older valid prefix, select between valid forks sharing the same genesis, prevent misuse of a compromised active key, or ensure data availability. Those require the separate mechanisms discussed in 6.3 History Truncation, 6.5 Fork Attacks, 6.2 Authorization Key Compromise, and 6.17 External Data Availability.

Note

An authenticated genesis digest or trusted checkpoint can also provide a cryptographic commitment for detecting replacement, subject to its verification rules and scope. VHCEL's SCID requirement makes a stable genesis identity common to all profiles; it does not introduce a protection that a CEL application could not provide.

6.16 Checkpoint Trust

Verification beginning from a checkpoint does not independently establish the validity of events preceding that checkpoint.

The security of partial-history verification therefore depends upon the authenticity and integrity of the checkpoint and the state associated with it.

Applications using checkpoints MUST define how checkpoints are authenticated.

Processors SHOULD expose whether verification began at genesis or from a checkpoint so that relying parties can distinguish the resulting assurance.

6.17 External Data Availability

A cryptographic digest can establish the integrity of external data but cannot guarantee its availability.

An event may remain cryptographically valid even when referenced data can no longer be retrieved.

Applications requiring long-term availability SHOULD define replication, archival, or persistence requirements separately from cryptographic integrity.

6.18 External Data Substitution

Processors MUST verify externally retrieved data against the digest committed by the event before using that data.

A location, URL, filename, media type, or transport security property MUST NOT be treated as a substitute for digest verification when a cryptographic commitment is present.

6.19 Confidentiality

A Verifiable History provides integrity and authenticity properties but does not provide confidentiality.

Event contents, cryptographic identifiers, witness information, timestamps, authorization keys, and external data references may reveal information even when application data is encrypted or stored externally.

Applications handling sensitive information SHOULD minimize information exposed in the log and SHOULD consider the correlation properties of stable identifiers and hashes.

6.20 Metadata and Correlation

Persistent identifiers, timestamps, update frequency, witness identities, authorization changes, and external data references may enable correlation across services or contexts.

Applications SHOULD consider whether every piece of metadata needs to be cryptographically committed or publicly distributed.

Transport privacy does not eliminate correlation that arises from the history itself.

6.21 Timestamp Reliability

Unless an application defines a trusted timestamping mechanism, an event timestamp represents an asserted time rather than independently proven time.

Cryptographic event ordering establishes causal succession within a history but does not, by itself, establish the real-world time at which an event occurred.

Applications MUST NOT use untrusted event timestamps as security-critical time evidence unless additional validation is defined.

6.22 Resource Exhaustion

A malicious or malformed history may contain a very large number of events, large operations, deeply nested data, expensive proof suites, excessive witness proofs, or external references intended to consume processor resources.

Implementations SHOULD impose appropriate limits on:

A processor SHOULD fail safely when implementation limits are exceeded.

6.23 Parser and Serialization Security

Implementations MUST treat serialized histories as untrusted input.

Parsers MUST reject duplicate object member names in JSON input used for cryptographic processing, before a parser can silently discard duplicate values.

Implementations SHOULD avoid parser differentials between the representation used for validation and the representation used for hashing or proof verification.

Cryptographic verification MUST operate on the exact semantic representation defined by the applicable CEL specification.

6.24 Deactivation and Recovery

Permanent deactivation may prevent recovery after accidental or malicious deactivation.

Applications defining irreversible deactivation SHOULD make that property explicit and SHOULD consider whether stronger authorization, delay, witnessing, or other safeguards are appropriate.

Recovery mechanisms, when supported, MUST NOT permit an unauthorized party to bypass previously established authorization or pre-rotation requirements.

6.25 Trust in Discovery

HTTPS, DNS, distributed storage, peer-to-peer systems, registries, and other discovery mechanisms may provide useful availability or origin information but are not substitutes for history verification.

A compromised discovery mechanism may redirect a verifier to an invalid, truncated, or unrelated history.

Processors MUST apply the same cryptographic verification regardless of the source from which a history was obtained.

6.26 Implementation Errors

The security guarantees of Verifiable History depend on correct implementation of canonicalization, hashing, proof verification, state transition processing, authorization, and application-specific policy.

Implementations SHOULD include test vectors covering:

Interoperability testing SHOULD include histories produced by independent implementations.

7. Privacy Considerations

Verifiable Histories are often append-only and may be widely replicated.

Information written to a history may therefore be difficult or impossible to remove from all copies.

Applications SHOULD avoid including personal or confidential data directly in events unless permanent disclosure is acceptable.

Where practical, applications SHOULD commit to externally stored data rather than embedding sensitive data in the history itself.

The use of cryptographic hashes does not necessarily make personal data anonymous. Hashes of predictable or low-entropy data may permit dictionary attacks or correlation.

Applications SHOULD consider data minimization, selective disclosure, encrypted external storage, and appropriate commitment constructions when processing sensitive information.

8. What VHCEL Takes from webvh and CEL

This section is non-normative.

VHCEL combines the history-verification requirements of did:webvh with CEL's application-independent event model. The following sections explain which ideas the current draft carries forward and which it changes or leaves outside the core. They describe design choices, not wire compatibility.

8.1 From did:webvh

[DID-WEBVH] supplies the starting point for stable history identity and verification across changes in control.

8.1.1 What VHCEL Takes

  • A mandatory genesis-derived SCID. Every history has a stable identity that can be checked against its genesis, even when its storage location changes.

  • Authorization through history. Each successor is checked against previously established authorization, including commitments that can authorize newly revealed keys.

  • Pre-rotation and witnessing. The model carries forward commitments to future keys and witness-policy checks, with their concrete rules defined by profiles.

  • Verification of state transitions. Processing checks the history and its control changes before accepting the resulting state.

8.1.2 What VHCEL Leaves Behind

  • A DID-specific core. DID Documents, DID syntax, method parameters, and DID-to-HTTPS discovery belong in an application profile. The core can describe other evolving objects.

  • A complete DID Document in every entry. Events carry operations; the application decides how those operations produce state, including whether to use snapshots or incremental changes.

  • Stored current IDs and predecessor substitution. VHCEL uses CEL's explicit previousEvent reference. It computes event digests without requiring versionId or replacing a current-ID field when hashing. Mandatory SCIDs do not require that construction.

8.2 From CEL

[CEL] supplies the starting point for representing events independently of the application whose history they describe.

8.2.1 What VHCEL Takes

  • Explicit predecessor references. Each non-genesis event uses previousEvent to reference the digest of the preceding event.

  • Operations and application profiles. The core describes history processing; applications define control and the meaning of state changes.

  • Embedded or externally referenced data. An operation can carry data directly or commit to data retrieved elsewhere.

  • Separate witness evidence. Witness receipts remain separate from controller authorization and outside the event-digest calculation.

8.2.2 What VHCEL Adds

  • Common history identity. VHCEL requires every application profile to use a genesis-derived SCID. CEL's DID example derives an identifier, but CEL does not make that a universal core requirement. An independently established SCID enables detection of the replacement attacks described in 6.15 Genesis and Whole-History Substitution.

  • Common history-processing requirements. VHCEL specifies how genesis, predecessor linkage, authorization, required data, and state transitions are checked together. CEL already requires application specifications to define control, state construction, and witness validity; VHCEL makes the shared verification sequence explicit while retaining those application semantics.

These additions describe a shared history-processing layer over the CEL model. They do not by themselves require a different event envelope. The result metadata in 4.4 History Verification describes what a verifier reports, rather than a difference in the log format.

8.3 What Is Still Open

Taking a design idea does not select every detail of its source format. VHCEL has not yet adopted an exact CEL envelope, serialization, digest encoding, or proof suite. SCID derivation and concrete policy bindings also remain open; these choices are deferred, not rejected. In particular, genesis may still need placeholder processing for embedded SCID references even though event chaining does not use current-ID substitution.

These sections describe the current processing model. A binding and test vectors are still needed to establish interoperability. Existing histories cannot be converted by renaming fields while assuming their original identifiers and proofs remain valid.

A. IANA Considerations

This specification has no IANA actions at this time.

B. Future Work

This section is non-normative.

Future specifications or profiles may define:

C. Alignment Work

This section is non-normative.

Issue 7

Before claiming compatibility, map a real did:webvh history into the selected CEL representation and perform the reverse exercise. Compare protected bytes, identifiers, proof coverage, SCID derivation, key transitions, and witness policy activation. Record which properties are preserved and which would require a newly signed history.

The first interoperability milestone is a named binding, a minimal application profile, and independently verified test vectors covering genesis, update, rotation, witnessing, deactivation, forks, and malformed inputs.

D. Issue summary

E. References

E.1 Normative references

[RFC2119]
Key words for use in RFCs to Indicate Requirement Levels. S. Bradner. IETF. March 1997. Best Current Practice. URL: https://www.rfc-editor.org/info/rfc2119/
[RFC8174]
Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words. B. Leiba. IETF. May 2017. Best Current Practice. URL: https://www.rfc-editor.org/info/rfc8174/

E.2 Informative references

[CEL]
Cryptographic Event Log v0.1. W3C Credentials Community Group. URL: https://w3c-ccg.github.io/cel-spec/
[DID-WEBVH]
The did:webvh DID Method — v1.0. Decentralized Identity Foundation. URL: https://identity.foundation/didwebvh/v1.0/