Jonathan Janisch
08/20/2024, 2:06 PMif (ticketStatus in ["OPEN", "STARTED"]) {
if (role in [A,B]) -> EFFECT_ALLOW
} else if (ticketStatus in ["RESOLVED"]) {
if (role in [C,D,E]) -> EFFECT_ALLOW
} else {
if (role in [F,G]) -> EFFECT_ALLOW
}
So for certain ticket statuses, only certain roles can do an "update". That's dead simple in Cerbos. The problem is the else branch. The else branch is only executed when the ticket status is not OPEN, STARTED, or RESOLVED. But I do not want to have to repeat that condition in another rule.
Here's how I've handled it:
variables:
local:
conditionA: R.attr.status in ["OPEN", "STARTED"]
conditionB: R.attr.status == "RESOLVED"
rules:
- actions:
- "update"
effect: EFFECT_ALLOW
roles:
- A
- B
condition:
match:
expr: V.conditionA
- actions:
- "update"
effect: EFFECT_ALLOW
roles:
- C
- D
- E
condition:
match:
expr: V.conditionB
- actions:
- "update"
effect: EFFECT_ALLOW
roles:
- F
- G
condition:
match:
none:
of:
- expr: V.conditionA
- expr: V.conditionB
This works, but it's not that elegant and there's likely some performance impact as the condition variables may be evaluated ahead of time even if there's no matching rule based on role. Rules can already have names. It would be nice if I can access the condition by rule name.
So maybe something like this:
rules:
- actions:
- "update"
name: ruleA
effect: EFFECT_ALLOW
roles:
- A
- B
condition:
match:
expr: R.attr.status in ["OPEN", "STARTED"]
- actions:
- "update"
name: ruleB
effect: EFFECT_ALLOW
roles:
- C
- D
- E
condition:
match:
expr: R.attr.status == "RESOLVED"
- actions:
- "update"
effect: EFFECT_ALLOW
roles:
- F
- G
condition:
match:
none:
of:
- expr: rule.ruleA.conditionA
- expr: rule.ruleB.conditionB
Maybe this already exists and I just couldn't find it in the docs. I thought the rule name was more for logging/debugging. So my guess is this is not currently possible.
Is there a better way of handling this that I haven't thought of? Thanks!Charith (Cerbos)
Jonathan Janisch
08/20/2024, 3:27 PM