Eventuous / eventuous

Event Sourcing library for .NET
https://eventuous.dev
Apache License 2.0
447 stars 71 forks source link

Crypto Shredding Serialization/Deserialization Support #221

Open diegosasw opened 1 year ago

diegosasw commented 1 year ago

Is your feature request related to a problem? Please describe. Event Stores are immutable. There are several techniques to protect sensitive information. Crypto Shredding is the process of encrypting sensitive data, associating it to a resource owner (the person who owns the data), and being able to dispose the encryption key when the person exercises the right to be forgotten.

Describe the solution you'd like A built-in crypto-shredding mechanism where sensitive data in an event could be marked with a [PersonalData] attribute, or similar, and where the resource owner (e.g: the person Id) could be marked with a [DataSubjectId] attribute, or similar, would be ideal. It could follow a similar approach to this one

where the serialization process

  1. Checks whether the event has a [DataSubjectId] attribute
  2. If there is one, it retrieves a new or existing symmetric encryption key from a repository (AKS, in memory or whichever)
  3. It looks for all the properties within the event, at root level or nested, with the [PersonalData] attribute, and it uses the encryption key to encrypt the value, so that it's stored as a string or base64 string property in the JSON. The encrypted value could have a specific suffix (e.g: '.crypto') which makes it explicit that the value is not the original one but the encrypted one.
  4. It saves the DataSubjectId value as a key value pair entry in the event metadata, so that it comes handy later on when deserializing

and the deserialization process

  1. Checks whether the event json has a DataSubjectId value in the metadata
  2. It retrieves the encryption key from the repository
  3. If the key exists, it decrypts every encrypted value (i.e: the values with suffix '.crypto') during deserialization
  4. If the key does not exist, it sets the default value or masks it (e.g: "", "***" or null for strings, 0 for numbers, false for booleans, etc.)

Describe alternatives you've considered An alternative would be to provide a contract IEventSerializer where we could register our own. But this IEventSerializer would need to also have access to write/read metadata for the above approach to work.

Then we could create serializers with Newtonsoft or System.Text Json