open-policy-agentrego

What is the difference between Assignment(=) operator and Equality(==) operator in OPA rule body


In OPA documentation https://www.openpolicyagent.org/docs/latest/policy-testing/ there is a policy definition given like below:


allow {
    input.path == ["users"]
    input.method == "POST"
}

allow {
    some profile_id
    input.path = ["users", profile_id]
    input.method == "GET"
    profile_id == input.user_id
}

here in first rule it is input.path == ["users"] whereas in second rule it is input.path = ["users", profile_id]. So can someone help me to point out the difference between these two?


Solution

  • The assignment operator in Rego is :=, == is for comparison, and the = operator is for unification. There's a section describing the differences in the docs, but simply put, unification combines assignment and comparison, so in your example, given that input.path has two elements, the second elements value will be assigned to profile_id.

    The policy could be written to split comparsion and assignment if you wanted:

    allow {
        count(input.path) == 2
        input.path[0] == "users"
        profile_id := input.path[1]
        input.method == "GET"
        profile_id == input.user_id
    }
    

    Which is arguably a bit messier. Unification should however be used sparingly, as in most other cases it is more clear to separate assignment from comparison.

    In this particular case, you could even use only comparison if you skip the intermediate assignment of profile_id:

    allow {
        input.path == ["users", input.user_id]
        input.method == "GET"
    }