Modernizing
authorization with
OpenFGA
Yamil Asusta @elbuo8
The process of verifying someone's identity.
E.g. "Is this person really Kate?"
The process of evaluating if a user can
perform a certain action on a resource.
E.g. "Can Kate reply to Jimmy's post?"
Authentication Authorization
�� ��
Example
You want to build a product like Google Drive that allows users to
create and share documents amongst each other.
Users can be in groups.
Documents can be in folders.
app.get("/documents/:id", async (res, req) => {
const document = await db.documents.findOne({ id: req.params.id });
res.send({ document });
});
app.get("/documents/:id", async (res, req) => {
if (!req.user.roles.includes("employee") && !req.user.roles.includes("manager")) {
throw new ForbiddenError();
}
const document = await db.documents.findOne({ id: req.params.id });
res.send({ document });
});
Add RBAC!
If the user has a role, grant access
But… what if there are many roles? What if new roles get added?
Add PBAC (RBAC + permissions)!
If the user has a permission, grant access
But… how do you grant (or revoke) permissions to view a single document?
app.get("/documents/:id", async (res, req) => {
if (!req.user.permissions.includes("documents:view")) {
throw new ForbiddenError();
}
const document = await db.documents.findOne({ id: req.params.id });
res.send({ document });
});
Role-Based Access Control (RBAC)
Downsides:
● Role explosion: delegating access to individual resources requires creating a
new role per resource. (and if you try to add the roles to the JWT? You can’t
have many!)
● Expressiveness: you can’t express more complex policies
○ How do you handle hierarchies, e.g. if a user can view a parent folder, they
should be able to view all the documents inside child folders?
○ How do you grant access to a single folder or a single document?
ABAC allows granting more granular permissions.
But… is this check fast?! What if you forget to check the folders the document is in?
// GET /documents/:id
const document = await db.documents.findOne({ id: req.params.id });
// Because we might have the document nested in many folders, any of which may have been shared with
the user
const folders = await db.folders.recursivelyFindAllFoldersInChain ({ id: document.folder_id });
// Because the document or folder may have been shared with a group the user is in
const groups = await db.groups.recursivelyFindAllGroupsInChain ({ ids: req.user.group_ids });
await authorize(req.user, "read", { folders, groups });
res.send({ document });
Use ABAC!
Downsides:
● Nesting gets complicated: attributes about the documents and the users need to
be gathered from the database, increasing database load and increasing
response latency
● Repeated implementation for each type of resources and each type of requests
(whether user can access a particular resource and what resources a particular
user can access)
Attribute-Based Access Control (ABAC)
Introducing… ReBAC!
It allows expressing authorization rules based on relations that users and objects in a
system have with each other.
Google Zanzibar
OpenFGA is based
on Zanzibar
There are other solutions out there, too: SpiceDB, Aserto,
Topaz, etc.
In order to make authorization decisions, OpenFGA
needs two types of data:
1. An authorization model
- Does not change often
- Usually updated when introducing new products
or features
2. The authorization data
- Changes very often
- Updated as relationships between objects
change
Step 1. Write the Authorization Model
● Direct Relationships
● Computed Relationships
● Hierarchical Relationships
● Rewrite Set Operations
○ Union
○ Intersection
○ Exclusion
Step 2. Write the Tuples
Can user:jon view document:1?
user:jon document:1
viewer
folder:X
viewer parent
Step 3. Check for access
Demo
Resources
Zanzibar Paper https://research.google/pubs/pub48190/
Zanzibar Academy https://zanzibar.academy
OpenFGA Documentation https://openfga.dev
OpenFGA Playground https://play.fga.dev
Thanks

Modernizing authorization with OpenFGA (Presentation)

  • 1.
  • 2.
    The process ofverifying someone's identity. E.g. "Is this person really Kate?" The process of evaluating if a user can perform a certain action on a resource. E.g. "Can Kate reply to Jimmy's post?" Authentication Authorization �� ��
  • 3.
    Example You want tobuild a product like Google Drive that allows users to create and share documents amongst each other. Users can be in groups. Documents can be in folders.
  • 4.
    app.get("/documents/:id", async (res,req) => { const document = await db.documents.findOne({ id: req.params.id }); res.send({ document }); });
  • 5.
    app.get("/documents/:id", async (res,req) => { if (!req.user.roles.includes("employee") && !req.user.roles.includes("manager")) { throw new ForbiddenError(); } const document = await db.documents.findOne({ id: req.params.id }); res.send({ document }); }); Add RBAC! If the user has a role, grant access But… what if there are many roles? What if new roles get added?
  • 6.
    Add PBAC (RBAC+ permissions)! If the user has a permission, grant access But… how do you grant (or revoke) permissions to view a single document? app.get("/documents/:id", async (res, req) => { if (!req.user.permissions.includes("documents:view")) { throw new ForbiddenError(); } const document = await db.documents.findOne({ id: req.params.id }); res.send({ document }); });
  • 7.
    Role-Based Access Control(RBAC) Downsides: ● Role explosion: delegating access to individual resources requires creating a new role per resource. (and if you try to add the roles to the JWT? You can’t have many!) ● Expressiveness: you can’t express more complex policies ○ How do you handle hierarchies, e.g. if a user can view a parent folder, they should be able to view all the documents inside child folders? ○ How do you grant access to a single folder or a single document?
  • 8.
    ABAC allows grantingmore granular permissions. But… is this check fast?! What if you forget to check the folders the document is in? // GET /documents/:id const document = await db.documents.findOne({ id: req.params.id }); // Because we might have the document nested in many folders, any of which may have been shared with the user const folders = await db.folders.recursivelyFindAllFoldersInChain ({ id: document.folder_id }); // Because the document or folder may have been shared with a group the user is in const groups = await db.groups.recursivelyFindAllGroupsInChain ({ ids: req.user.group_ids }); await authorize(req.user, "read", { folders, groups }); res.send({ document }); Use ABAC!
  • 9.
    Downsides: ● Nesting getscomplicated: attributes about the documents and the users need to be gathered from the database, increasing database load and increasing response latency ● Repeated implementation for each type of resources and each type of requests (whether user can access a particular resource and what resources a particular user can access) Attribute-Based Access Control (ABAC)
  • 10.
    Introducing… ReBAC! It allowsexpressing authorization rules based on relations that users and objects in a system have with each other.
  • 11.
  • 12.
    OpenFGA is based onZanzibar There are other solutions out there, too: SpiceDB, Aserto, Topaz, etc.
  • 13.
    In order tomake authorization decisions, OpenFGA needs two types of data: 1. An authorization model - Does not change often - Usually updated when introducing new products or features 2. The authorization data - Changes very often - Updated as relationships between objects change
  • 14.
    Step 1. Writethe Authorization Model
  • 15.
    ● Direct Relationships ●Computed Relationships ● Hierarchical Relationships ● Rewrite Set Operations ○ Union ○ Intersection ○ Exclusion
  • 16.
    Step 2. Writethe Tuples
  • 17.
    Can user:jon viewdocument:1? user:jon document:1 viewer folder:X viewer parent Step 3. Check for access
  • 18.
  • 19.
    Resources Zanzibar Paper https://research.google/pubs/pub48190/ ZanzibarAcademy https://zanzibar.academy OpenFGA Documentation https://openfga.dev OpenFGA Playground https://play.fga.dev
  • 20.