-
Notifications
You must be signed in to change notification settings - Fork 615
Adding verifiability proposal #1330
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 7 commits
38f04a0
bfba32a
0f9cf68
f3bdeae
8bdae8d
296a103
5114289
14c0078
1d25d47
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,290 @@ | ||
| # CloudEvents Verifiability Extension | ||
|
|
||
| This proposal introduces a transport protocol agnostic design for verifiable | ||
| CloudEvents. It allows producers of CloudEvents to sign the events that they | ||
| send—and consumers to cryptographically verify the *authenticity and the | ||
| integrity* of the events that they receive. Through this process consumers can | ||
| be sure that events were in fact produced by the claimed producer | ||
| (authenticity), and that the events were received exactly as they were sent, | ||
| and not modified in transit (integrity). | ||
|
|
||
| The threats addressed by this proposal are those of malicious actors | ||
| impersonating CloudEvent producers and of malicious actors modifying messages | ||
| in transit. | ||
|
|
||
| This proposal only applies to individual events. It does not give consumers any | ||
| guarantees about the completeness of the event stream or the order of events. | ||
|
|
||
| The threats of malicious actors removing or hiding items from the event stream | ||
| as well as swapping their order are not addressed by this proposal. Neither are | ||
| the possibilities of messages accidentally getting lost or delivered in the | ||
| wrong order. Both can be addressed by producers through means of adding the | ||
| necessary information inside the event payloads. | ||
|
|
||
| Further, this proposal only aims at *verifiability*. It does not aim to enable | ||
| *confidentiality*. Consequently, it does not address the threat of unauthorized | ||
| parties reading CloudEvents that were not meant for them. | ||
|
|
||
| ## Notational Conventions | ||
|
|
||
| As with the main [CloudEvents specification](../spec.md), the key words "MUST", | ||
| "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", | ||
| "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as | ||
| described in [RFC 2119](https://tools.ietf.org/html/rfc2119). | ||
|
|
||
| However, the scope of these key words is limited to when this extension is | ||
| used. For example, an attribute being marked as "REQUIRED" does not mean | ||
| it needs to be in all CloudEvents, rather it needs to be included only when | ||
| this extension is being used. | ||
|
|
||
| ## Attributes | ||
|
|
||
| ### verificationmaterial (Verification Material) | ||
| - Type: `String` | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. remove the indent from these sections, otherwise they appear as "code snippets" and not normal text. |
||
| - Description: the material that consumers can use to verify a CloudEvent. | ||
| For example, the verification material could be a signature of the event | ||
| based on a private key. Consumers would use the producers’ public key to | ||
| verify the signature. | ||
| - Constraints: | ||
| - OPTIONAL | ||
| - If present, MUST be base64 encoded | ||
| - If present, a `verificationmaterialtype` attribute MUST also be | ||
| present | ||
|
|
||
| ### verificationmaterialtype (Verfication Material Type) | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. s/Verfication/Verification |
||
| - Type: `String` | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If a consumer doesn't understand this value, is there any requirement that they reject the event? I'm guessing what they do if they don't understand it, or the validation fails, it's an impl choice, right? Meaning, we can't mandate that they don't accept the event but they're then going to "proceed at their own risk" - is that the intent?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think that's up to the organization or company. I didn't want to be too heavy handed here, because one company or org may have completely differently security requirements and may want to fail or not fail depending on those requirements. For example, I can see a bank or a government institution would WANT to fail. However, something like a proxying service, would not. |
||
| - Description: tells consumers of CloudEvents what type the verification | ||
| material is of. This high level category is used by the consumer to | ||
| choose an appropriate implementation for performing the verification. The | ||
| verification material can contain information specific to the | ||
| implementation such as a sub type, version information, etc. | ||
| - Constraints: | ||
| - OPTIONAL | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think both attributes need to be "REQUIRED" since when the extension is enabled they're both needed, right?
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See line 36 for more info
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, okay, I misunderstood this section a little. My impression of what Hence to USE this extension, both would be
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. correct, when this extension is used then both attributes are REQUIRED. |
||
| - If present, a `verificationmaterial` attribute MUST also be present | ||
| - Producer and consumer MUST agree on an appropriate type | ||
|
|
||
| ## Usage | ||
|
|
||
| When this extension is used, producers MUST set both the `verificationmaterial` | ||
| and `verificationmaterialtype` attributes. Consumers can choose to verify if | ||
| the material. | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. perhaps add this to the end: maybe?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ha, yes, exactly what I just insinuated above :) Good call out! |
||
|
|
||
| ## Assumptions | ||
|
|
||
| This proposal contains a few assumptions that will be highlighted here. | ||
|
|
||
| 1. SDKs will verify as early as possible which depends on the | ||
| verification implementation. | ||
| 2. Users manage their secrets, e.g. public key infrastructure (PKI). | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you elaborate on why these assumptions are being made? It'll help people understand the overall proposal.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In particular, when option 1 is chosen, does it impact assumption 1 ? |
||
|
|
||
| ## Design | ||
|
|
||
| Verifiability in CloudEvents consists of two steps: | ||
|
|
||
| 1. The producer of an event adds verification material to the message | ||
| 2. The consumer of an event MAY use the verification material to verify the | ||
| authenticity and integrity of the event | ||
|
|
||
|
|
||
| The specifics of what the verification material looks like and how the | ||
| verification is performed depend on the *verifiability implementation*. | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. s/depend/depends/ |
||
|
|
||
| For example, in a public/private key based implementation the producer of an | ||
| event would add a signature based on their private key as the verification | ||
| material, and the consumer of an event could use the corresponding public key | ||
| to check the if the signature matches the event. | ||
|
|
||
| The flow looks like this: | ||
|
|
||
|  | ||
|
|
||
| *Option 1*: useful for verifiability implementations outside of the CE SDK. The | ||
| CE SDK merely passes on messages and is not involved in producing verification | ||
| material or performing verifications and has no knowledge about the secrets | ||
| that the verification is based on (e.g. private keys). Appropriate for tools in | ||
| a closed ecosystem like an enterprise with special requirements that are not | ||
| suitable for the CE SDK. | ||
|
|
||
| *Option 2*: useful for verifiability implementations that are directly | ||
| supported by the CE SDK. The CE SDK has to be provided with the secrets (e.g. | ||
| private key for producer and public key for consumers) and will create the | ||
| verification material on the producer side and also perform the verification on | ||
| the consumer side. This is the appropriate choice for any type of tool that is | ||
| used by other entities, for example open source. | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would it be worth mentioning that each side of the interaction could choose a different option?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Exactly. So yes, let me clarify that. |
||
|
|
||
| **Note:** If an intermediary party modifies an event, they are considered the | ||
| producer of a new event. They MUST create an updated verification material and | ||
| the consumer(s) MUST recognize them as a trustworthy producer. | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It might be worth calling out that the intermediary is also a consumer that needs to verify the incoming message before it does it's own verifiability creation processing, right? Which begs the question... do we need to worry about nested verification scenarios? e.g. client and receiving app do their own verify logic, but then the sdks do as well and neither know about each other. Is this a user error or something we should consider in the design to ensure a proper separation of concerns?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
That’s a great question, and an important one to scope clearly. This proposal intentionally avoids prescribing nested verification logic. The goal is simplicity and clarity: if an intermediary verifies and re-signs an event, downstream consumers can safely assume that all prior verification steps were completed successfully. If certain use cases require retaining and re-validating upstream signatures (e.g. for compliance or traceability), they can implement that at the application level. However, I believe this behavior is out of scope for the core proposal, and handling it by default could introduce unnecessary complexity for most users.
Ideally, verification logic should be explicit and predictable, not something silently enforced at multiple layers (e.g. SDK and application both independently verifying without coordination). That said, I view this as a matter of implementation discipline and documentation, not something that needs to be deeply enforced in the spec. When the SDKs include built-in verification, that should be clearly documented and ideally exposed as a configurable behavior. Likewise, applications integrating with such SDKs should understand where verification happens to avoid redundant or conflicting logic. This is not a user error per se, but it is a UX and documentation consideration for implementers of SDKs, not something the event format itself needs to control. Let me know if I understood that last question right
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
only if we trust the "man in the middle".
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Correct, you're right that this assumes the intermediary is trusted once it re-signs. This proposal offers a baseline model where each hop that re-signs effectively vouches for the previous event state. That model works well for many common deployment scenarios where intermediaries are under control of the same org or within a trusted boundary. That said, if an implementation operates in a zero-trust or cross-organizational context, then yes—nested signature chains could be introduced to preserve and verify the original event alongside any transformations. I think that should remain an implementation detail, not a requirement of this extension. I can certainly note this as a pattern for advanced use cases, but our aim is to keep the spec as simple and flexible as possible without precluding stronger models. |
||
|
|
||
| ## Verifiability Implementations | ||
|
|
||
| While this proposal is agnostic to the specific implementations, we set the | ||
| following rules for verifiability implementations: | ||
|
|
||
| A verifiability implementation **MUST**: | ||
|
|
||
| * transport the verification material in the same message as the event | ||
| * use the two relevant context attributes in this proposal | ||
|
|
||
| A verifiability implementation **SHOULD**: | ||
|
|
||
| * avoid depending on canonicalization (and its | ||
| [unnecessarily large attack surface](https://github.com/secure-systems-lab/dsse/blob/master/background.md#motivation)) | ||
| * transport the verification material detached from the event payload | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure what this one means. If you mean the material shouldn't be part of |
||
| (this helps avoid canonicalization) | ||
|
|
||
| A verifiability implementation **MUST FAIL** on: | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm move all of the requirements (in this section) into the core part of the spec (into the "Attributes" section), so everything critical is in one section. Then these other sections are just helper sections to better understand why certain decisions were made and guidance on how to implement it. |
||
|
|
||
| * Duplication of a relevant context attribute (e.g. two `verificationmaterial` | ||
| attributes being set in a message) | ||
| * One relevant context attribute being present but the other missing (e.g. | ||
| `verificationmaterial` being set but `verificationmaterialtype` missing) | ||
| * Unknown material type (e.g. the implementation only attempts to use the | ||
| verification material if it knows how to do so) | ||
| * Invalid material (e.g. the verification material did not match the received | ||
| event) | ||
|
|
||
| In order to get a verifiability implementation into the official CloudEvents | ||
| SDK, the following requirements are set. | ||
|
|
||
| ## Verifiability Implementation Proposals | ||
|
|
||
| A proposal for adding a verifiability implementation to the CE SDK **MUST:** | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It feels a bit odd to use RFC2119 keywords for things sdk authors need to do (here and below). |
||
|
|
||
| * provide specs on how to implement verification | ||
| * provide test vectors | ||
| * provide a verification coverage table (see Verification coverage table) | ||
|
|
||
| Test vectors ensure that implementations are consistent which does NOT affect verifiability. | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. wrap at 80 |
||
|
|
||
| A proposal for adding a verifiability implementation to the CE SDK **SHOULD:** | ||
|
|
||
| * provide information about they handle attributes, and if relevant, normalization | ||
|
|
||
| ## Example | ||
|
|
||
| To illustrate, let’s walk through how to implement a verification | ||
| implementation CloudEvents provide test vectors as well as a verification | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this reads funny to me. Is it missing a word (like "and") or a comma? |
||
| coverage table. | ||
|
|
||
| ### Verification Implementation | ||
|
|
||
| This is an example message containing a CloudEvent directly from the spec. It | ||
| happens to be an HTTP structured mode message in JSON format. Our goal is to | ||
| come up with the most insecure but also most concise verification | ||
| implementation imaginable: one based on a reversed digest which we will call | ||
| `rev`! The `rev` implementation will only verify whether or not the | ||
| payload, `data`, is valid and not additional attributes for the sake of | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ...and not whether the other context attributes are valid, for the sake of simplicity. yes? |
||
| simplicity. | ||
|
|
||
| Here is how a message containing that CloudEvent might look: | ||
|
|
||
| ``` | ||
| content-length: 209 | ||
| content-type: application/json | ||
|
|
||
| { | ||
| "specversion" : "1.0", | ||
| "type" : "com.example.someevent", | ||
| "source" : "/mycontext", | ||
| "subject": null, | ||
| "id" : "D234-1234-1234", | ||
| "time" : "2018-04-05T17:31:00Z", | ||
| "data" : "I'm just a string" | ||
| } | ||
| ``` | ||
|
|
||
| In order to make this event verifiable, a sha256 digest of the 'data' field is | ||
| computed: `Z25pcnRzIGEgdHN1aiBtJ0kK`. | ||
| This value will then be base64 encoded and added as the `verificationmaterial` | ||
| context attribute: | ||
|
|
||
| ``` | ||
| content-length: 209 | ||
| content-type: application/json | ||
|
|
||
| { | ||
| "specversion" : "1.0", | ||
| "type" : "com.example.someevent", | ||
| "source" : "/mycontext", | ||
| "subject": null, | ||
| "id" : "D234-1234-1234", | ||
| "time" : "2018-04-05T17:31:00Z", | ||
| "data" : "I'm just a string", | ||
| "verificationmaterial": "Z25pcnRzIGEgdHN1aiBtJ0kK", | ||
| "verificationmaterialtype": "rev" | ||
| } | ||
| ``` | ||
|
|
||
| A consumer then receives the this message and in order to verify, they MUST | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. s/MUST/would/ |
||
| look at the `ce-verificationmaterialtype` header to determine whether it knows | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. s/ce-// |
||
| how to perform the verification. The consumer sees that verification material’s | ||
| type is `rev`, so they will compute the `rev` of the payload to verify the | ||
| CloudEvent contained in the message: | ||
|
|
||
| ``` | ||
| $ echo -n "I'm just a string" | rev | ||
| gnirts a tsuj m'I | ||
| ``` | ||
|
|
||
| The consumer can then confirm that the `rev` output matches the verification | ||
| material and conclude that the CloudEvent’s authenticity and integrity are | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ...matches the verification material by ...(add something about sha256'ing it)... and conclude... |
||
| “guaranteed“. | ||
|
|
||
| Now, since we want to make our fantasy verification implementation into a | ||
| proposal to be included in the CE SDK, we will need to define test vectors and | ||
| a verification coverage table. | ||
|
|
||
| ### Test Vectors | ||
|
|
||
| An example test vector is defined below: | ||
|
|
||
| ``` | ||
| [ | ||
| "input": { | ||
| { | ||
| "specversion" : "1.0", | ||
| "type" : "com.example.someevent", | ||
| "source" : "/mycontext", | ||
| "subject": null, | ||
| "id" : "D234-1234-1234", | ||
| "time" : "2018-04-05T17:31:00Z", | ||
| "data" : "I'm just a string" | ||
| } | ||
| }, | ||
| "expectedVerificationMaterialType": "rev", | ||
| "expectedVerificationMaterial": "Z25pcnRzIGEgdHN1aiBtJ0kK" | ||
| ] | ||
| ``` | ||
|
|
||
| SDKs and implementers can then use the vectors to ensure that any | ||
| implementation is correct and verifiable across different languages and | ||
| systems. | ||
|
|
||
| ### Verification Coverage Table | ||
|
|
||
| The table below outlines which parts of a CloudEvent for our imaginary `rev` | ||
| based verification implementation would cover: | ||
|
|
||
| |Verifiable information |binary-mode |structured-mode |comment | | ||
| |--- |--- |--- |--- | | ||
| |data/payload |✅ |✅ | | | ||
| |mandatory context attributes |❌ |❌ |The `rev` verification implementation only looks at the payload, not at any headers. | | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. s/headers/context attributes/ |
||
| |permissive context attributes |❌ |❌ | | ||
| |extension attributes |❌ |✅ | | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why is structured mode checked?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Because this example implementation ONLY verifies payload, so either structured or binary mode works for this trivial example.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wasn't clear... you have "extension attributes" checked but no other attributes have a check-mark. That seems weird to me since, as you said, you're only checking the data not ANY other attributes. |
||
|
|
||
| Again, `sha256` was chosen because it makes for an easily readable example. It is | ||
| wildly insecure and not suitable for actual verifiability. | ||
|
|
||
| ## Appendix | ||
|
|
||
| ### Dictionary | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure you need this section but if you keep it I'd prefer if we just point to CE spec that defines most of these terms so we don't run the risk of there being a conflict between the two definitions. |
||
|
|
||
| * *event*: a CloudEvent | ||
| * *consumer*: a system that consumes CloudEvents | ||
| * *format*: a specific way to format messages, often depending on the transport | ||
| * *message*: an envelope that is used to transport a CloudEvent from its producer to the consumers | ||
| * *producer*: a system that produce CloudEvents | ||
| * *transport*: a system used to get CloudEvents from their producers to the consumers (e.g. HTTP, RabbitMQ, etc.) | ||
| * *verifiability implementation*: an implementation that makes CloudEvents verifiable according to the design in this proposal | ||
| * *verification material*: the material offered to consumers so they can perform the verification of an event | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| # CloudEvents Verifiability Extension | ||
| מסמך זה טרם תורגם. בבקשה תשתמשו [בגרסה האנגלית של המסמך](../../../extensions/verifiability.md) לבינתיים. | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| # CloudEvents Verifiability Extension | ||
|
|
||
| 本文档尚未被翻译,请先阅读英文[原版文档](../../../extensions/verifiability.md) 。 | ||
|
|
||
| 如果您迫切地需要此文档的中文翻译,请[提交一个issue](https://github.com/cloudevents/spec/issues) , | ||
| 我们会尽快安排专人进行翻译。 | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/send-and/send and/