This document defines a JSON Web Signature (JWS) profile and abstract operations for representing, extending, validating, and merging a linear issuer-anchored history of JSON documents.
This document is an Editor's Draft and may change at any time. It is published for implementation and review feedback.
A history consumer often needs to verify what an issuer intended at a particular time, even when snapshots are exchanged across distributed systems. This document specifies a JOSE-based format and deterministic operations that preserve a single conflict-free chain per issuer.
This specification is format- and algorithm-focused. API shapes used by a specific reference implementation are non-normative.
The key words MUST, MUST NOT, REQUIRED, SHALL, SHALL NOT, SHOULD, SHOULD NOT, RECOMMENDED, NOT RECOMMENDED, MAY, and OPTIONAL in this document are to be interpreted as described in BCP 14 [[!RFC2119]] [[!RFC8174]] when, and only when, they appear in all capitals.
JSON is defined by [[!RFC8259]]. JWT and NumericDate are defined by [[!RFC7519]]. JWS and base64url handling in this specification follow [[!RFC7515]]. JWK and JOSE algorithm identifiers are defined by [[!RFC7517]] and [[!RFC7518]].
jti,
iss, nbf, aft, and
doc.
doc
value by running [=derive document schema=].
U+0000, used as aft in
exactly one root [=JWH entry=].
A [=JWH entry token=] MUST be a JWS Compact Serialization as defined by [[!RFC7515]].
The JWS Protected Header MUST contain:
typ with the exact value JWT.alg set to a JOSE algorithm identifier from [[!RFC7518]].
The alg value MUST NOT be none. The signing or
verification key used for processing a token MUST be a JWK compatible
with the declared algorithm [[!RFC7517]] [[!RFC7518]].
| Member | Type | Requirements |
|---|---|---|
jti |
string | MUST be non-empty and unique within one [=JSON Web History=] [[!RFC7519]]. |
iss |
string | MUST be non-empty and equal across all entries in one [=JSON Web History=] [[!RFC7519]]. |
nbf |
number | MUST be a NumericDate [[!RFC7519]]. |
aft |
string |
MUST be either [=root pointer=] or the jti of exactly
one earlier entry in the same history.
|
doc |
JSON value | MUST be valid JSON and MUST be schema-compatible with the history's [=document schema=]. |
A candidate [=JSON Web History=] is valid only if all of the following are true:
aft equal to [=root pointer=].
aft references an existing
jti in the same history.
jti.aft links from root is
acyclic and includes every entry exactly once.
iss value.doc values are schema-compatible with the
root entry's [=document schema=].
This specification defines the following abstract operations: [=derive document schema=], [=create a JWH entry=], [=tokenize a JWH entry=], [=parse a JWH entry token=], [=verify a JWH entry token=], [=validate a JWH snapshot=], [=start a JWH=], [=extend a JWH=], [=inspect a JWH=], and [=merge JWH snapshots=].
This operation takes a JSON value doc and returns a schema fingerprint string.
null, return "null".
"array<...>" containing the sorted
member schemas joined by |.
JSON.stringify(key) + ':' + schema(value).
"object{...}" containing sorted key-schema
pairs joined by ,.
This operation takes iss, aft, and doc and returns a [=JWH entry=].
entry.jti to a new non-empty unique string.entry.iss to iss.entry.nbf to the current NumericDate.entry.aft to aft.entry.doc to doc.This operation takes a [=JWH entry=] and signing key and returns a [=JWH entry token=].
typ set to
JWT and alg set to the key algorithm.
This operation takes a [=JWH entry token=] and returns decoded header, payload, signature bytes, and signing input without validating the signature.
. into three parts.typ to equal JWT.alg to be a non-empty string.This operation takes a [=JWH entry token=] and verification key and returns the verified [=JWH entry=].
alg is none, fail.alg, fail.
This operation takes a [=JWH snapshot=] (or [=JWH string=]) and optionally a verification key and returns normalized history state.
This operation takes iss, doc, and a signing key, and returns a [=JWH string=].
aft set to [=root pointer=].
This operation appends a new entry to a valid history and returns a [=JWH string=].
iss = head.iss and aft = head.jti.
This operation returns the effective [=JWH entry=] at time t.
nbf > t.nbf; break ties by
lexicographically greatest jti.
This operation takes one or more [=JWH snapshot=] values and returns a single merged [=JWH snapshot=].
jti across all inputs.jti differ in content,
fail.
A reference TypeScript implementation can expose these operations as top-level functions and optional convenience classes. Class names and method names are not normative requirements of this specification.
Implementations MUST follow JWT best current practices from
[[!RFC8725]]. In particular, implementations MUST enforce algorithm
allowlists and MUST reject alg=none.
Consumers MUST verify every token signature before relying on entry contents. Treating unverified payload data as trusted history state can enable forgery.
Implementations SHOULD treat malformed or invalid histories as hard failures and MUST NOT auto-repair by dropping conflicting entries.
This document has no IANA actions.
This specification defines conformance requirements for producers and consumers of [=JSON Web History=] artifacts. Requirements are expressed in this document using the terminology defined in [[#conventions]].