ash-project / ash

A declarative, extensible framework for building Elixir applications.
https://www.ash-hq.org
MIT License
1.6k stars 213 forks source link

Proposal: switch from the satsolver to a rules engine #21

Closed zachdaniel closed 4 years ago

zachdaniel commented 4 years ago

Is your feature request related to a problem? Please describe. The satsolver is used for filter subsets and for authorization, but a few things have become clear:

1.) filter subset logic requires the expression of constraints in the two filters provided in order to be accurate, due to the nature of predicates that are mutually exclusive/inclusive e.g [id: [not_in: [1, 2]]] and [id: [not_eq: 2, not_eq: 1]]. The naive choice for this example is to turn not_in into a set of not_eq and not_eq and in into a set of eq or eq. However, this pattern breaks down when you start talking about things like greater_than: 10 and its relationship to eq: 11. We can't turn greater_than: 10 into not_eq for all values less than 10. If we use a rules engine instead of a sat solver, we should be able to express many/most of these variations much more easily. Specifically, it can be part of the work to implement #18, essentially allowing predicates to state their rules/relationships to other predicates as part of their behavior. This shouldn't logically lead to false positives, because two unrelated predicates are assumed to be unrelated facts. But it would lead to false negatives.

2.) Building policy authorization, having to transpile the policy expression to a boolean statement is difficult, and often requires that the emitted scenarios lose some of the context that was used to generate them (in effect, policy -> boolean statement is a lossy translation). We want users to be able to choose between multiple methods of applying each individual policy (e.g this policy can be applied as a filter to the data vs this policy must be expressed as a filter by the caller vs this policy can be figured out at runtime after fetching data) and due to the fact that you can have clauses that are the same except for that detail, you lose the context when translating to boolean.

Describe the solution you'd like Find and use/create a rules engine tailored to these use cases

The challenge will be setting up a rules engine that can partially evaluate/provide the scenarios so we can transform them into filter statements.

zachdaniel commented 4 years ago

After further examination, the best path forward here is, at least for now, to stick with the satsolver for filter subset logic, but to move away from the satsolver/rules engine entirely in AshPolicyAccess, and just build it in a more procedural fashion. It didn't make sense to do that until it was broken out as a dependency, but now its possible/reasonable. We can talk about optimizing these two operations later.