flippercloud / flipper

🐬 Beautiful, performant feature flags for Ruby.
https://www.flippercloud.io/docs
MIT License
3.7k stars 413 forks source link

Allow explicitly disabling actors #514

Open jnunemaker opened 3 years ago

jnunemaker commented 3 years ago

This has come up a few times. It would be great if we could come up with a good way of explicitly enabling a feature with exceptions. For example, this feature is enabled for everyone but john. Or this feature is enabled for everyone but customers on the basic tier.

The main problem currently is that flipper is about gates and letting people through the gates. Flipper.disable is about clearing those enablements, not explicitly disabling the gate for the actor which is different.

https://github.com/jnunemaker/flipper/issues/82#issuecomment-759626499 talks more about this. Storage of disabled is easy but the interface changes could cause quite a ripple for existing flipper users so we'd want to be careful.

Workarounds

jnunemaker commented 3 years ago

A concrete example of how this would be cool. For flipper cloud, say we have an api feature. Its always enabled.

If we made it possible to disable for individual actors or groups, then when we got a bad actor using too many resources or whatever we could just Flipper.disable(:api, bad_actor).

No code changes. No additional software other than flipper. Now the bad actor can no longer do things.

bkeepers commented 3 years ago

Would it work to add deny as another state for gates (or maybe there's a better word)? Unlike disable, which will proceed to the next gate, deny would stop checking gates and immediately return false.

Flipper.deny_actor :api, bad_actor
Flipper.deny_group :api, :abusers

Implementation wise, it could use throw :denied to abort checks.

jnunemaker commented 3 years ago

Yeah that could work. We’d still need to adjust api, ui, adapters and Feature but that verbiage could help make it all more clear.

We’d also still need a way to remove someone from the deny list. I guess we could use allow/deny. Part of me wonders if that is confusing, like what is the difference between allow and enable.

nickvanw commented 2 years ago

I'll definitely second/third this feature - we ❤️ this gem, and this is one of the things that we've found ourselves working around a number of times - either when testing a regression, or some sort of back-compatibility after we've released a feature to everyone.

I definitely think that a deny gate would be how we'd want this to work - much like there are a handful of other types, we'd love to add a group or individual actor to never return true for a particular flag - basically like adding an "inverse" flag that we would logically && with when checking.

Let me know if there's anything we can do to help this along.

Haegin commented 2 years ago

Somewhat related to this, it'd be useful to be able to specify a default when checking if a feature is enabled. For example, if I run a hypothetical SaaS blogging platform and everyone has comments, but then I sell to a customer who doesn't want comments it'd be nice to be able to add a comments feature, disable it for that new user but default the code to enabled for everyone else.

Presumably the changes you're talking about here would support this because you could globally enable comments, then disable it for that particular user. I'm currently looking at trying to build this on top of our use of Flipper at the moment.

As for the terminology, disable or deny both sound good but I agree that allow vs enable wouldn't be clear. How about clear to just wipe out any current settings for a given actor/group?

brandondrew commented 10 months ago

For the terminology, I think block is just a bit clearer than deny—implying that you're on a list of blocked users.

Let's think of "real-world" analogies. If you try to enter an event, but you don't have a ticket, you'll be denied entry. Not because you're on a list of blocked people, but because you're not on the list of invited people (based on the credentialing system of tickets). But block as a word in English seems to imply a more active prevention of access rather than just avoiding the granting of access.

Also, since deny and disable begin with the same letter, it's easier to occasionally confuse them. (Especially since their meaning is also more similar (IMO) than block and disable.)