Search code examples
kubernetesopaopen-policy-agentrego

REGO how to get object (map) keys that match a pattern


Working with Rego, the Open Policy Agent (OPA) "rules" language, and given the following data:

{
    "x-foo": "a",
    "x-bar": "b",
    "y-foo": "c",
    "y-bar": "d"
}

what is the correct Rego expression(s) or statement(s) to get just the keys that start with "x-"? That is, I want an array of

[ "x-foo", "x-bar" ]

I know about the startswith() function, and I've tried various attempts at comprehensions, but no matter what I try I can't get it to work.

Any help would be much appreciated.


Solution

  • This can be accomplished either by using a comprehension, like you suggest, or a partial rule that generates a set:

    x_foo_comprehension := [key | object[key]; startswith(key, "x-")]
    
    x_foo_rule[key] {
        object[key]
        startswith(key, "x-")
    }
    

    Finally, if you need to take nested keys into account, you could use the walk built-in to traverse the object:

    x_foo_rule[key] {
        walk(object, [path, value])
        last := path[count(path) - 1]
        startswith(last, "x-")
        key := concat(".", path)
    }
    
    # x_foo_rule == {
    #     "x-bar",
    #     "x-foo",
    #     "y-bar.x-bar",
    #     "y-bar.x-foo"
    # ]