|
| 1 | +# Proposal: CloudEvents Verifiability |
| 2 | + |
| 3 | +## Notational Conventions |
| 4 | + |
| 5 | +As with the main [CloudEvents specification](../spec.md), the key words "MUST", |
| 6 | +"MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", |
| 7 | +"RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as |
| 8 | +described in [RFC 2119](https://tools.ietf.org/html/rfc2119). |
| 9 | + |
| 10 | +However, the scope of these key words is limited to when this extension is |
| 11 | +used. For example, an attribute being marked as "REQUIRED" does not mean |
| 12 | +it needs to be in all CloudEvents, rather it needs to be included only when |
| 13 | +this extension is being used. |
| 14 | + |
| 15 | +## Attributes |
| 16 | + |
| 17 | +### verificationmaterial (Verification Material) |
| 18 | + - Type: `String` |
| 19 | + - Description: the material that consumers can use to verify a CloudEvent. |
| 20 | + For example, the verification material could be a signature of the event |
| 21 | + based on a private key. Consumers would use the producers’ public key to |
| 22 | + verify the signature. |
| 23 | + - Constraints: |
| 24 | + - OPTIONAL |
| 25 | + - If present, MUST be base64 encoded |
| 26 | + - If present, a `verificationmaterialtype` attribute MUST also be |
| 27 | + present |
| 28 | + |
| 29 | +### verificationmaterialtype (Verfication Material Type) |
| 30 | + - Type: `String` |
| 31 | + - Description: tells consumers of CloudEvents what type the verification |
| 32 | + material is of. This high level category is used by the consumer to |
| 33 | + choose an appropriate implementation for performing the verification. The |
| 34 | + verification material can contain information specific to the |
| 35 | + implementation such as a sub type, version information, etc. |
| 36 | + - Constraints: |
| 37 | + - OPTIONAL |
| 38 | + - If present, a `verificationmaterial` attribute MUST also be present |
| 39 | + - Producer and consumer MUST agree on an appropriate type |
| 40 | + |
| 41 | +## Usage |
| 42 | + |
| 43 | +When this extension is used, producers MUST set both the `verificationmaterial` |
| 44 | +and `verificationmaterialtype` attributes. Consumers can choose to verify if |
| 45 | +the material. |
| 46 | + |
| 47 | +## Goals |
| 48 | + |
| 49 | +This proposal introduces a transport protocol agnostic design for verifiable |
| 50 | +CloudEvents. It allows producers of CloudEvents to sign the events that they |
| 51 | +send—and consumers to cryptographically verify the *authenticity and the |
| 52 | +integrity* of the events that they receive. Through this process consumers can |
| 53 | +be sure that events were in fact produced by the claimed producer |
| 54 | +(authenticity), and that the events were received exactly as they were sent, |
| 55 | +and not modified in transit (integrity). |
| 56 | + |
| 57 | +The threats addressed by this proposal are those of malicious actors |
| 58 | +impersonating CloudEvent producers and of malicious actors modifying messages |
| 59 | +in transit. |
| 60 | + |
| 61 | +## Non-goals |
| 62 | + |
| 63 | +This proposal only applies to individual events. It does not give consumers any |
| 64 | +guarantees about the completeness of the event stream or the order of events. |
| 65 | + |
| 66 | +The threats of malicious actors removing or hiding items from the event stream |
| 67 | +as well as swapping their order are not addressed by this proposal. Neither are |
| 68 | +the possibilities of messages accidentally getting lost or delivered in the |
| 69 | +wrong order. Both can be addressed by producers through means of adding the |
| 70 | +necessary information inside the event payloads. |
| 71 | + |
| 72 | +Further, this proposal only aims at *verifiability*. It does not aim to enable |
| 73 | +*confidentiality*. Consequently, it does not address the threat of unauthorized |
| 74 | +parties reading CloudEvents that were not meant for them. |
| 75 | + |
| 76 | +## Assumptions |
| 77 | + |
| 78 | +This proposal contains a few assumptions that will be highlighted here. |
| 79 | + |
| 80 | +1. SDKs will verify as early as possible which may or may not depend on the |
| 81 | + verification implementation. |
| 82 | +2. Users manage their secrets, e.g. public key infrastructure (PKI). |
| 83 | + |
| 84 | +## Design |
| 85 | + |
| 86 | +Verifiability in CloudEvents consists of two steps: |
| 87 | + |
| 88 | +1. The producer of an event adds verification material to the message |
| 89 | +2. The consumer of an event may use the verification material to verify the |
| 90 | + authenticity and integrity of the event |
| 91 | + |
| 92 | + |
| 93 | +The specifics of what the verification material looks like and how the |
| 94 | +verification is performed depend on the *verifiability implementation*. |
| 95 | + |
| 96 | +For example, in a public/private key based implementation the producer of an |
| 97 | +event would add a signature based on their private key as the verification |
| 98 | +material, and the consumer of an event could use the corresponding public key |
| 99 | +to check the if the signature matches the event. |
| 100 | + |
| 101 | +The flow looks like this: |
| 102 | + |
| 103 | + |
| 104 | + |
| 105 | +*Option 1*: useful for verifiability implementations outside of the CE SDK. The |
| 106 | +CE SDK merely passes on messages and is not involved in producing verification |
| 107 | +material or performing verifications and has no knowledge about the secrets |
| 108 | +that the verification is based on (e.g. private keys). Appropriate for tools in |
| 109 | +a closed ecosystem like an enterprise with special requirements that are not |
| 110 | +suitable for the CE SDK. |
| 111 | + |
| 112 | +*Option 2*: useful for verifiability implementations that are directly |
| 113 | +supported by the CE SDK. The CE SDK has to be provided with the secrets (e.g. |
| 114 | +private key for producer and public key for consumers) and will create the |
| 115 | +verification material on the producer side and also perform the verification on |
| 116 | +the consumer side. This is the appropriate choice for any type of tool that is |
| 117 | +used by other entities, for example open source. |
| 118 | + |
| 119 | +**Note:** If an intermediary party modifies an event, they are considered the |
| 120 | +producer of a new event. They MUST create an updated verification material and |
| 121 | +the consumer(s) MUST recognize them as a trustworthy producer. |
| 122 | + |
| 123 | +## Verifiability Implementations |
| 124 | + |
| 125 | +While this proposal is agnostic to the specific implementations, we set the |
| 126 | +following rules for verifiability implementations: |
| 127 | + |
| 128 | +A verifiability implementation **MUST**: |
| 129 | + |
| 130 | +* transport the verification material in the same message as the event |
| 131 | +* use the two relevant context attributes in this proposal |
| 132 | + |
| 133 | +A verifiability implementation **SHOULD**: |
| 134 | + |
| 135 | +* avoid depending on canonicalization (and its |
| 136 | +[unnecessarily large attack surface](https://github.com/secure-systems-lab/dsse/blob/master/background.md#motivation)) |
| 137 | +* transport the verification material detached from the event payload |
| 138 | +(this helps avoid canonicalization) |
| 139 | + |
| 140 | +A verifiability implementation **MUST FAIL** on: |
| 141 | + |
| 142 | +* Duplication of a relevant context attribute (e.g. two `verificationmaterial` |
| 143 | + attributes being set in a message) |
| 144 | +* One relevant context attribute being present but the other missing (e.g. |
| 145 | + `verificationmaterial` being set but `verificationmaterialtype` missing) |
| 146 | +* Unknown material type (e.g. the implementation may only attempt to use the |
| 147 | + verification material if it knows how to do so) |
| 148 | +* Invalid material (e.g. the verification material did not match the received |
| 149 | + event) |
| 150 | + |
| 151 | +In order to get a verifiability implementation into the official CloudEvents |
| 152 | +SDK, the following requirements are set. |
| 153 | + |
| 154 | +## Verifiability Implementation Proposals |
| 155 | + |
| 156 | +A proposal for adding a verifiability implementation to the CE SDK **MUST:** |
| 157 | + |
| 158 | +* provide specs on how to implement verification |
| 159 | +* provide test vectors |
| 160 | +* provide a verification coverage table (see Verification coverage table) |
| 161 | + |
| 162 | +Test vectors ensure that implementations are consistent which does NOT affect verifiability. |
| 163 | + |
| 164 | +A proposal for adding a verifiability implementation to the CE SDK **SHOULD:** |
| 165 | + |
| 166 | +* provide information about they handle attributes, and if relevant, normalization |
| 167 | + |
| 168 | +## Example |
| 169 | + |
| 170 | +To illustrate, let’s walk through how to implement a verification |
| 171 | +implementation CloudEvents provide test vectors as well as a verification |
| 172 | +coverage table. |
| 173 | + |
| 174 | +### Verification Implementation |
| 175 | + |
| 176 | +This is an example message containing a CloudEvent directly from the spec. It |
| 177 | +happens to be an HTTP structured mode message in JSON format. Our goal is to |
| 178 | +come up with the most insecure but also most concise verification |
| 179 | +implementation imaginable: one based on a reversed digest which we will call |
| 180 | +`rev`! The `rev` implementation will only verify whether or not the |
| 181 | +payload, `data`, is valid and not additional attributes for the sake of |
| 182 | +simplicity. |
| 183 | + |
| 184 | +Here is how a message containing that CloudEvent might look: |
| 185 | + |
| 186 | +``` |
| 187 | +content-length: 209 |
| 188 | +content-type: application/json |
| 189 | +
|
| 190 | +{ |
| 191 | + "specversion" : "1.0", |
| 192 | + "type" : "com.example.someevent", |
| 193 | + "source" : "/mycontext", |
| 194 | + "subject": null, |
| 195 | + "id" : "D234-1234-1234", |
| 196 | + "time" : "2018-04-05T17:31:00Z", |
| 197 | + "data" : "I'm just a string" |
| 198 | +} |
| 199 | +``` |
| 200 | + |
| 201 | +In order to make this event verifiable, a sha256 digest of the 'data' field is |
| 202 | +computed: `Z25pcnRzIGEgdHN1aiBtJ0kK`. |
| 203 | +This value will then be base64 encoded and added as the `verificationmaterial` |
| 204 | +context attribute: |
| 205 | + |
| 206 | +``` |
| 207 | +content-length: 209 |
| 208 | +content-type: application/json |
| 209 | +
|
| 210 | +{ |
| 211 | + "specversion" : "1.0", |
| 212 | + "type" : "com.example.someevent", |
| 213 | + "source" : "/mycontext", |
| 214 | + "subject": null, |
| 215 | + "id" : "D234-1234-1234", |
| 216 | + "time" : "2018-04-05T17:31:00Z", |
| 217 | + "data" : "I'm just a string", |
| 218 | + "verificationmaterial": "Z25pcnRzIGEgdHN1aiBtJ0kK", |
| 219 | + "verificationmaterialtype": "rev" |
| 220 | +} |
| 221 | +``` |
| 222 | + |
| 223 | +A consumer then receives the this message and in order to verify, they MUST |
| 224 | +look at the `ce-verificationmaterialtype` header to determine whether it knows |
| 225 | +how to perform the verification. The consumer sees that verification material’s |
| 226 | +type is `rev`, so they will compute the `rev` of the payload to verify the |
| 227 | +CloudEvent contained in the message: |
| 228 | + |
| 229 | +``` |
| 230 | +$ echo -n "I'm just a string" | rev |
| 231 | +gnirts a tsuj m'I |
| 232 | +``` |
| 233 | + |
| 234 | +The consumer can then confirm that the `rev` output matches the verification |
| 235 | +material and conclude that the CloudEvent’s authenticity and integrity are |
| 236 | +“guaranteed“. |
| 237 | + |
| 238 | +Now, since we want to make our fantasy verification implementation into a |
| 239 | +proposal to be included in the CE SDK, we will need to define test vectors and |
| 240 | +a verification coverage table. |
| 241 | + |
| 242 | +### Test Vectors |
| 243 | + |
| 244 | +An example test vector may look like: |
| 245 | + |
| 246 | +``` |
| 247 | +[ |
| 248 | + "input": { |
| 249 | + { |
| 250 | + "specversion" : "1.0", |
| 251 | + "type" : "com.example.someevent", |
| 252 | + "source" : "/mycontext", |
| 253 | + "subject": null, |
| 254 | + "id" : "D234-1234-1234", |
| 255 | + "time" : "2018-04-05T17:31:00Z", |
| 256 | + "data" : "I'm just a string" |
| 257 | + } |
| 258 | + }, |
| 259 | + "expectedVerificationMaterialType": "rev", |
| 260 | + "expectedVerificationMaterial": "Z25pcnRzIGEgdHN1aiBtJ0kK" |
| 261 | +] |
| 262 | +``` |
| 263 | + |
| 264 | +SDKs and implementers can then use the vectors to ensure that any |
| 265 | +implementation is correct and verifiable across different languages and |
| 266 | +systems. |
| 267 | + |
| 268 | +### Verification Coverage Table |
| 269 | + |
| 270 | +The table below outlines which parts of a CloudEvent for our imaginary sha256 |
| 271 | +based verification implementation would cover: |
| 272 | + |
| 273 | +|Verifiable information |binary-mode |structured-mode |comment | |
| 274 | +|--- |--- |--- |--- | |
| 275 | +|data/payload |✅ |✅ | | |
| 276 | +|mandatory context attributes |❌ |❌ |The sha256 verification implementation only looks at the payload, not at any headers. | |
| 277 | +|optional context attributes |❌ |❌ | |
| 278 | +|extension attributes |❌ |✅ | |
| 279 | + |
| 280 | +Again, `sha256` was chosen because it makes for an easily readable example. It is |
| 281 | +wildly insecure and not suitable for actual verifiability. |
| 282 | + |
| 283 | +## Appendix |
| 284 | + |
| 285 | +### Dictionary |
| 286 | + |
| 287 | +* *event*: a CloudEvent |
| 288 | +* *consumer*: a system that consumes CloudEvents |
| 289 | +* *format*: a specific way to format messages, often depending on the transport |
| 290 | +* *message*: an envelope that is used to transport a CloudEvent from its producer to the consumers |
| 291 | +* *producer*: a system that produce CloudEvents |
| 292 | +* *transport*: a system used to get CloudEvents from their producers to the consumers (e.g. HTTP, RabbitMQ, etc.) |
| 293 | +* *verifiability implementation*: an implementation that makes CloudEvents verifiable according to the design in this proposal |
| 294 | +* *verification material*: the material offered to consumers so they can perform the verification of an event |
0 commit comments