Search code examples
oktaopen-fgazanzibar

OpenFGA: difference between types of indirect relationships


What's the difference between these two approaches to defining indirect relationships in an OpenFGA authorisation model?

type user

type team
  relations
    define member: [user]

type project
  relations
    define member: [user, team#member]

---

fga.writeTuples([
  {team:'devs#member', relation:'member', object:'project:next-big-app'}
])

vs

type user

type team
  relations
    define member: [user]

type project
  relations
    define team: [team]
    define member: [user] or member from team

---

fga.writeTuples([
  {team:'devs', relation:'team', object:'project:next-big-app'}
])

I find the second approach clearer and easier to reason with, but the first approach seems to be promoted more in the documentation. Any functional difference between the two? Any performance differences between the two?


Solution

  • For that scenario, is equivalent.

    If you use the first approach, you can assign different relations to different teams, e.g.

    type user

    type team
      relations
         define member: [user]
    
    type project
      relations
        define reader: [team#member]
        define writer: [team#member]
    

    If you use the second approach, and you can easily define more relations than inherit the team's ones:

    type user
    
    type team
      relations
         define member: [user]
         define owner : [user]
    
    type project
      relations
        define team: [team]
        define member: [user] or member from team
        define owner : owner from project
    

    When you have a hierarchy, you tend to use the second approach (e.g. folder/document) but when you have a set of users that you want to assign a specific relation to (e.g. 'teams', 'groups', 'roles') the first approach is preferred.