First of all, sorry for the 6h devlog, I couldn’t have devlogged sooner and I’ll explain the reasons here.
I was trying to add a way to update existing objects and I wanted to take inspiration from how DynamoDB does it (PutItem to create or replace existing objects, UpdateItem to partially update objects). To enable versioning, I completely refactored how the PUT operation works, also optimizing how lightweight objects are uploaded (before, common flow of: client sends metadata -> server creates pending object and sends a presigned put url -> client uploads the object; now, for lightweight objects, everything is done in one backend call, while for large objects the client first asks for a presigned put url, then confirms the upload to the server and only later the metadata is stored in DynamoDB).
However, while I was figuring out how indexes should be updated on an object update, I noticed that they were currently encrypted (with det. enc.) using the object’s DEK as key. Obviously, this completely broke how index should work, since a user should be able to det. encrypt an index token and search for it across the entire table. To solve this problem, I had to create a new TableConfig table, which stores, among other table metadata, the WrappedIEK field, which represents a KMS-wrapped table-wide Index Encryption Key to use for consistent and deterministic index encryption.
This way, I solved both the versioning issue and the index encryption consistency issue.
To complete the PUT operation refactoring, I refactored how indexes are stored, adding a DynamoDB Global Secondary Index to enable a new Object ID access pattern (I needed to search for every index of a specific object).
Finally, after all these problems, I completed the refactoring, enabling users to update their objects and indexes, and in the picture attached there’s the proof of it passing all tests!