SoftInstigate / restheart

Rapid API Development with MongoDB
https://restheart.org
GNU Affero General Public License v3.0
807 stars 171 forks source link

Roles vs predicate in security.yml for one write-only collection #222

Closed visualist closed 7 years ago

visualist commented 7 years ago

I’d like to create a restheart user in security.yml which has read-only perms on all but one collection (call it /db/writeme), while at the same time write-only perms on /db/writeme.

Do you have advice for the best approach using predicate vs roles?

I tried using two roles, like this:

users:
    - userid: u1
      roles: [users, wo]

permissions:
    - role: users
      predicate: regex[pattern="/.*/.*", value="%R", full-match=true] and method[value="GET"]

    - role: wo
      predicate: regex[pattern="/.*/writeme", value="%R", full-match=true] and method[value="POST"]

But this approach still allowed 'u1' to read the 'writeme' collection.

I was looking through both restheart and undertow docs:

What wasn't clear is how precedence works when combing roles. It also wasn't clear how operator precedence worked with Undertow predicates, or how to group a set of and/or operations with parentheses.

ujibang commented 7 years ago

Hi @visualist

the problem with your configuration is the users role that gives permission to read from all collections, including writeme

permissions:
    - role: users
      predicate: regex[pattern="/.*/.*", value="%R", full-match=true] and method[value="GET"] and not path-prefix[path="/db/writeme"]
visualist commented 7 years ago

Thanks! I did end up figuring something else out that worked, along similar lines. I didn't know about path-prefix, that's helpful to know.

My bigger question was about the logic when combining roles that conflict between giving and taking away permissions. It seems the implication is that as long as one rule gives access permissions, that takes precedence.

(My other "big" question is more of an undertow one: how to express more complex and/or logic with parenthetical-like groupings, etc. The undertow docs I found didn't talk much about how that works.)

FYI, here's what I ended up doing:

permissions:
    - role: users
      predicate: method[value="GET"] and regex[pattern="/db/.*", value="%R", full-match=true] and not regex[pattern="/db/writeme.*", value="%R", full-match=true]

    - role: wo
      predicate: regex[pattern="/db/writeme.*", value="%R", full-match=true] and not method[value="GET"]

Yours is simpler.

visualist commented 7 years ago

Thanks - I closed this issue, btw. Hope that's all right.