awslabs / awslabs/aws-encryption-sdk-specification
Allow implementations that return results instead of mutating inputs
- Dominant language
- JavaScript
- Stars
- 37
- Forks
- 27
- PR merge metrics
- No merged PRs in 30d
Description
The current version of the specification describes the behaviour of some interfaces in terms of what values and structures they take as input, and what portions of that data they update if they are successful.
There will exist implementations in which it is much more natural to return results as independent, freshly-allocated data, instead of mutating inputs. This allows structures to be immutable, which can generally help to avoid many types of bugs. In addition, some programming languages do not naturally support code with mutation and side-effects as naturally as the pure functional programming style.
This issue proposes rephrasing the existing interfaces in a way that describes what values are accepted as input and what values are produced as output. It should NOT invalidate any existing implementations. Instead, there should be a preamble (probably in framework/structures.md) that describes how equivalent implementations are allowed that "produce output" by mutating existing structures instead. If the current description specifies that a value in a structure MUST NOT be modified by an interface, the functional-style version will specify that the value in the returned structure MUST match the corresponding value in the input.
In particular, the PR that addresses this issue will make the following changes to the Keyring interface (which may be hard to perceive accurately in the actual diff):
1. **OnEncrypt**: instead of modifying the input Encryption Materials, the interface will return an independent Encryption Materials value. Each field other than the encrypted data keys and the keyring trace must be equal to the corresponding field of the input.
The list of encrypted data keys and the keyring trace specified in the input materials each must be a prefix of the corresponding fields in the output.
2. **OnDecrypt**: instead of modifying the input Decryption Materials, the interface will return an independent Decryption Materials value. Each field other than the plaintext data key and the keyring trace must be equal to the corresponding field of the input. The keyring trace specified in the input materials must be a prefix of the trace in the output. The plaintext data key may or may not be populated in this result.
This is closely related with specifying error conditions, as some implementations will indicate different flavours of failure through different return values. Implementations may define one "success" outcome that contains the above output values and multiple "failure" outcomes, either as different return types, or as thrown exceptions, or some other mechanism. The above should be a complete and self-contained idea by itself, though, and I submit that we should commit this change first before improving the specification of failure.
Contributor guide
Research direction
Start with framework/structures.md and the existing Keyring interface specification. Map the current mutation-based descriptions for OnEncrypt and OnDecrypt to equivalent returned-output semantics, preserving the stated field and prefix constraints. Done means the specification supports independent returned structures without invalidating existing mutating implementations.
Written by the indexing model from the issue text.
Assessment
- Domain
- documentation
- Issue type
- Documentation
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100