 I think we can start, but I want to start with a disclaimer. This deck, when I created the first draft of it, took me one hour and 10 minutes, and then I have to reduce it to 25 minutes. So some slides will be packed of text, but I'll speak less, but be relaxed, I'll share the deck after. So no worries if you see a lot of text and I'm just speaking for 10 seconds. First I want to share with a personal issue I have in my life. It's really hard for me to connect with new people. That happens since I was a little child, and I'm happy to sit here in the room with many other that choose computers as friends instead of people. When I was a child, I have a little brother that helped me. Any time I had to connect with someone, he was just like an extrovert guy, very different than me, so he just did the work for me, not for money, maybe sometimes, but generally not for money. But when I grew up, I found myself again and again a situation when I need to connect and socialize with new people, and something getting really urgent, but I'm postponing it because it's really hard for me. And as a good developer, getting a problem and trying to identify what actually make me hard to connect with new people, and I identified four problems. The first is the chaos. I need to reach someone. I need to ask someone, where is the line for the tickets? I have thousand stories in my head how I'm going to say that. I have no structure how to say that. Second is a complexity, too much keywords, too much ways to say that, too much languages sometimes. The velocity of that also create problems because I need to do it multiple time a day, and my social battery is usually limited. And last is the confidence that I have to have when I'm trying to connect new people so many times in so many complex ways. My name is Gabriel, and today I'm going to share how I took a solution from my program life into my personal life, but in a meantime, we'll talk about the domain specific declarative languages. Since the early day of problem in software, people tried to create more productivity to automate stuff, and in the beginning, they used to code with machine code, just took a silicon and tried to write some binary or next assembly code to that. But then they found that computer are good in solving a lot of problems, so they tried to find a structure to it, right? They tried to get a structure from the chaos, so they created languages like C for personal computers and servers or Fortran for scientific stuff. Then the structure became too much complex, right? Because if you write a large program with C and you try to have productivity, you get a limitation. So people invented design pattern, like object-oriented programming, and then they created languages to deal with this design pattern. This is where C++ came into the tail, but that's not only old, because when we got a lot of problems with concurrency, we invented a Go language to deal with a very specific design pattern of concurrency. At some point, the velocity of the software gets faster and faster, right? If we are delivering software to a browser, we need to deliver software very fast and the user will get it at the minute we will deliver it. And then we start to create a framework or we start to take languages and make them to a framework languages. For example, if you think on JavaScript, there is no JavaScript developer. There is no JS developer. There is React developers. These languages that we are using because they are oriented from framework and that help us to create more velocity. At some point, this velocity breaks software and we need more confidence. And a very specific confidence of, for example, if we are delivering user interface, we want to make sure that it looks exactly as we mean for. And this is where we start to use domain specific declarative languages, like HTML. I know it's not a programming language, but it's still create a domain specific confidence that when we are delivering UI, when we are delivering code that should represent user interface, we can have the highest confidence that what it looks there is what the user will have. And just to example the simplicity, here is example of code, it's not a real code, it's just to get from chatGPT how to write a simple div in all languages and how to write it in HTML, right? So domain specific declarative languages create us an option to be in a high confidence in what we are delivering, do it in a high velocity, simplify the structure, not always, I know CSS break everything, but still it solve us problem. And it's not only user interface. We have tons of domain specific declarative languages around us for configuration like Yammer, there is even languages for creating music or creating some kind of tests and stuff like that. And we always want to get these domain specific declarative languages to help us with the problem. A new problem came lately, the problem of getting decisions. Now I know you probably said maybe you and your partner has a problem with getting decision and that's good for the TV dinners company, but in software the most basic thing is like getting decision. The if statement is a very basic ability of every programming language out there. But that's not the case in some specific decision. Is anyone now the context of this or what is in this picture? Sorry, so unfortunately in my 30 crisis, I started to have a new hobby, coffee, and if you're following the coffee world, there is a new trend lately or for the last five to ten years with a single origin specialty coffee that is roasted to perfection and then made in a very precision way to get the most of the taste of this coffee. You need to have a very consistent fine grained grinding on this beans and then have a precision temperature and a very consistent one to make it to perfect. And that's actually what happened today when we want to get decisions for authorization or policy decision, what a user can do, what a service can do. And that's very fast getting to this kind of code. Now you probably said this code is bad and you have tons of bad patterns here, etc. But let me talk about some problems that will get you to such good at some point of time. The first problem is about architectures of application. When I started to work in development back in 2010, we had one server, one programming language, one database, and one application, right? Today, even the very basic applications start with a service, with another service for to be API gateway with a UI application, right? So the simplest stack is starting with tons of services. All these services need to get the same decisions for all users and all services. We don't want user to access data that they are not supposed to. And these decisions have to be streamlined across all the stack and code the same and get the same decision. The second is the data point that we have today. Again, in LAMP or in older architecture, we used to have one database, one SQL database. Today, again, simple applications start with two database, one for tables and none for tables because we like the complex thing, right? So the data that we have is getting complex and complex in our application and all this data supposed to have same security levels on the decisions that we are getting. And that's also create a lot of complexity on how we are getting these decisions. Then when we have a lot of data, we get at some point that we have more and more decisions because we need to get decision on the amount of data that we have. But the amount of data is also drive the way that we are getting decision. We should have much more data in our decision making. So we got to some point of decision fatigue and we say, we are not supporting that level of fine graining authorization of our decision because we are tired to create such complex decision. And then the velocity because, again, we're just delivering more and more software and more and more endpoints, production environment, getting new software every minute. And that's also create a need for a layer that we can trust that we always getting the right decision, the right policy decision of what user can or cannot do. And last is the confidence. And I think that's one of the biggest problem today in applications. The user really want to, I mean, user really want to have impossible features, right? The application user, and you get to an example soon, want to own the data, want to have a privacy, and you need to support that. But not only that, application users are not application users anymore. Even our organization is much more stakeholders to the code, right? DevOps, RevOps, APSEC, whatever apps is it, they want to get access to the code and they affect the way that we are delivering software. It's affected the way that we need to get right decisions, okay? And if we're just speaking about what user want, this is a great example because back in 2018, not that much years ago, all my healthcare data were owned by healthcare insurer, right? So if, for example, I came to the doctor and I want him to have healthcare access to my healthcare records, I trust my insurer to provide that, right? But today I'm owning my healthcare data and I want to have a very specific fine-grained authorization on what data my healthcare has. So for example, I'm getting to a nurse and I want to give her access for 10 minutes for a very specific data, right? And that's happened in only five years. It's happened probably because the COVID, but still user really want to govern the on data and make sure that you are getting the right decision about this data. And also lately, Vectors, AI agents, LLAMs, this is create a problem of unstructured decisions, right? Because AI agents or VectorDBs want unstructured access to our data. And how can we get the right decisions in the data that we are providing to them? Right, so this is actually the same problems that they have with connecting with people. Right, I have the chaos of all the architecture and the services around. I have the complexity of the data that need to get decision. The velocity is just here without the velocity we need today. We didn't have KubeCon and with so much people and the confidence that we need. So let's see how we solve each of these problems. How we solve chaos with structure, right? The same as see solve the problem of machine code. First, we need to understand where we need this getting this decision. Where we need to get this complex decision. So the bottom layer is the code itself. The developer today has a lot of effect on how the code is delivered, how the production looks like. So this is where we need to get the decision. Who can deliver what, when, where, whatever it is. And then we have the services itself. We need to get a decision what service can talk with other services. And how do they deploy in the CI CD and speak with each other. And then we have the application itself, the backend and the database that we also have a level of control on who can read what from our database. And on top of that we have the front end. We want, for example, to give some user some screen and fields and some other than that, right? So now that we have a structure where we need this authorization decision, we can have a better solution designed for that. Then here is an abstract architecture of how we want to do that. The first point is that we want centralized policy configuration. We want all our configuration to be in one place that will help us streamline it. And that will help us make sure that we are standing in all the standards that we're trying to define. And then we have the policy engines themselves, right? We have a piece of software that knows to take this policy and get the right decision on it. But that need to be decentralized from a couple of reasons. The first one, it has to be very fast. It has to react very fast. If you think about your API endpoint, an average API endpoint has five authorization decision that they do. Usually we consider them as a feature, but at the end we decide what a user can do and then we decide what a particular set of data that they can get and if it invokes some workflow. So decision, decision, we need to decentralize this decision. And we want every part of our software, every part of our stack, to be able to enforce permissions based on this decision. And that create a structure in the architecture we want our policy engines and authorization to work. Here is an example on how to model it in application in a domain driven design. So we have the authorization domain which has the policy data and the policy configuration that help us getting decision. And then every application only has some decision engine deployed with it that get all the data and config from the domain of the decision. So here is the structure that solve the chaos and now we want to solve the complexity. And as we say, the complexity is getting solved with design patterns. What are design patterns we have in decision? So the first one is defining what are the components we do when we are making decision. Here is a very simple design pattern proposal. We use policy which is like the code that getting the configuration. We use the data that we have in the system, what we have in the DB, what the identity provider provide us for this user, what is the configuration of this Kubernetes cluster. And then we have the context. The context is what happened actually now. When we have this design pattern we can always try to think how do we focus now. So now we need to focus in the policy that we are creating. Now we need to focus in the data that we'll use when this policy will process to make decision. And then we have to think about the types of the decision that we want to make. So I have in my design pattern two types of decision. The first one is binary decision, is something allowed or denied. It's the simplest decision. The more complex decision is filtering data, right? I want to get a lot of data from somewhere. I want to filter this data. And then after I know the basic, I can have design pattern for the check functions, for the pure function that's supposed to get decision. They always should get the same arguments. They always should get the same decision. What are the argument of this function? So I can define user or principle because it's not always user. It could be a service or something. Then we have the action, what they want to perform. The resource they want to perform on. And a context, context can help me get more decisions. Some decision need a lot of context that is not part of these three, right? So if I'm creating a server with this three, with this four argument, I can streamline the design pattern that I'm getting decisions across all my stack in a way that will stand for all the decision type. If I want to do filtering, so a nice design pattern is what we called partial evaluation. Partial evaluation means because software is built on source trees and abstract binary trees or non-binary trees, you can always convert a decision into a query language. So what we can create, a design pattern we can think of, is an engine that knows not only to get a decision based on set of data but also convert it into a query language that will help us to get only the data that we need. So we have design pattern. We have the structure in our head. And that's where we start to define framework. In my opinion, the best thing to think about is policy models. So there are tons of policy models. They all end up with AC for access control. Probably most of them in BAC, based access control, some not. But I think the best one for our applications today is this for policy-based access control, role-based access control, attribute-based access control, and relationship-based access control. And I explain why each one of them is different. Then I'll explain what each one of them does. So first, this policy-based access control is a way that we can very easily define policy rules, right? If we have a language that we can write this kind of rule, we can get a decision that are based on policies. The problem with policy-based access control is if we want to keep this decision engine pure, we are less able to use data. So if we need to get a decision that are based in a lot of data, for example, what a user can do or some complex data from our billing system, policy-based access control, we're a bit less relevant for that. Role-based access control is the most traditional, I think, in the market, and actually it uses a generic name for authorization for many people. We are segmentizing users by role, and then we are defining what action they can perform on a particular set of resources, right? So role-based access control is very simple, but it's also not granular. We want to get a fine-grained decision or a specific resource or a specific instance of a resource getting harder. This is where relationship-based access control came into the picture. It had a relationship perspective or angle to the roles. So what we can do instead of assigning role for a specific resource, we are assigning users or services role for a specific instance, right? So we can say, I am the owner of my file, and I think about relationship-based access control is that leverage the relationship that we have in application to derive these roles from each other. So for example, if I am assigning owner to my folder, the relationship that exists in the DB to all the files in this folder will propagate me or derive me the role in that, right? So if our software is very distributed and decentralized and we can build it like a graph, relationship-based access control will let us get much more fine-grained decisions on our make fine-grained decisions, sorry, on our data. Then there is attribute-based access control, which in my opinion is more complex than all, but is very grand. And attribute-based access controls say we don't need roles, we don't need resource types. What we can do is attributes. Every object has attributes. What if we can build conditions on these attributes? For example, we can say if an owner ID on a resource is equal user ID, that's a resource that we are allowing. But if it's not equal, we are not allowing that. And then we can create very complex conditions. And what good in attribute-based access control is super decentralized in a way that we actually don't need one data because the data is always either in the context or either in the policy engine and the condition is better dynamically on that. Here is an example of how we can model a combination of these three. So in the left-hand side, we have the resources. These are the resources we want to allow or deny actions on. This is an example of mobile plan management application. So we have the users itself, which are also resources because there is admins and there is representatives and there is users. And then we have the plans. So in the left-hand side on the bottom, we have the environment-level role. The RBAC, we are having administrators that can modify or do something to agents. Then we have in the right-hand side the resource-level roles that we can assign to a specific instance of account. And we also derive permission from the editor on account to the editor of plan if the account is apparent of this plan. And then we also model condition sets for active users, which mean the attribute blocked on the user is unequal to true or equal to true, something broke here. And plan, mean plan owner is user ID. So if we are taking this framework, we can imply a very fine-grained model on any kind of data that we have. These policies actually create us a way to do these fine-grained decisions in a very efficient way. Here is an example code that used these three. If you look at this screen, you can see that the manager is RBAC. They can list all the agents. The representative has access only to Harry Potter because it actually assigned to the specific role, and they can also change the plan because they have derivation. And we have the user that has access because of the A-BAC, because they are owner of its own plan. Okay, so we do have structure. We do have design pattern and frameworks, and now let's talk about implementation. And what's better than create a domain-specific declarative language to make it simple? Here is an example of AWS Cedar. This is an application-specific authorization language where we create a policy, an A-BAC policy, so we can see we have the three principles, like principle, which is the user, action and resource, and then we can define conditions. On the principles or either in one statement that help us create more complex conditions. If we have this language and we have one repository with such files that create policies, we can have much better fine-grained decisions on our stack. And declarative language has a lot of benefits on imperative language, but the main one is readability. When I look at the code, I immediately understand what is happening. Not only that, domain-specific language also help us with performance because they want to do one domain. We don't have the danger that some other, our external factor, will affect the time that it takes us to get a decision. I can say from personal perspective, I'm eight years around policy languages, and we got into times that we'll never succeed to get in imperative languages. So that really could help in a location. In performance. I want to speak about three languages today, OpenFGA and the language RIGO, AWS Cedar, which I showed you already example, and OpenFGA, which is not only a language, it's more a decision platform or authorization platform. There are many more, but this one has principles that I think differentiate from the other, and this one I think is the most important to know. So here is an example of a RIGO code. This is the OpenPolicyAgent language that getting a decision about attributes of a user. So we validate the department and the classification, and then we can create rule apps there to see if a user has a permission. OpenPolicyAgent and RIGO language, in my experience, are very good, and they are good for multi-purpose. That the power of OpenPolicyAgent, the language has so flexibility, has a large flexibility that can help you create any kind of decision you want. But RIGO is complex. It might maybe miss the point of declarative language because it's a complex language, but on the other end it can get very complex decision on any layer. So it doesn't matter some library use it, the library kicks that use it for admissions on the infrastructure as code. And there are libraries that use it as a plug-in for envoy and API gateways and for application themselves. And there is even a plug-in that do it for React application to get a decision there. And you can run it as a Wasm or as Go library. So if you have the ability to learn this new language and you really want to have one agent across all the stack, with one policy across all the stack, OpenPolicyAgent is a great choice. Then there is the CIDA language and the main point, there are two main points about CIDA language. AWS released it a year ago, yeah, last April. And there is two points, two principles. First one is super fast, means the user definitely language, a scientific proof language to prove the time that it takes for decision. And they are committed for a time for decision no matter what his policy looks like. But the data is complex. So if you want to manage data and you want to get decision based on graphs, on structured data, it's hard to do that. And then, I'll skip that. Then we have the OpenFGA. OpenFGA is based on Google Zanzibar. It's especially helpful for relationship based. It has a graph engine in it and you can define relationship. Yet it's less powerful for RBAC role based access control and attribute based access control. Here is the key differentiation between them. I'll do it short because we're just out of time. Open policy agent, super multi-purpose, super helpful but a complex language. AWS Cedar, super powerful for application level authorization but has some limitation in relationships. OpenFGA good also only for relationship. If you really have a distributed application with relationship that need to be connected to each other, that's a great choose to go with. There is also a slide, I'll share it later what large company does. Every logo here, as a blog post, they share how to do it. I also want to talk about open source service that we are doing that let you running policy languages very easily near your application. So OPAL Open Policy Administration layer is a project that I'm one of their maintainers. It has a battery included approach. It means you can plug in any kind of policy agent you want and just give you like a wrapper service so you can use it efficiently anywhere you want in the stack. I'm not going over it and actually the same solution work for my personal problem, I create a structure of the sentence I want to say and then I am doing design patterns on how to connect with people and I know better how to connect with people at least. Thank you.