Skip to content

Add optional guidance on committing a CDEvent's canonical hash - #320

Open
MarkovianProtocol wants to merge 4 commits into
cdevents:mainfrom
MarkovianProtocol:event-provenance-guidance
Open

Add optional guidance on committing a CDEvent's canonical hash#320
MarkovianProtocol wants to merge 4 commits into
cdevents:mainfrom
MarkovianProtocol:event-provenance-guidance

Conversation

@MarkovianProtocol

@MarkovianProtocol MarkovianProtocol commented Jul 28, 2026

Copy link
Copy Markdown

Adds an optional, informational document on one property a signature does not carry: that an event existed by a given time.

The mechanism is a commitment — canonicalize the CDEvent with RFC 8785 (JCS), hash the canonical bytes with SHA-256, record the digest on a timeline the emitter does not control. The document does not pick an anchor. RFC 3161 timestamp authorities, append-only transparency logs and public blockchain inclusion are named as a class; which one to use is an operational choice and explicitly out of scope. The only thing CDEvents tooling needs to agree on is the canonicalization and the hash.

The document also states what the commitment does not prove: authorship, that the anchoring party did not wait to see how something resolved before writing the anchor, and anything at all about events that were never committed.

Scope

  • One new file, event-provenance.md. Seven wordlist entries for the terms it uses.
  • No schema changes, nothing added to spec.md or the README, no changes to CI configuration, no in-tree example.

This PR was previously larger. Per @xibz's review it has been cut back: the DSSE guidance (Part 1) is out, since that is the document he is writing; the in-tree worked example, its dependency set and the eslint carve-out it required are out; the README entry is reverted. The worked example is kept outside this repository. This no longer closes #315 — that issue's original subject was answered by pointing at DSSE.

Happy to walk through what is left at the SIG before it merges, as agreed.

@MarkovianProtocol
MarkovianProtocol requested a review from a team as a code owner July 28, 2026 20:16
Adds an informational companion document describing two distinct properties:
authenticity and integrity via DSSE, and existence-over-time via an optional
commitment to the event canonical hash on an external timeline.

Mechanism-agnostic per the discussion in cdevents#315: the document names the class of
anchors without endorsing one. No schema changes; nothing is required of an
implementer.

Signed-off-by: Colin H Winter <hello@markovianprotocol.com>
@MarkovianProtocol
MarkovianProtocol force-pushed the event-provenance-guidance branch from c92881c to 0f085aa Compare July 28, 2026 20:17
Comment thread .spellcheck-en-custom.txt Outdated
url
viewUrl
wpaper
CDF

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why was this section moved?
Typical ordering based is based on ASCII / unicode order which has capital letters first.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Restored — my edit had re-sorted the file case-insensitively, which moved the capitalized block. The original ordering is back with the additions inserted in place, plus the missing canonicalization entry that caused the CI failure.

Comment thread event-provenance.md Outdated
Restore the original ordering of .spellcheck-en-custom.txt (capitalized
entries first) with additions inserted in place, and add the missing
'canonicalization' entry that failed CI. Move the worked example into
examples/event-provenance/ per review preference and point the guide at
the in-repo path.

