Hi guys,
I’ve been reading up on how to do contextual based relationships
https://docs.fga.dev/modeling/basics/organization-context-authorization
and i’ve mocked something up that is sort of akin to what i would like to represent our objects and relationships as:
model
schema 1.1
type user
type organization
relations
define base_org_viewer: [user] or org_viewer
define base_org_writer: [user] or org_writer
define has_view_access: base_org_viewer and user_in_context
define has_write_access: base_org_writer and user_in_context
define member: [user]
define org_viewer: [user] and user_in_context
define org_writer: [user] and user_in_context
define user_in_context: [user]
type subscription
relations
define can_view: viewer
define can_write: writer
define subscriber: [organization]
define viewer: has_view_access from subscriber
define writer: has_write_access from subscriber
type application
relations
define can_view: can_view from subscription
define can_write: can_write from subscription
define subscription: [subscription]
so in this case, if a user is part of an organization that has view access and the organization has a relationship with a subscription that also has a relationship with the application that the user is trying to view, then the it should return allow.
i ran this snippet of code while passing the context into the contextTuple and i am getting the expected response of true
const fgaClient = new OpenFgaClient({
apiUrl: FGA_API_URL,
storeId: FGA_STORE_ID,
authorizationModelId: FGA_MODEL_ID,
credentials: {
method: CredentialsMethod.ClientCredentials,
config: {
apiTokenIssuer: FGA_API_TOKEN_ISSUER,
apiAudience: FGA_API_AUDIENCE,
clientId: FGA_CLIENT_ID,
clientSecret: FGA_CLIENT_SECRET,
},
}
});
const check = async () => {
const { allowed } = await fgaClient.check({
user: 'user:anne',
relation: 'can_view',
object: 'application:app1',
contextualTuples: [
{"_description":"Anne is authorizing from the context of organization:A","user":"user:anne","relation":"user_in_context","object":"organization:org1"}
],
}, {
authorization_model_id: FGA_MODEL_ID,
});
console.log(allowed);
}
check()
// logs out true
the tuples i used are :
await fgaClient.write({
writes: [
// Anne has a `base_org_viewer` role in org1
{"_description":"Anne has a `base_org_viewer` role at org1","user":"user:anne","relation":"base_org_viewer","object":"organization:org1"},
// org1 has a subscription to subscription1
{"_description":"org1 has a subscription to subscription1","user":"organization:org1","relation":"subscriber","object":"subscription:subscription1"},
// subscription1 has a relation to app 1
{"_description":"subscription1 has a relation to app 1","user":"subscription:subscription1","relation":"subscription","object":"application:app1"},
],
}, {
authorization_model_id: FGA_MODEL_ID
});
My question was whether or not there was a way to simplify my schema as this seems a bit confusing to me when reading it as there feels like a lot of duplications in organization, subscription and application model
Thanks