Allow SET without GET arg on write-only ACL. Allow BITFIELD GET on read-only ACL#10148
Allow SET without GET arg on write-only ACL. Allow BITFIELD GET on read-only ACL#10148oranagra merged 7 commits intoredis:unstablefrom
Conversation
|
I agree we probably need this command. I couldn't think of a good alternative that respects the keyspecs without adding a lot of complexity. |
|
@redis/core-team please approve. |
yossigo
left a comment
There was a problem hiding this comment.
I'm not happy with this command. Does this mean expect clients to always use SET_WO unless they use the GET option? If not, I don't see how this solves the ACL problem.
Reverting GET seems like a lesser evil to me right now.
|
@yossigo i was thinking that many people won't use ACL with key patterns limit. Reverting the GET argument we added in 6.2 would require to really disable this mechanism, not just deprecate it. Another option we can take maybe, is handle it the same way we're gonna handle the BY and GET arguments of SORT. I suppose this may be a valid way for ACL, and would be less valid from the perspective of exposing the right key-spec flags to clients (who knows what they're gonna do with them). @madolson WDYT? |
|
@oranagra There's also an option to leave the key-specs as they are and a specific hack in ACL handling to ignore that for I think either one of those alternatives, or even the third one (breaking |
|
ok. i agree about SET_WO (we don't wanna go there). so the two alternatives are:
and then on top of one of the above, add and explicit ACL check inside setGenericCommand when the GET argument is used. i prefer [2] |
yes... yossigo is right. breaking the if this up to me. i might want to break
or this, we may write some ugly / hack code? |
|
I think it boils down to how much we officially want to support the GET parameter. What's more important: promoting the GET parameter or avoiding flagging SET as read?
This is the alternative of choice if we want to deprecate the GET parameter and add a hack to make the GET parameter work and require read permissions when it's used, to be backward compatible with 6.2.
This is a good alternative if we don't want to deprecate the GET parameter. (3. Add SET_WO. If we go this way, we can steer users in the right direction using documentation. The first sentence in SET_WO can be "A write-only variant of SET, which should only be used if you have write but not read permission to the key". Most developers try to follow best practices after all.) The same can be asked about SORT's STORE parameter: Is it important enough to flag SORT as a write command? If we had added an ACL hack, we wouldn't have needed to add SORT_RO. Perhaps we can add an ACL hack for STORE and then there's no need for SORT_RO anymore...? |
|
note that SORT_RO (and EVAL_RO) was not added for ACL, it was added for clients to be able to send this command to replicas. I vote for 2.
|
|
discussed this with @yossigo and we agree on my above proposal. |
|
make a quick hack (b979fb7c6306eacb54cd1dab746abdaa273b6641) SET RW SET only write before: |
|
thanks. I rather have acl.c explicitly remove one of READ flag for setCommand, and then add some code to setCommand to check ACL on it's own (we'll need similar check to be done by SORT for the BY and GET arguments, see #10106) |
@oranagra Sure, but a similar hack would be possible when checking if it's allowed in replicas. |
|
@zuiderkwast check where? these commands were basically added so that their command flags are different, in order to affect client libraries, so adding such a hack for that concern will need to be done on the client libraries, not reids. you can argue that SET_WO is required for the same concern, but i don't think it's likely. |
|
another ugly / attempt hack... Note the key pattern check become O(2n) ffc90e4 |
|
@enjoy-binbin i think the approach of your last message is right. |
|
I'm ok with skipping over SET_WO, I never liked it much anyways. I don't think there is a clear winner here though. I'm not sure how I feel about deprecating the GET argument, although I think it's the best long term outcome. The GET argument also causes the SET command to return a different type (integer vs string) which I don't think we should be doing as well as the ACL issue that has been raised. It might be useful longterm to be able to rewrite some commands for compatibility but execute them as different commands, in this case we could rewrite SET + GET into a GETSET command (and presumably implement the needed flags). We're no doubt going to make more mistakes, maybe it's worth building some engineering to help us unwind them. It sounds like a lot of work, so maybe the most Redis thing is just to implement a simple hack. I don't think there is that much to lose in just parsing the arguments twice and implementing a custom getKeys function. Most clients shouldn't care, since key positions are the same. madolson@e22e6c2. If we find more later we can add this hack there as well. |
|
@madolson i like your approach (implementing a getkeys_proc to control the flags). few minor notes:
p.s. |
|
oranagra
left a comment
There was a problem hiding this comment.
any last words before i merge this?
|
i am done here, i am not sure the title (should we mention BITFIELD?) |
|
yes, no harm in waiting a few more hours. |
SET and BITFIELD added `get_keys_function` in redis#10148, causing them to be wrongly marked movablekeys in `populateCommandMovableKeys`. Currently SET and BITFIELD has only one key, and key_specs are marked as VARIABLE_FLAGS, so we can rely on the VARIABLE_FLAGS flag. This was an unintended side effect introduced in redis#10148 (7.0 RC2) Fixes redis#10833
) The SET and BITFIELD command were added `get_keys_function` in #10148, causing them to be wrongly marked movablekeys in `populateCommandMovableKeys`. This was an unintended side effect introduced in #10148 (7.0 RC1) which could cause some clients an extra round trip for these commands in cluster mode. Since we define movablekeys as a way to determine if the legacy range [first, last, step] doesn't find all keys, then we need a completely different approach. The right approach should be to check if the legacy range covers all key-specs, and if none of the key-specs have the INCOMPLETE flag. This way, we don't need to look at getkeys_proc of VARIABLE_FLAG at all. Probably with the exception of modules, who may still not be using key-specs. In this PR, we removed `populateCommandMovableKeys` and put its logic in `populateCommandLegacyRangeSpec`. In order to properly serve both old and new modules, we must probably keep relying CMD_MODULE_GETKEYS, but do that only for modules that don't declare key-specs. For ones that do, we need to take the same approach we take with native redis commands. This approach was proposed by Oran. Fixes #10833 Co-authored-by: Oran Agra <[email protected]>
…is#10837) The SET and BITFIELD command were added `get_keys_function` in redis#10148, causing them to be wrongly marked movablekeys in `populateCommandMovableKeys`. This was an unintended side effect introduced in redis#10148 (7.0 RC1) which could cause some clients an extra round trip for these commands in cluster mode. Since we define movablekeys as a way to determine if the legacy range [first, last, step] doesn't find all keys, then we need a completely different approach. The right approach should be to check if the legacy range covers all key-specs, and if none of the key-specs have the INCOMPLETE flag. This way, we don't need to look at getkeys_proc of VARIABLE_FLAG at all. Probably with the exception of modules, who may still not be using key-specs. In this PR, we removed `populateCommandMovableKeys` and put its logic in `populateCommandLegacyRangeSpec`. In order to properly serve both old and new modules, we must probably keep relying CMD_MODULE_GETKEYS, but do that only for modules that don't declare key-specs. For ones that do, we need to take the same approach we take with native redis commands. This approach was proposed by Oran. Fixes redis#10833 Co-authored-by: Oran Agra <[email protected]>
SET is a R+W command, because it can also do
GETon the data.SET without GET is a write-only command.
SET with GET is a read+write command.
In #9974, we added ACL to let users define write-only access.
So when the user uses SET with GET option, and the user doesn't
have the READ permission on the key, we need to reject it,
but we rather not reject users with write-only permissions from using
the SET command when they don't use GET.
In this commit, we add a
getkeys_procfunction to control keyflags in SET command. We also add a new key spec flag (VARIABLE_FLAGS)
means that some keys might have different flags depending on arguments.
We also handle BITFIELD command, add a
bitfieldGetKeysfunction.BITFIELD GET is a READ ONLY command.
BITFIELD SET or BITFIELD INCR are READ WRITE commands.
Other changes: