 We are so happy to have you here. So I'm Pauline, I'm French as you can hear and I'm a software engineer at AGCAP. It's the leading software for cash flow management. I don't know why I'm missing this. I have two mics now. Sorry. No, I'm Andres. I'm from Bison, Uruguay. So I speak Spanish. She speaks French. We tried to make this in English. See how it goes. I'm a product manager at Octa and I lead the OpenFGA product in the CNCF community. Okay. So let's start. So imagine you are a startup building a software like AGCAP with an account-receivable project. So you are dealing with payments. So at the beginning, like every software in the world, basically you have users and entities in any organization, whatever, and you have members of those entities. And only members can access its resources. It's a simple authorization rules, but at the beginning with a product with not much features, it works like a charm. So we had this model in our database, which is pretty basic. And every time you want to secure an API or something, we're just asking the question, is user N, a member of the entity Acme, then okay, she can access the payments. But when you are dealing with sensitive data, like in our case payments, do you really want all members to access payments? Not sure. So what we did in phase two, we needed to have administrators to say, hey, only administrators can access approved payments, for example. So what we did is just a naive approach. We introduced a Boolean, his admin, on the table. And now we can say, if the user is an admin, he can approve payments. If he's only a member, he just can see it. So now we have his admin everywhere in our code base. And it's not really scalable because we don't have a clear representation of what an admin can do versus a simple user. You don't really have a model, an authorization model with what you can do. You just have a hundred of occurrences of his admin in your code base. Except if you have a good documentation. But we know we don't have a good documentation in startups, so there it is. And then we needed our customer success and support engineers that we call staff to access the entity's resources. So to see the payments, for example, because they need to help our customers, right? But they can't be members of entities. So what we did is, again, a really naive approach. We introduced a role, like in a rose-based access control that we called staff. And again, table linking user in this role. So can you guess the next slide? So now, everywhere in our code base, we had hundreds of occurrences of his staff or his admin. And all our authorization rules were pretty basics, like when we want someone to approve payments and say, okay, who can approve payments, staff or admin, so staff or his admin can approve payments. So is there a better way? Because basically what I want to do as a developer is to say, hey, is user and authorized to approve payments? I don't want to ask questions about, like, she's staff, member or admin. I don't care. I just want to ask a business question with authorization. And that's when we started to look for something better. And we found OpenFDA. And that's why I'm here today with Andres. Thank you, Polin. So what is OpenFDA? OpenFDA is an authorization system for developers that is based on a concept called relationship-based access control. You can see it as an evolution of role-based access control and attribute-based access control. It's inspired by a research paper that Google published a few years ago, where they describe how they implemented authorization internally in a way that was flexible enough to support all of their use cases and also scale it well enough to Google's needs. What we did is we packaged those ideas in a server, plus SDKs, plus tooling to make it easy for you to integrate it in your applications. So let's try to see if we can help Polin to achieve what she wanted initially with the first version of Agica. I'm going to show now go to my mission studio code. And so this is the way I'm going to raise the phone here and see if you can see it better. Hopefully you can read it from the back. Is it fine in the back? Yes? Okay. So the way we OpenFDA works on relationship-based access control works is by defining two things. First, what we have here on the left is what we call an authorization model. There we are going to describe all the types or entities that are relevant when we're making an authorization decision. In the scenario that Polin described, that implied that they had an entity with three roles, administrator, staff members, and a couple of actions that they want to check if the user can perform or not, which is can upload payments and can view payments. And we're saying there that we can assign users to administrators, users to members, and users to staff roles. And then in addition of that, we are going to instantiate that model with data. And the data is in form of what we call relationship tuples that are like this. User, then I put a user type and a user ID. In this case, then I'm saying administrator, entity object type, object ID. So in this case, I'm setting this relationship. I'm saying that the user ID is user N, and the entity ID is entity ACME. This user could be users, or it could be applications, or it could be employee, whatever I want to use as a user type, it is fine, right? In a simple, same app, I could want to authorize multiple principles. Each of them would have a different user. Okay, so once I have this, I'm going to try to run OpenFGA and see how this works. So I'm going to start the server here locally. I could run it in a local container, or we have a chat if you want to deploy the Kubernetes, so the usual things. And then I'm going to open another terminal, and I'm going to just copy the things I have here. The first thing I'm going to do is I'm going to use a CLI that FGA has. And I'm going to create what we call an FGA store. A store has the model and the data that we're going to use for solving a specific scenario. And in general, you can have a store for development, staging, or for different applications. Okay. So I'm going to run this command, and you see that the store was created. I don't know what's happening. Okay. And I'm going to take this store ID and set it in an environment variable. Okay. And now what I can do is I can start writing these tuples to the system. I have this command here that is FGA, tuple, write, user, and administrator entity at me. The same data I have here. It told me that I wrote it. I can also import all the tuples that I have in that file, so instead of typing them one by one, I will get two that succeeded and one that failed, but it was already there, so that is expected. And then what I can do is I can run this command that is called check. That is the one you're going to run from your APIs. You're going to call user and API call to make this call to the system. In this case, user and can view payments for the ACME entity. Okay. And that is the way you end up integrating this in your application. We're going to see more details there. And in addition of using the product this way, we can also define a YAML file that has the model plus the tuples, plus different tests, for example, user and should be view payments in the ACME entity or approved payments in the ACME entity search. Should only view payments but not approved. Marie should be able to do anything. And if I have that, I can then use a tool that is going to run all those tests with my model, but I didn't tell me the old pass. This is a way I have to kind of iterate on my model and test it and make sure it still works as I expect. Okay. So, and then from your applications, you're going to use an SDK. This example is the JavaScript. We have one for Java.Net, Golang, and Python for now. You're going to call this method right when you're adding new tuples to the system. For example, a user decided to specific organization. Okay. That's good. That's a good day today. And then the other thing we can do is we're going to call check from our APIs whenever you want to know if a user can perform an action in a resource. This can be called from an API or from an API gateway or any moment from a Rigo policy. At some moment in your stack of executing an API, you need to call this API to know if the user can perform an action on a resource. So, Pauline, do you think this is going to help you? Yes. Actually, as you can see, the model is pretty clear. We have a clear authorization rule, like the one I wanted. And when I need to ask a question, I ask the question, is a user authorized to approve payment on TT Acme? And I don't know if she's administrator or what, because it has been initialized before. Perfect. So, yeah, it's perfect. And just to add a little more context about how this works, right? You get a request from your application. In your API, you're going to call up the FCA saying if the user can perform an action on an object, you're going to get yes or no, and you're going to return that to your application, right? So the API is the place where you do the enforcement there. And it's centralized. Yeah. OpenMCA is going to write this in a centralized database. It can be posted on my SQL and that the data is there. Okay. So now I have entity administrators that can approve payments. And now I want to say, like, the owner of the payment, the one created it, actually, I want his manager to be able to approve payments like in a Spain solution, you make payment with a card, for example, so you are the owner, but only your manager can approve it. Can we do that with your model? Okay. Let's see how that can do and see if it wishes to your code doesn't crash again. And so for what you explained, Pauline, what we want to do is something like this. So we're going to, this is what we had before, write this entity and this user. But now we want to introduce a new type. There is a payment that is going to have, and it's going to belong to a specific entity, Acme or whatever other customer you have, and it's be owned by a user, right? And then we can, we want to define permissions based on this. However, this time we're going to try something different. In Agicap, they built a BDD tool that lets product managers specify how the system should behave from an authorization perspective. So here they say users, managers, and administrators can approve payments. Omar is a member of the entity Acme is managed by Marie and is the owner of the payment. And then we say, okay, we've given the, and it's an administrator. Omar is a member and Marie is the manager of Omar and the entity. Yeah. So Omar should be, sorry, and given that this payment is part of the Acme entity and Omar is the owner of the payment. Omar shouldn't be able to approve it because he's submitted the payment. He cannot approve. Marie should be able to approve because she's the manager of Omar and should approve because she's the admin. Okay. So what we're going to do is we're going to first store this, this new model in FCA. So I'm going to write the model. Okay. So, sorry, I did the wrong thing. This one. Yes. This one. I'm going to write the model and that works fine. So the next tool that Acme created is called FCA BDD and send that definition that we just saw. You see here, it's telling me that the relationship payment can approve doesn't exist. Okay. So let's go and add that. So we're going to define here, define can approve. And then I'm going to say, I can't look at the test and figure out what should I do here, but I'm going to just do something more intuitive, which is if you can approve payments from the entity, you can approve payment. Okay. So I'm going to write this model again and now I'm going to run the tests. Now it's telling me that there's a manager relationship that doesn't exist. Okay. So we need to define now that user can have a manager, which is a user. Perfect. I'm going to now write the model and try to do this again. Now it's better, but it's telling me that Marie should be able to approve the expense report, but she's not. And that's because Marie is Omar's manager, but we haven't defined that here. So we can say that you can approve payments, if you can approve payments from the entity, or if you are a manager from owner. Okay. Now we write the model and we try this again, and now it succeeded. Okay. So the idea here, if you see, is that we can start defining these additional resources for everything you have in your application. And when you're defining permissions, you can start walking up the hierarchy of relationships to now to define the specific user can perform an actual on a specific resource. Make sense? And it's perfect because my project manager, that's not Andre, but I'm letting him do all the code. But my project manager can write tests with me and she can actually read the model. Like the model is readable from a product perspective, because it's really clear. Like who can approve payment? Like the ones that can approve it from entity or the manager of the owner? It's really, it's like English for it. So it's perfect. So now, like I said before, we wanted staff to be able to help our customers, so to see the payment. But what we did at first, it's letting staff see the payment for every unlimited amount of time. And now I want to be able to say, okay, so the staff can only see my customer's data for a limited amount of time only when they are in the phone with the customer. So I don't want to be, I don't want it to be like open for everyone to see because it's still sensitive data. So can we do that with OpenFGA? Yeah. So that's an interesting scenario, right? In most of our applications, we have some kind of super admin role or something like that that can perform actions that they shouldn't be able to perform all the time, right? Only in very specific situations, right? So let's see how we can model that with OpenFGA. So we have a third model here. This is the one we previously had. But now when I'm assigning the staff relationship, I'm saying like staff equals user with time constraint. And then I define a function here that is called time constraint. It can be whatever function is a function I just created. It receives current time, grand time, and grand duration. And then it succeeds if the current time is less than grand time plus grand duration. Now, when I write the tuple, in this case, I'm saying like a search is a staff of the entity Acme. I'm specifying a condition while search is a staff of that entity, right? And then we're saying we have time constraint starting today at midnight for one hour, right? And then when we are checking for specific permission, the way we're going to do it is we're going to call user search related to object payment at this moment. And this is going to be true or false depending on the moment. In this case, this is tomorrow, so you should return false. In this case, this is today, 10 minutes before midnight, it should return true, right? So now if I, let's see if I do this right, if I go to the CLI again and run this test, FGA model test. Did you update the model before? No, in this case, I don't need to. Just let me see if I can make this bigger. Okay, I'm not going to be lucky with this. Tests and steps. Yeah, I am all. So when I do this model . Okay, so what I'm doing here is I'm kind of executing this YAML file with the model, the tuples and the tests, and it's telling me that all are passing. If I change this and I say I expect this to be true, for example, and I run it again, one is going to fail and I cannot see it because I cannot increase this. Yeah, so this one is the one that failed. So I'm going to run this model with these conditions and based on that, define permissions only for a limited amount of time. I can use the same conditions for other things like based on an IP range or whatever value you want to compare, you can define a function that takes that value into account. So. Perfect. So how did you open FGA help? So first it's centralized, so we don't have like hundreds of occurrences of is admin or staff and every microservices redefining this function. So now we just call an IPI and we ask our business question. It's fine-grain, like you saw. I can really go fine-grain with saying, okay, the owner, the manager's owner can approve payment but not staff, et cetera, et cetera. It's readable, like my own product manager and every product manager at IGCAP, they can read the model and understand it very quickly. And it respects your business logic. So we are a fan of domain-driven design at IGCAP, so I don't know if you practice DDD here, but yeah, it's like, it follows the DDD principle, like making your authorization close to the business. Great. So and something that I've seen this link of, like when you're starting a new project in a new company, authorization is the last thing you want to think about, right? You're very focused in trying to solve the problem you want to solve, right? So this thing of starting with is admin or no authorization is very common, right? I joined Okta as part of an addition of another company called Outsero. Outsero had a, I joined Outsero like six years ago, was five years old, the company, the managed dashboard of Outsero didn't have rules. Everyone could do everything, right? And that is kind of an authorization company, five years ago, right? So it's very common that this happens when you're in the startup trying to get product market fit. You don't care about authorization, you can care later, you can integrate it with something like Open FGA. And so Open FGA is currently in the sandbox stage. We just proposed to incubation like four days ago. And so it's number eight in the list of projects based on the number of commits in the CNCF set of projects, which is surprising, but awesome. And so if you want, please join Open FGA. So we have a very welcoming community that a lot of people from other companies are helping us to move this forward. And I know like if you can join us, you can also join Atchicab that I know they are hiring. So if you want to work on Open FGA on the other side, you can also work with them. And so thank you very much. Thank you. We are going to have a kiosk in the project pavilion. And please send session feedback here. We have time for questions. We have 30 minutes. So someone has a question? Yeah. Maybe you can. If you want to go to the microphone. Thank you. My question is we are trying to put this in production. We are facing some issues. Maybe there is no, I didn't see any like white paper with practices. How to use, for example, how applications can know the model ID, which is calculated at runtime. Anytime, anything, anybody in any environment, which is this model ID will be different. I know the bigger needs to know this model ID. So how to deal with this, at least I cannot find information on how to do that. So awesome. So he is a very experienced Open FGA developer and he is asking a question. So thank you for the question. What happens with Open FGA is that it's time you write a model. You might have seen that I wrote a model and it says something model ID and it shows me a model. It's like you are always updating a model, you are never overriding it. So if you are using an application, you want to target to that model ID as part of the HAPI you call to make sure that your application works with that specific model. So if someone changes the model later, you can change in the applications later, but it's not that your application is going to break. The process there is after you build the model, you need to put that in a vault or something that the rest of applications can share. So it's kind of a shared secret. You treat it as such and when the application is deployed, you get a new model and you get a new secret that the rest of applications can access. We can go into more details there, but it's something like that, right? One more question. I think Pauline is there. It was more just a question about the examples you showed. Is there a place we can find those examples that you showed today? Sorry, what? The examples that you showed on the presentation. Can we find any? Yes. So we have an in the OpenShare repository. There's a samples store in the OpenShare organization in GitHub. There are samples to store projects, right? That has a lot of examples there. Not exactly this one, but very similar. Okay. Hi. My presentation. I have a question. Do you have any, so you mentioned the policies and data are stored centrally. Do you have any model where you can push that more locally for, or how do you deal with things like latency, for example? Yeah. So you can, so right now the storage are Postgres and MySQL. We have people that are developing one for SQLite, so you can deploy it more locally. In general, the thing is that when you're making authorization decision today, you generally are looking to a lot of reading databases to make the decision, right? So you're trading off that latency, but you're not making those anymore and you're calling OpenFGA, right? So first I will try to check if you really need that complexity of having the data spread in multiple places to have checks more locally. If you do, you can, you can have a product like OpenFGA that you call the service because everything is going to be like more consistent and easier to manage if you can do that, right? The system is designed to have pretty low latency, right? Okay, so I think that's it, but I'll be out there if someone wants to follow another question, okay? Thank you very much. Thank you.