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?
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.