opa icon indicating copy to clipboard operation
opa copied to clipboard

Feature Request: Create builtin to construct complex JSON objects

Open samgurtman-zz opened this issue 4 years ago • 3 comments

Following on from https://github.com/open-policy-agent/opa/pull/2168 it would be wonderful if OPA had a reverse walk function to build up JSON objects from sets. This would allow OPA to better service introspection type functionality such as "What things does my API Key give me access to?"

My original thought was expanding walk(x, [path, value]) so that x could be an output rather than just an input, but perhaps it needs to be a new function such as

object := map(path,value)
entitlements := permission_tree {
  permissions[[user_id, entity_type, entity_id, action]] = { ... }
  permission_tree := map([user_id, entity_type, entity_id], action[_])
}

entitlements == {
  "jim": {
    "car" : {
      "jims_suv" : ["drive","service"],
      "bobs_minivan": ["drive"]
    },
    "tea": {
      "green_tea" : ["drink", "brew"],
      "black_tea": ["brew"]
    }
  },
  "bob": {
    "car": {
      "bobs_minivan": ["drive","service"]   
    }
  }
}

samgurtman-zz avatar Mar 12 '20 03:03 samgurtman-zz

We've talked about this in the past. I think a function that accepts [path, value] tuples and constructs a hierarchical structure out of them would be nice. What you described is very close. Something like this would work:

# use an array comprehension to build [path, value] tuples
tuples := [
  [[userid, etype, eid], action] | 
    some userid, etype, eid, action
    permissions[[userid, etype, eid, action]]]

# call function on [path, value] tuples and output is a hierarchical structure
map(tuples) = {
  "jim": {
    "car" : {
      "jims_suv" : ["drive","service"],
      "bobs_minivan": ["drive"]
    },
    "tea": {
      "green_tea" : ["drink", "brew"],
      "black_tea": ["brew"]
    }
  },
  "bob": {
    "car": {
      "bobs_minivan": ["drive","service"]   
    }
  }
}

Ordering is important here because of potential conflicts. For example:

[
   [["foo", "bar"], 1],
   [["foo", "bar", "baz"], "hello"],
]

Some thought needs to be given about the input structure (e.g., just arrays or arrays/sets/objects) and how to resolve conflicts. Also, the function should not be called map. We'll have to come up with something else.

tsandall avatar Mar 16 '20 13:03 tsandall

This issue has been automatically marked as inactive because it has not had any activity in the last 30 days.

stale[bot] avatar Nov 22 '21 22:11 stale[bot]

This issue has been automatically marked as inactive because it has not had any activity in the last 30 days.

stale[bot] avatar May 26 '22 12:05 stale[bot]