Signed-off-by: Colin H Winter <hello@markovianprotocol.com>
Comment thread event-provenance.md Outdated
Comment on lines +101 to +104
Note on CloudEvents: a message-level signature profile for CloudEvents itself is an open
discussion in the CloudEvents project
([cloudevents/spec#565](https://github.com/cloudevents/spec/issues/565)) rather than a
finished standard. Applying DSSE to the CDEvent document, as described here, does not

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PR is merged, so I believe the discussion is over - FYI @xibz.
Should we refer to that as the recommended approach for signatures (part 1)?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated in the latest commit: the note now points at the merged verifiability extension and recommends it as the signing approach when a CDEvent travels as a CloudEvent — it's DSSE in both cases, so the extension and Part 1 align rather than compete. The extension's own non-goals (stream completeness, ordering, existence over time) are exactly what the Part 2 commitment adds, so the two compose.

Comment thread event-provenance.md Outdated
Comment on lines +134 to +137
Which anchor to use is an operational and threat-model choice. The only thing CDEvents
tooling needs to agree on is the commitment itself: the canonicalization
(RFC 8785) and the hash (SHA-256). Everything about the anchor is out of scope for this
document and MUST NOT be assumed by consumers.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1

@afrittoli afrittoli left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this PR @MarkovianProtocol - much appreciated!

I left a comment about DSSE and CloudEvents, let me know what you think.
I'm not sure if the CloudEvents SDK already supports DSSE. Do you think we should include something in the CDEvents SDKs to support the generation of the sea for the commitment side (part 2)?

I think the docs might benefit from a mermaid diagram showing which part is signed, where the signature is stored, on what the commitment is calculated on and where it is stored, but this can be done as a follow up.

- Add 'runnable' to the spellcheck wordlist (vendored example README)
- Exempt event.canonical.json from JSON style linting: its exact bytes
  are the RFC 8785 canonical serialization the example commits to, so
  it cannot be reformatted
- Update the CloudEvents note: the DSSE verifiability extension has
  merged; reference it as the recommended signing approach when a
  CDEvent travels as a CloudEvent, with Part 2 as the composing layer
  for the extension's stated non-goals

Signed-off-by: Colin H Winter <hello@markovianprotocol.com>
@MarkovianProtocol

Copy link
Copy Markdown
Author

Thanks for the review. Both CI failures are addressed in the new commit — one with a change worth flagging: event.canonical.json is the RFC 8785 canonical serialization the example commits to, its exact bytes are the artifact, so rather than reformat it I added a commented ignorePatterns entry to .github/linters/.eslintrc.yml. If you'd rather keep the linter config untouched, I can rename the file out of the .json extension instead.

On SDK support for the commitment side: yes, and it can stay small and neutral — a helper that emits the canonical bytes and their SHA-256 covers the part every anchor shares, while the anchor choice stays out of the SDK. Whether the CloudEvents SDKs ship DSSE for the verifiability extension yet I don't know; the extension specifies the SDK flow, so CDEvents inherits it wherever those SDKs land.

On the diagram: agreed, and happy to contribute it as a follow-up — one sequence showing what is signed, where the signature rides, what the commitment is computed over, and where each is stored.

@MarkovianProtocol

Copy link
Copy Markdown
Author

Checks pass, the review comments are addressed, and the vendored example verifies from a fresh clone — the genuine event passes both checks, the tampered one fails both. Ready for review whenever the group has time.

@xibz — I can't make the SIG call. If it's useful I can write the walkthrough up as a comment here for you to take to the group, or answer questions in the thread.

@MarkovianProtocol

Copy link
Copy Markdown
Author

Small follow-on to the Part 2 anchor discussion: the log used in the vendored worked example (examples/event-provenance/) now issues offline proof bundles (c2sp.org/tlog-proof) and accepts public submissions — a CDEvent's canonical-bytes sha256 can be notarized with one curl and the receipt re-verified with no network and no trust in the log operator. No spec impact; noting it because the example's anchor step is now reproducible end-to-end by any reviewer.

https://markovianprotocol.com/log.html

@xibz

xibz commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

Thanks for putting this together, and for taking the DSSE/anchoring distinction as far as a full worked example, that's a lot of careful work.

Looking back at #315, though, I think this PR has grown past what we actually scoped there. What I originally asked for was a short paragraph on the authenticity-vs-existence-in-time distinction, to live in the DSSE guidance doc I was planning to write myself. What we're reviewing here is a full standalone document, and it includes the DSSE guidance itself (Part 1), a runnable example with its own dependency set, CI lint carve-outs, and new wordlist entries, plus a README entry that puts it on the same tier as spec.md and the schemas.

I'd like to split this into two pieces that match what was actually agreed:

  • Part 1 (DSSE wrapping guidance): I'll take this one, since that's what I said I'd write.
  • Part 2 (the anchor/commitment guidance and worked example): let's walk through this at the SIG before merging, since that was the explicit gate we agreed to, and it hasn't happened yet.

I also don't think this should say "Closes #315", since #315's original subject (the markovianroot/markovianverify extension attributes) was addressed by pointing to DSSE, not by this document.

Appreciate the work either way, just want to make sure this goes through the process we agreed to before it lands.

@MarkovianProtocol

Copy link
Copy Markdown
Author

You're right, and I should have come back to #315 before writing rather than after.

I'll cut this PR down to Part 2 — the anchor and pre-commitment guidance plus the worked example — and drop the DSSE guidance, the README tier entry, and the "Closes #315" line. Part 1 is yours; #315 was answered by pointing at DSSE, not by this.

On Part 2, I'd rather walk it through at the SIG as you asked than keep it sitting in review. When does the SIG next meet, and is it enough to show up, or do you want something written circulated first? The example brings its own dependencies and a lint carve-out, so if the SIG would rather the guidance land without a runnable example, I can move the example to my own repo and cite it.

Cuts this PR back to what cdevents#315 scoped and what the SIG has not yet
discussed, per review:

- drops Part 1 (DSSE guidance), which the maintainer is writing
- drops the in-tree worked example, its dependency set and the eslint
  carve-out it needed
- reverts the README key-assets entry
- trims the wordlist to the terms the remaining text uses

What is left is the optional hash commitment: RFC 8785 canonicalization,
SHA-256, and an anchor the document deliberately does not pick.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018SdjRQgeydA1YSxbmMXmbZ
@MarkovianProtocol MarkovianProtocol changed the title Add optional event provenance and tamper-evidence guidance (#315) Add optional guidance on committing a CDEvent's canonical hash Sep 4, 2026
@MarkovianProtocol

Copy link
Copy Markdown
Author

Cut, in c81e69c. Two files now: event-provenance.md at 108 lines, and seven wordlist entries.

Part 1 is yours, so it's gone, along with the in-tree example, the eslint carve-out, the README entry, and the "Closes #315" line. What's left is the commitment and what it doesn't prove.

Still happy to hold it for the SIG rather than merge.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Optional event-level provenance / tamper-evidence for CDEvents (worked example)

3 participants