What you will do
You will run the prepared expression in the playground above, change one input at a time, and explain the result. Start in CEL only, then repeat the same rule in CEL + JSON.
How it works
The in operator answers a membership question. For a list it compares the left value with each item; for a map it tests a key. size() returns the number of items. The two checks here are independent and joined with &&.
Read the prepared example
The CEL + JSON rule is:
role in allowedRoles && allowedRoles.size() == 2Its input is:
{
"role": "editor",
"allowedRoles": ["editor", "admin"]
}The CEL only tab contains the values and the rule in one expression. The enabled cel.bind() extension keeps each name local to its final argument.
Evaluation step by step
role in allowedRolesistruefor"editor".allowedRoles.size() == 2is alsotrue.- The combined result is
true.
Your task
- Run the expression.
- Add
"viewer"to the list without changing== 2. - Update the expected size to 3 and run again.
Expected observation: Adding an item makes the size check false until the expected count is updated.
Common mistake
in is not a substring operator. Use contains() when searching inside a string.
Show the explanation
It tests whether the map contains the key "editor".
Knowledge check
What does "editor" in {"editor": true} test?
Key takeaway
Use in for collection membership and size() for cardinality; keep the two meanings separate.
Sources
CEL-DEV— official CEL overview.CEL-LANG— official CEL language definition.CEL-GO-BIND— official documentation for the optionalcel.bind()extension used by the self-contained tab.