-
Notifications
You must be signed in to change notification settings - Fork 24.4k
Description
As part of Redis 7 we introduced keyspces which marked each key as having a "read" or "write" flag. We are hoping to use this information for the new ACL v2 functionality, but there is some ambiguity that needs to be resolved. Whether a key is written to is pretty well defined, is it possible to mutate the data or not. However, there is ambiguity about what constitutes "reading from a key".
To help clarify the discussion, I'm going to split all of the key/value data into 3 parts.
- Key information: The key string representation.
- Value user data: The user supplied data stored in the value. This also includes TTL information, since it's explicitly provided by users.
- Value metadata: The value type and metadata that is used to make user data available, but aren't directly supplied by users. Examples include dict entries for storing hashes and LRU/FLU data for handling evictions.
I think we have to assume that every operation has to have access to the key information, otherwise it wouldn't be able to look it up in the dictionary. So, I see two possible options for categorizing the remainder of the data.
With that background, I think we have 4 options for what we consider "reading" from a key. They are illustrated with a couple of commands.
Option 1: Any value data access counts as a read
- LPUSH: Marked as read, since it needs to access metadata to push.
- APPEND: Marked as read, since string length is metadata.
- SINTERCARD: Marked as read, since set values must be read to compute
Option 2: Any value user data copied or returned counts as a read
- LPUSH: Not marked as read, since it returns no value user data.
- APPEND: Not marked as a read, since it does not return any of the user data.
- SINTERCARD: Not marked as a read, since it does not return any of the user data, just an aggregate result.
Option 3: Any processing, storing, or returning of value user data counts as a read
- LPUSH: Not marked as read, since it returns no value user data.
- APPEND: Not marked as read, since length is not user data
- SINTERCARD: Marked as a read, since it processes user data to compute the intersection.
Option 4: Any processing, storing, or returning of user data or metadata about user data counts as a read
- LPUSH: Marked as read, since it returns the underlying length of the list after the push.
- APPEND: Marked as a read, since it returns metadata (length) about the total string length.
- SINTERCARD: Marked as a read, since it accesses user data to perform cardinality checks
I'm on the fence between option 3 and option 4. Option 4 seems the most correct, but it also places a lot of unnecessary restrictions on what counts as a read for ACLs. Intuitively it makes sense to me that APPEND and LPUSH shouldn't count as read commands and SINTERCARD should.
Misc
We also need to audit the all of the command specs to make sure they make sense. I noticed that LMOVE marked the first key as read + write, but does not also mark LPOP as read + write.