 Hi, everyone. My name is Adrian Tam. I'm a senior engineer from the Office of FGA team. Today, we are going to go on an exciting journey for to go beyond row-based assets with Office of FGA. But before we do all this, we have to go through this safe harbor provision, read it, understand it, and next. All right, to begin with, we need to distinguish between authentication and authorization. Authentication is the process of verifying someone's identity. For example, we ask the question, is this person really Kate? Authorization, on the other hand, is the process of evaluating if a user can perform certain action on the resource. For example, can Kate reply to Jimmy's post? Next, we want to define what is fine-grained authorization. For fine-grained means that individual users have access to specific objects because the object, all its parents, have been shared with them, all one of the groups that they belong to. Examples of this might include Google Drive, a user can share individual folders and documents with other users or groups. You can also think about GitHub. Individual repositories can be shared with any number of users or teams across organizations. It might be even as simple as an expense report. A manager can approve the expense report of the employee. So you may be thinking, why do I need an authorization service? Instead of just building it on my own inline, well, having an authorization service gives you a few benefits. First, it provides you with better auditability. You will have centralized logs to tell you who access what at what time. Next, you can decouple access policy enforcement from your policy decision. Instead of having separate teams working in silos, writing authorization checks all over the code, one here, one there, you will have one place and to centralize all your knowledge. Third, it will allow you to have consistent APIs across entering teams. You can implement and establish and enforce company-wide best practices. Finally, you will allow to have enforcement of authorization across surface boundaries. For example, you can think of the case where Gmail asks you to share a document when you send a link with it in an email. This may involve multiple teams if you do it inline. So if you're going to choose an authorization service, what type of things you need to look for? First, it needs to be highly available because authorization is needed on every API request. So any downtime means that user will not be able to access your services. Second, it needs to have low latency. Every delay in your authorization service adds up to the delay the user sees when they access your API. Third, it needs to be correct. What makes by correct is that you will need to be able to have assertion and test on your model and data instead of the entire thing. This will allow you to focus on what is needed. Finally, it needs to be flexible. Your authorization service should enable you to solve a variety of problems instead of requiring you to work around them. So we have an API here, a very, very simple application, where you will return a document. And let's say that we want to implement authorization on it. So how should we go about? One of the way to address this is to use our back. Our back means role-based access control. User can access resource based on their role. For example, if the user is an employee or a manager, then they are allowed to access these documents. Otherwise, if they're not an employee or manager, we will return a 403 forbidden error. This will work well for most cases. However, it does not scale well if you have many roles. So instead of employee manager, let's say that you have developer, designer, QA, auditor, commenter, manager, director, for every single role, you will need to include in this line. And you can see that it does not scale well. You will have a huge check here. Another possibility to address this problem is to use our back with permission. Instead of specifying a role, you specify the permission in the JWT token. This will work well. If you have many roles, you just need to have one line that says, if the user permission includes documents view, voila, everything will be good. However, how do you solve the case if you want to share a single document? How do you do it? And what about the case where you want to refold to permission? Since the permission is already encoded in the JWT, you will need to wait for it to expire. You cannot refold it immediately. So in general, our back is good for situations when you grant board access to a collection of resource. Examples may include all managers at the company can approve expense reports, or engineers can view servers. Any dev in your organization can view your organization's GitHub repositories. They're good for that. But it has done size of role explosion. As we said earlier, if you want to include all these permission in the token itself, the token can get really, really large. And this will cause token bloat. The problem here is that many proxies will block headers that's about certain size. So if you have a very large token, then your proxy will block it, and your authorization cannot be proceeded. The second problem with our back is that it has limited ability to express more complex or contextual use cases. So examples may include if you want to express a case where a manager can approve the expense report that were submitted by someone that they manage, or by someone that has been delegated to them, then our back will have problem expressing this properly. Another problem is that let's say that if you want to have developers to have limited access to some GitHub repos, depending on the team or organizations that they are in, or if they have been shared with that repositories, our back will have difficulty in implementing this. So another possible approach to this problem is use attributes-based access control, or A-back. A-back solutions allows you to have finer granularity than the Outback case. So the whole idea is that you express your policy in terms of attributes of the user, or the resource, or the attributes of the environment's context. So you can think of cases where if a user can read an object they have read or added access to its parent's folder container, then A-back is a good solution. Or if you want to have user approve a report, if they are the manager of the employee that submitted the report, you can use A-back. Another case is a very classical A-back case is that if you want to have user access to server, if they are from a certain IP address, or during work hours, A-back would be a good solution for that. So the general idea of A-back is that the user attribute will indicate whether you have access to the resource. However, if you have cases where the folder belongs to another folder, then it has problem. So in our case here, we want to read the document. But a folder can be a parent of another folder. So what happens is that you need to go recursively up all the way to the chain to find out all the folders that have access that is a parent of the document. Or another case is that let's say that you have groups belong to another group. Then you will need to go all the way up the chain to find out all the groups that they belong to. And only after you find out all these groups then you can check whether the user is authorized or not. So the downside, as I said, is that you will need to, if they are recursive relationship, then you need to collect the data all the way up to the chain. And this will lead to high latency. Another problem is that, as I said in the earlier slide, is that you will need to go back to your product, your product database to understand all this relationship. And looking up the product database all the time, you will need to increase in the database load. Third is that you will need to repeat this recursive check for every type of resource and every type of request. And you don't want to do that. That's not fun. So this leads us to another way to approach this. And this is called relationship-based access control, or the REBEC. The REBEC or relationship-based access control allows you to express authorization rules based on relations the user and the objects in the system have with each other. So the REBEC service uses this knowledge of relationship between different entities in the system in order to reach the authorization decision. So in our case here, user John can access document 1 if he is assigned a fewer relationship with the document. Another way he can access the document is that he is given a fewer relationship with folder x. And folder x has a parent relationship with document 1. So this leads us to off-serial FGA. Off-serial FGA is a fully managed fine-grained authorization SAS provided by Arcter. You can use it to solve authorization problem in general, and it is especially designed to solve the fine-grained authorization ones. It was originally inspired by Google's Sensible Paper, which described how authorization for all of Google's services was built using relationship-based access control. It is currently free to use while in developer's preview, and it is available for production as early access. You can check it out at our website, hdtpsfga.dev. And one thing I want to mention before we go to next slide is that the core technology of off-serial FGA has been open-sourced as OpenFGA, which is adopted by CNCF as a sandbox project. This makes off-serial FGA's core quote auditable and extensible by anyone that wants to get involved. And the API of off-serial FGA and OpenFGA is binary compatible. The API is compatible, and it allows you to seamlessly switch between the two. Off-serial FGA provides you with a flexible modeling language, and it has extensive documentation on modeling your system's permissions. It has SDKs for JavaScript, Go, .NET, Python, with more languages planned. It is highly available with multi-active active region support. Internally, its caching infrastructure and automatic routing of requests to the closest region allows you to minimize latency. It has a management dashboard to allow you to great store, update your model, collaborate with your team members, and manage credentials for the off-serial FGA API. Finally, it has backup, replication, on-call support, and more. So what does off-serial FGA do? Off-serial FGA answers the question, is someone related to a particular object with a specified relationship? It uses two things to reach this authorization decision. First is the authorization model. The authorization model describes the type of object in the system and how they relate to one another. For example, here in line 15, we specified that a user is a document if it has been directly shared with them, or if they create the document, or they can fill a folder containing it. Relationship tuples, on the other hand, represent the system state. And it is defined by no facts of the system of who is related to what. So in that case, we have user join has fewer relationship with folder x, and folder x has parent relationship with document one. Off-serial FGA uses the authorization model to traverse the relationship graph between the tuples and find out if there's a path from the user to the object. And if there's a file path, it will allow the request. With all that said, we can demo it with the off-serial FGA playground. The playground is a learning tool meant to help you to learn and play with off-serial FGA. It is completely free to use, and you don't need to sign up for it. So with that in mind, let's switch to my laptop. Voila! All right, so here is the off-serial FGA playground. So the off-serial FGA playground has default stores and user stores. The default stores have its authorization model, relationship tuples, and assertions pre-populated. You're not allowed to modify it, but you can look at it. And they are examples for you to allow to learn more advanced use cases. The user stores, on the other hand, allow you can use it to modify your authorization model, add multiples, add assertions to test it out, and for you to play and learn it. So here, we have the authorization of model, more complex one, that we described with our earlier API. So we have user, group, folders, and documents. A user can belong to a member of a group. The folder, you can have a folder of being a parent of a folder, and you have a viewer of a folder. And I would like to draw your attention here is that for the document viewer, it can be a user or group member assigned to it, or the member of someone who has owned the relationship, or someone who has viewed a relationship of its parents, in this case, the folder. So we have two tuples defined, which is we talked about earlier. User John being a viewer of folder X, and folder X being a parent of document one. So we can ask the question is, user John related to document one as viewer? And it does. The reason why it does is that it has viewer relationship with the folder, and the folder is a parent of document one, as we said earlier. So we can go back to our slides now. So after we understand and design our model, the next thing we want to do is hook it up to our API. To do this, we have our code that we see earlier, where you have the function getDocument, and you want to return the document if the user is allowed. So instead of doing all these checks earlier, we just call the API of using check to see whether the user has viewer relationship with the document. That's it. It will return if you're allowed, then you will return the documents. Otherwise, before a four or three error. And not only you can answer the question, is someone related to an object as certain relationship, you can also ask the question, what type of objects or what type of documents the user has viewer relationship with. So to do this, we have the API called this object, which allows you to just say, tell me all the document where my user has viewer relationship with. And once we have that list, we can just go to our database, look up all those documents, and return those documents to the user. Simple enough. So in general, all of our official FGA functionality is exposed through our APIs. We can update the authorization model, write and delete relationship tuples, update our assertions, the test that we have, execute our check calls. We can query if the object that user has access to, or watch for relationship changes, or even query the subjects that the user has access to. So after we do all this, let's see how we can put the whole thing together. And to do that, we will have a little demo where the user can switch between, can create and share folders and documents, can create groups, invite others to join their groups, and share resource with other groups. And the first thing we want to do, once we start our project, is to put our authorization model. And here, we have the authorization model in our dashboard. The dashboard allows you similar to the playground, but it allows you to manage your official FGA setup. It has special ability for settings. The settings is where you can define, to create, and manage your credentials. And with this credential, you can hook up your application to call the official FGA API. So in our example here, we have a few calls that we can do. We can create folder. We can create document. We can create group. We can share this object with other users. Let's see how the whole thing fits together. The first thing we want to do is that we want to create the folder as join. So we are going to press send. Yay! So the document is returned, right? So simple enough. Now, think about the case. OK, if I create the folder, if John create the folder, who can access the folder? Well, John can access the folder. So as John, we send, and the folder is returned. But let's say that if he wants to do it as Bob, can he do that? No, he cannot access the folder, because he does not have permission to it. Similarly, you cannot access the document as Jill. So why is this the case? So we can go back to our dashboard and see that user John have owner access, owner relationship with the folder. And because he's an owner, he will have fewer relationship. But Bob or Jill does not have that relationship. So let's say that we want to do something next. We have Bob create a document and attach that document to the folder. So think about that. Who will then have access to that document? Let's create it Bob first. Create the documents created. So if Bob create a document, obviously he has access to it. What is interesting is that John also have access to the document. But Jill, on the other hand, does not have authorization to access the document. The reason why this is the case is that we first this user Bob has owner relationship document, so he can access it. But the folder itself is a parent of the document. So John, who has owner access to the folder, will also have access to the document itself. But Jill, on the other hand, has no access. Finally, let's say that we want to share the document. We would first create the group and invite Jill to it. And we assign that any group member will have fewer to the folder. So after we do that, we can now check to see that Jill will also have fewer access to the document here. And we can go back to our dashboard and see that we have user Jill assigned as a group member and the group is assigned as fewer access. So let's go back to our slide now. Thank you very much. So if you're interested, we can go to look up the various resources. For example, you can look up the original sensible paper or go to our sensible academy where we explain how the whole sensible paper works. You can check out our FGA documentation, visit the playground to play and learn with it, go to the management dashboard where you can create a store and start hooking up your application to it. And if you're interested in learning more about our OpenFGA documentation, you can visit this website. If you have more questions, you can go to our Discord channel to ask this question. And you can subscribe to our Twitter to see our latest update as well as go to our GitHub channel, GitHub repository, and see our OpenFGA code. Thank you very much. Questions? Adrienne, I've got a bunch of questions coming in from the virtual chat. Some of them have been answered by your colleagues on the team. Thank you, team. But I'll read them out because there's quite a few. So how would you compare this to AWS Cedar, if you're familiar? AWS Cedar is something similar but not completely because the AWS Cedar is not directly focused on the FGA side. Gotcha. So next question, is the latency of list objects the same order of magnitude as an authorization check? It is longer because the problem is that you have to look up all the information, not just one. So if you have that for the check, which is optimized as long as there's one connection, you're good. But for this object, you have to traverse all the documents, folders associated with it. So it has a longer latency. Wonderful. And here's a comment from Ben in virtual chat. This model is amazingly powerful. I'm just wondering how tightly coupled we would become to this tech if we implemented it. If we needed to move, i.e., if we needed to move to another vendor, how open is this type of model? Not that I would want to move, but it is an architectural consideration. Good question. So there's two parts to it. First, the authorization model itself is like right now, there are movement in the open world where we try to consolidate between different vendors to have similar language. But this is an ongoing process. The second part is that the implementation that you see the model here, you call it the DSL, which is a language that's abstract. But internally, they are JSON. So you can even use the JSON to do manipulation or modification if needed. Great. I think you covered them all. Thank you so much. Thank you very much for your time. And there's that Discord channel if we missed your question. Thank you.