Thank you for registering for our webinar! Whether you joined us live or plan to watch the replay, we're excited to share valuable insights on enhancing your application security and efficiency.
During the session, Alex Olivier, Cerbos Chief Product Officer, and Wesley, presenter of the popular ByteGrad Youtube channel, demonstrated how to author permissions and policy changes using Cerbos Hub, and deploy those changes without changing any other code.
Scroll down to read a high-level summary of the webinar, and check out the transcript.
Alex clarified the distinction, highlighting authentication as the process of verifying who someone is, whereas authorization determines what resources a user can access.
Wesley discussed the technical debt and security vulnerabilities that typically arise from handling roles, permissions, and policies across multiple apps and platforms in-house.
Alex examined how Cerbos Hub simplifies creating, managing, and deploying access control policies across your entire application landscape, ensuring a unified and secure approach.
Setup of a free policy repository on Cerbos Hub to defines roles and permissions.
Instant policy synchronization across your apps, from front-end frameworks like React and Next.js to back-end Node.js services, mobile apps, and APIs.
Utilization of WASM libraries to enforce and sync access controls seamlessly, ensuring a consistent security posture across any environment.
Alex discussed additional features of Cerbos Hub, such as audit logging and trail, SDKs for all languages, and others.
Alex Olivier: Excellent. Hello everyone that's starting to join us now. We'll begin our webinar in a couple of minutes. Give everyone a chance to join in. So grab yourself a cup of coffee if it's in the morning or maybe something stronger if you're in the evening, depending where in the world you are. And we'll be kicking off in about two minutes.
Wesley: Hello everyone. I'm Wesley. I'll be talking a little bit as well. I'm gonna show you a practical demo of using Cerbos and Cerbos Hub in practice. soMe of you may already know me from a YouTube channel. I create React and Next.js content. So maybe you've seen me before some of you're actually in my course.
I think. So welcome to the call. We'll start in a little bit.
Alex Olivier: One more minute.
Right. I think we will kick it off. So, hello everyone. Thank you for joining this webinar with Cerbos and talking about the simplifying access controls in Node.js, React and serverless applications. By way of introductions, I'm Alex Olivier. I am a CPO here at Cerbos. Focusin on authorization space, and as this has maybe be an educational piece, we went out to the world.
I found one of the best educators we've found out there to demonstrate today Cerbos and how you can improve your authorization in your applications. So, Wesley from ByGrad, how are you doing? Good to see you. Good to see.
Wesley: Thanks to everyone. What you guys have built at. I think it's a wonderful product.
So a little bit about me. I'm a React Next.js developer and if you've watched any React or Next.js contents on YouTube, you may have seen me. I came across Cerbos as a solution for authorization, and I found it really interesting because I ran into many authorization problems myself. I've built my fair share of SaaS startups, and I noticed that as soon as the product gets a little bit complex and you have.
Multiple roles and permissions, you start to run into quite a few issues and the whole code becomes messy. So I actually already thought about why that was a problem, why it was so difficult to solve that, and I came across Sorbos and they have a great product, I think. So that's what we're gonna talk about in this webinar.
I'm gonna show you a practical example in a little bit.
Alex Olivier: Great. Yeah, we're really looking forward to that. So just firstly make sure we are all on the same page. This term authorization unfortunately sounds very similar to other terms. So just to clear, clear air, we're talking about authorization, not about authentication.
So the difference of those two authentication with an N is all about taking a credential from a user and verifying who they are. So online, this is logging in with your password. This is logging into Google account. You kind things real world. It may be like showing your passport once you get on a flight, for example.
And that's authentication. Authorization is the second piece, which is once you know who someone is. What are they allowed to do? What actions can they perform? What part of the app can they interact with? Are they allowed on that particular product? A real-world example. Now, unfortunately, AuthN and then AuthZ are these terms that get bandied around.
They're two very different concepts, basically linked. But today we're really gonna be talking about authorization. So working out in your application in code, your code base, what a user or what a particular actor can do with inside of your system, and which actions they can perform. So to give you an idea of what this might look like today, if you were to building an application or you are looking at your code base today or looking at out there uh, somewhere in your code, there'll probably be an if statement that looks something like this, where you've got the user, they're authenticated, you've got their email address.
Maybe you are like selling different packages or software. You now know what package they belong to maybe use it in different groups and you end up just kinda like. Complex Getty code type, whatever logic where you're checking whether someone's email address, it contains your company domain that should be able to do an action.
Or you're checking what package they purchased or what user group they belong to. And this logic gets quite messy. You know, smaller application is quite simple, but if you imagine every code path and every service inside the application, probably have to do some sort of permission checks or access checks to decide what to do.
So this code ends up being. Every part of your application starts
Wesley: Alex people. People in the chat, sorry to interrupt you, people on chair are saying your volume is a bit low. Maybe you can turn it up a little bit.
Alex Olivier: Yeah.
Hey, now how we doing that? Better? Hopefully that is,
Wesley: maybe you get bit closer to the mic.
Alex Olivier: Two seconds.
Are we doing? Is that better? It's louder. Excellent. Apologies. We'll continue like this. So the authorization piece, the spaghetti code ends up distributing across your various different parts of your code base and can get quite complex and quite embedded. So, Wesley, you, you already mentioned at the start there that you've kind of built numerous systems and numerous applications and you've had to kind of face this challenge and kind of come up with solutions for it.
Maybe it's kind of worth just highlighting some of the pain you've seen and the pain you've experienced with trying to implement this logic in your
Wesley: code bases. So, for example, actually this code sample already shows it. So in, oops, I think I just. Went to the next, next slide, but some users are from the EU and the EU has different standards when it comes to user data, right?
So you have to be careful with passing EU user data to other regions. So it, you, you wanna, you wanna make sure that the user data is safe, cannot be requested outside certain regions. So I had lots of issues with. With with regions actually, but also my girlfriend actually works at large corporate and there's always issues when she goes to a different region.
So I know that regions are a big one, but I, I've built some SaaS products and I always start off with just a basic user and a basic admin role. And you can get going pretty quickly like that, but as soon as it becomes a little bit complex and you want to add more roles and permissions, I always run into issues.
And I think Cerbos is a great solution to, to, to solve that.
Alex Olivier: Yeah, I mean, some of the challenges we, we kind of see, and this is really we built Cerbos based on kind of pain we experience from building system ourselves, is you end up in a situation where you are like hunted down. Logic across your code base.
If you wanna go and for example, have a web of microservices in different languages, you might have some of JavaScript, you might have some going on summer Java. Whenever those business requirements change or those authorization logics need to change, you then need to go into all these different services and all these different languages and update that business logic and basically translate or those requirements into code.
So the way Cerbos is helping you solve this problem in a far more scale approach is by decoupling all that logic outta your application code base. So Cerbos policy decision points is an open source project. Go and find it on GitHub.com slash Cerbos. And the way it works is it basically takes all that application authorization logic outta your code base and runs it as a standalone service that runs inside of either inside of your infrastructure or as a kind of function that runs at the edge.
For the high level, how it works is you have your end users, they're making requests to your application. Inside your application you have your sly, your request handlers, and inside that request you really know two things. Firstly, you know who the user is 'cause they've authenticated that step's already happened.
You know who that you've got there. User details maybe from a directory or database, you know what team they're in, those kind of things. You also know what about which resource they're trying to access. So based on the actual URL, you know, they're trying to view a report or edit a dashboard or submit an expense.
And you can go off to your database and you can go fetch that record from, from the system. And you also, based on the URL, you know, what action they're trying to do. Create, read, update, delete are the common ones, but approve, deny, comment, flag, or are kind of open-ended based on whatever your application does.
And then as we were talk showing in that snippet, that's where you might then have that big if-else case switch style statement. Service model is all that logic is now deployed as a service that runs alongside your application or runs as a function that runs alongside your application and inside of your code base, you package up that information about who the user is and what the resource they're trying to access is, and the action, and send that data over to a a service instance.
That server's instance has loaded into it. Policy and policies are a much more human readable way of defining your authorization logic, which we'll see in the demo in a second. Ultimately, the YAML files that define, okay, for this resource, here are the different actions, and for each action, here are the role user must have, or which condition must be met for that particular action to be allowed or, or not inside of the system.
And those policies sit as a another asset. They set a configuration inside your code repo. They sit in a GitHub repo. They can sit in database, they can sit in a bucket and really kind of makes whatever makes sense to you. And all those policies are loaded up into that service instance. So now in your application, when you send that request over to that service instance, this resource is trying to, this act, this principle is trying to do this action or this resource.
These policies are evaluated. The service engine comes up with a decision. Either allow or deny, creates an audit log of that decision, and it simply returns back and allows and denies back to your application. So all that logic is now reduced to a single if statement. If service says allow, do the action.
If not return permission. Denied message. And what this model really means now is you can evolve and change your authorization policy independently of your codebase, which has kind of massive wind when it comes to very distributed codebases or codebases in different languages or complex requirements that need to be tested thoroughly.
You can actually now unit test those policies separately to your application code to really make sure that your authorization logic is as is as secure and performant as you kind of expect and kind of meets all your requirements. So let's service the open source project, so it's PDP. Go grab a get help you get up today.
Cerbos Hub is our offering that sits on top of the open source project and Cerbos Hub is a management control claim that your Cerbos instances connect to and that the Cerbos Hub environment connects to your existing repository or policies. It acts as a managed CI-CD pipeline. So whenever you push a change to your policy.
That Cerbos Hub will compile, test and validate all those policies, and then Cerbos Hub will coordinate the rollout of those policy changes to all your Servers instances. So if you're an environment where you're running high availability, 3, 4, 10 dozens, hundreds of Servers instances, Cerbos Hub will ensure that all those instances will get the updates whenever there's a change in a coordinated manner rather than each one having to pull in policies separately.
And this basically ensures that your application's always serving based on the latest policies that need to be applied. The Cerbos hub environment also generates a second version of your policies as a WebAssembly module, or what we call an embedded policy decision point, which we'll be seeing, which allows you to do authorization kind of at the edge or on device.
So if you're running an environment like Basel, let's say, where you have edge functions and these kind of things, you can actually do authorization right in those functions without having to run a. Or for those cases where you want to conditionally show high buttons or menu items, you can pull those policies down directly onto the client via a browser or a mobile app or those kind of things, and actually do the evaluation locally on device, all while working on the same set of policies that are running in your backend and Cerbos Hub coordinates that that rollout and that synchronization of where policies are being served to make sure everything's always up to date and serving based on your latest policy.
That's enough of me talking. Let's go and see a real-world example. So I'm gonna hand it off to the best round of the job. Wesley, please take it away. Stop over
Wesley: screens. All right. Thank you very much, Alex. Let's see. I can share my screen like this, so hopefully you can now see my screen. Yep. Can you confirm Alex?
Yep. All good. Right. All right. So I'm gonna walk you through a simple example so you can see how that entire diagram that Alex just showed you, how that actually works in code. So it looks maybe a little bit intimidating but actually it's very logical once you've seen the entire flow. Once you'll easily understand how it all works.
I'll also show you why we even wanna do this. Why go through the hassle here? The friction is really worth it, in my opinion, and I wanna show you why that's the case. So I have this simple demo app. Let's say we have some kind of ex expense management type of app, and if li we are currently logged in as a particular user, let's say as a Lisa.
Lisa has a role of manager and she is in the engineering department. Now, depending on her role and department, we may wanna render an edit or approve button on the page. So you can imagine that if somebody has the manager role, we wanna show an approve button. But if the user has. Just a basic user role, so not a manager.
We should not be rendering an approve button on the page, right? So we want to change the UI depending on the permissions that the user has, and we can very easily do that with the WebAssembly module that Alex just talked about. But before we talk about the UI, and let's actually talk about the backend because most of you are probably gonna be from a backend or DevOps type of background.
So I wanna show you how this works in the backend first. So. I created a simple Next.js app. So Next.js is a full stack framework that is both a client side as well as a server side. And the benefit of doing that in this demo is that I can show you very easily how all of this works on both sides.
So let's say we have some kind of get API endpoint, and this is very similar to your typical Node.js Express web server, right? So you would have something like App.get in, in express, right? So in Next.js it's all very similar. anD this is just a server side. So we're gonna imagine that if you make, if I refresh here, there's going to be some request coming into the backend, right?
And you may have some API gateway in front of that. We're gonna ignore that here. So my Next.js app is right here. You can imagine that we're right here and we need to know what the user is trying to do, right? So the user is going to try to perform a particular action on a particular resource, and we need to, we need to decide if the user is allowed to do that.
So here in this Get API endpoints. There's a request coming in and to make it work with Cerbos. We only need to pass in the user information, what the user is trying to do. So which action and also the resource. So that's what we need to pass to the Cerbos instance. So what you first need to do, in order to do that, you need to of course collect the information about the user and you also need to collect the information about the resource, right?
So that's step one. So. Step one here is your typical authentication check. So you're gonna guess the user info and you can just keep using your, your step the typical identity providers, whether it's Okta, Auth Zero kind, Auth, Clerk next Auth but typically as an example that look like this, right?
So I'm using next Auth as an example here. So you would use the Auth function and it will give you the user information. So this is your typical authentication step, which Alex just talked about. This is different from authorization, right? So Cerbos is for authorization, authentication, nothing changes there, right?
So this is always step one. You're gonna check if the user is logged in and it will give you the user information. Now, I'm not actually gonna use one of these services 'cause it's a little bit too complicated for this demo. So let's just say that we get this user from our, from our identity provider. So we get this user and.
Now we know two things. We know who the user is, right? So we know who the user is, the principle as a service call, because technically it could also be services talking between each other, but we're just gonna imagine it's a real user. So we know who the user is, we know information about the user, and we also know the action, right?
So this is a gut end point. So the user trying to get something to view something. So the third part we need is the information about the resource. The second step. Is to actually get the information about the, the object, the resource that the user is trying to perform some action on. And this is typically coming from your database.
And so then the second step would actually be to retrieve it from the database. I'm using Prisma as my ORM as an example here, not actually making a, a network call here. But let's say that we get some result back here. And this is the expense resource. So let's say it's gonna look something like this, right?
So now we have the user information. We have information about the object or the, the resource that the user's trying to do something with. So now we get to step three. Now we can, we can check if the user is allowed to actually, well, what is the user trying to do to get this resource right? We know the user, we know the user information.
Is this user allowed to get this, to view this expense? So that's where that's where we arrive now, right? So this is the authorization check. So this is really where we're gonna use Surabox. So Cerbos makes it really really easy actually. So you just have one API call. This is the main API call that you're gonna make to Cerbos, right?
And I actually already filled it out, but just to give you a quick overview here, you're just gonna have you, you're just gonna need to pass three things at least. So you have your principle, this is the user, and then you pass the resource. And then you pass the action that the principal's trying to do on the resource.
These are the only three things you need to pass to Cerbos and Cerbos will return a response, right? So you pass these things to Cerbos. So we're right, right here. That's my back end Next.js app, and it's gonna send over the principal action resource to Cerbos. And we're telling Cerbos, Hey, here's all the information that you need.
Give me back an allow or deny decision. Right. So before, as Alex showed before without Serba, you would have to, you would, you would be encoding your business logic right here, right? So you would do something like, if User.roles includes manager and if the user is of a particular department or particular region, then either return or not return anything.
bUt we're not going to have that logic anymore here. We're going to put that logic in a policy file, right? So that policy file will then be loaded up by the Cerbos instance. The Cerbos instance will just give us an allow or deny decision based on a policy file, right? So the only thing in the app codes then that we have to do is to just make that call to Cerbos, right?
So we just say, Cerbos, check resources. Here's all the information you. Needs and Cerbos will give us that decision, allow or deny. We can just say, if the decision is not allowed, so the user is not allowed to fuel the expense, we can return a 4 0 3 error to the client. If the user is allowed, then we get here, we can just return the expense, right?
So this is a very basic example of how you would protect your API endpoints with Cerbos. Now, in order for Cerbos to make this to, to actually make this work. wE need to have a policy decision point, right? So what you see here, this is so, so-called PDP policy Decision points. So we, we encode the actual logic, the business logic in a policy file, and that's what we give to this policy decision point, which will actually enforce the policy.
Right. So in order for Cerbos to make this decision properly, it needs to it needs to know the policy, right? It needs to know in what cases we wanna allow this. So this is where the policy file come, comes in and, excuse me, so. Typically what you're gonna have in your codebase is you're gonna have a Cerbos folder, and in there you have policies.
In, in our case, we only have one object here, we only have one resource that we wanted to find rules for. So this is where you're gonna put all your business logic. Right. So here is where you have essentially a way of wiring it up. The actual business logic. Like for example, a manager can only approve expenses if it's below a thousand dollars, right?
That is business logic that has to do with actual business requirements. You're going to pull that out of your apps, out of your services. You're not gonna have any of that spread around anymore. You're going to put all of that business logic in a policy file. Right, and the policy file looks like this.
So here I have a simple expense, a YAML file, and the logic here, the, the syntax here is very easy to pick up. Now we could write the policy in here, but Cerbos Hub has a very nice playground actually. And it will also automatically give you. A warning if you make a mistake. So if you go to Serbus Hub, they will actually show you that they have playground.
And I have to say, they have some really wonderful high quality examples here. So, lemme make this a little bit bigger. Yeah. So here they show you get started with an example. So let me just pick one of them. Let's actually take the e-Commerce Inventory management. So I'm gonna quickly show you how this would look like.
We don't have enough time to completely check this out here, but what you'll see in these playgrounds is well these resource, these resource policy files. Let's see if I can make it a little bit bigger. Yeah. So they have some wonderful examples here. It'll cover most likely to a very large degree, your own use cases as well.
They have some really the first set of examples. And you can also see, by the way, that it can get very granular here, right? So traditionally with simple roles and permissions, you run into issues as soon as you wanna get a little bit granular, but you can see as soon. As soon as we wanna get granular here in this YAML file, you can see that this is this is not difficult to do at all.
Right? So this, this logic here is very readable. It's human readable. And one of the benefits of that is that anybody in on the project can change this, right? So before, if you had to business logic in a Node.js microservice, for example, and also in a Golang microservice, you will have an issue when you wanna change that.
Because if I'm a JavaScript developer. I'm just a humble JavaScript developer. I don't know anything about Golang. I don't want to touch any Golang code. I'm not comfortable making important code changes in Golang, so I don't wanna do that, but I am comfortable changing it here. Right. So you have one universal language essentially to define all of that business logic.
And also if you have a product manager, you may, maybe you have some non-programmers. They may also wanna change the authorization logic, right? So if you, if you use this, it's gonna be easy for everybody to update that, right? So this is where you would code your, your, your policies, it's also collaborative, right?
So multiple people can log in and you can work on the same file here, and that's how you would do it in practice. Now, I already did this before so I already copied this over into my IDE here and I have my Expense.yaml file right here. So let's actually take a look at how I define the rules here. Lemme actually drink some water here.
So. We were looking at the API endpoint for getting an expanse. So just viewing essentially. So we are saying here that a basic user is allowed to view and also edit under one condition, right? So you can have these conditions in these YAML files. Here we can see if the resource is created by the user itself.
Right? So typically this is called the owner of the resource. Usually when you create a resource, you are also the owner of it, and typically you wanna allow few added it. Maybe also delete if you are the owner, right? So here what serverless will do is it will take the principal information, uh, the resource information, and it sees that we are trying to check for the view action.
And so it's gonna check for well this condition and it'll return a response. So to make it actually work, I'm gonna console, log and see if we can actually get a decision here. So I'm gonna log here. So we're gonna say console, log that decision. And let's see. So here, I'm gonna log this to my terminal.
So I need to hit this API endpoint and it, we'll run that logic, right? So I have a simple example user here. We saw that before, that the user has an id. They have, there's an expense and we can see the created by is the same ID as the user. So it should pass this rule that we have set up here. Right. So let's see what the decision will be that Cervos will give from us, and then we can also see how the entire flow works together.
Okay? So Cervos locks you out sometimes. That's okay. Let me make this a little bit smaller.
Yeah, so we need to, we're passing the principle action and resource to Cerbos. This is a Cerbos policy decision point, right? So this is like a microservice, essentially our, our rules are in a policy file. So how do we get this on that? Policy, decision point. Well, this is actually very easy. So you need to connect your Git repository to Cerbos.
Hub. Super easy to do. They have the workspace. It's a very standard straightforward once you connected that workspace. Right? So I'm gonna, I'm gonna push my. Repository to GitHub. I've connected that to Cerbos Hub. And what Cerbos Hub will do is it can see that you pushed a new policy file to your repository.
It'll pull, it'll pull that policy file and it'll, it'll distribute that to all your policy decision points, right? So right now what I'm gonna do is I'm gonna start a policy decision point. Actually, I already started this, but let me shut it down and show you how I spin one up. It's just one command here.
And I'll also show you the, I'll also publish the Git repository after the demo so you can look at it by yourself. But there is one command here. So there's the Docker command. So I'm just gonna paste this right here, and this will spin up that policy decision points. You can see it downloads the latest bundle.
That bundle opened. That bundle is coming from. So this policy decision point that I just spun out is on my own local computer, of course, but this would be, let's say a microservice, right? It's gonna get the policy file from Cerbos Hub, which in turn gets it from your Git repository, right? So hopefully you can follow along there.
And you can also see in the dashboard all the decision points that are connected to that. And so you can see here, actually there's an active session here for the surface here, right? So you can see, thirty-one seconds ago I spun up that instance. It's properly connected now, and we saw in the logs here that it opened the bundle, so it has access to the latest policy file now.
So let's actually see what happens now when we log that decision, right? So everything is connected now. Everything is set up. And if you wanna see the complete setup, I'll also release a complete tutorial step by step where we actually start from scratch. So if you wanna see that, check out the huge channel.
But now I wanna log this decision, right? So now we're gonna hit the API endpoint. I'm gonna refresh, which will hit that API endpoint. And you can see we get through here. I'm not sure why it's double logging there. Oh. It's probably because I'm using user effect in React on the front end. Which ones twice.
So this is working now, right? So now you can see the entire flow. The only thing we have to do, there's no business logic here. We don't have to we, we, if we wanna change something, we know where to change it. It's not in the app codes, not in the service code anymore. It's all in that policy file.
Okay, so this is an example of a get API endpoint. Of course we also maybe want, wanna, wanna edit this, right? So this, this would look similar. You first do the authentication check, you get the user information, you can use your existing identity providers. You don't have to change the thing there. You get the user information, you get the resource information typically from your database.
And then you do the authorization check, right? So this is how it now works on the backend, right? So this is how it all works on the backend. Now you spin up a Cerbos instance, policy decision point, it will load your policy file, and this is where you have all the business logic. This is where you define all the business logic and Cerbos Hub will make sure it's distributed to all of these decision points that you may have.
Right now, we only have one, but you can imagine it's, it's stateless. So you can scale this up. Or down as much as you want, and it's gonna distribute that whenever you make a change. So if you make a change maybe I can even show you that if I make a change here. So we'll talk a little bit more about this later, but for example, we also have a manager here, right?
So manager can view and approve all expenses, but only in their own departments. So you can have that sort of logic as well. Now here for example, we have a manager can only approve expenses up to a thousand dollars. So we may wanna change this, right? So this is a typical example of a business rule that may change over time.
Maybe we decide, you know, what managers they can improve all expenses up to $5,000 now, right? So that's a business requirement change. Previously if you wanted to do that, I had to hunt down all the instances where I was using that logic in my services, in my apps, maybe even on the front end. And I would have to update that, right?
And then, and that's actually very difficult to do because you, it's very easy to get out of sync. It actually can become a security issue. But now I have one source of truth. All the business logic is in this one policy file. I know where to look, I know where to update it. I only have to change it in one place here, right?
So now I'm gonna stay there. I wanna show you what happens when I update this. So, because that's ultimately the, the tricky part, right? So you can define things one time, but what happens when you actually update it? So, very quickly, I'm gonna push to GitHub Cerbos hub is connected to my Git repository.
Very easy to set up. It'll pull the latest policy file and it'll, it will, it will give that to all the policy decision points. So I should see here in my policy decision points that that is downloading a new policy file. So let me push to GitHub. I'm gonna say Git, add, change, some other things. Let's say test, right?
I'm gonna push to GitHub and let's see if CertBuzz Hub actually gives me the new policy file. Let's see. It should pop up here. Or maybe I made a mistake. No, actually bundle opens, right? So here we can see Cerbos Hub. Saw that I pushed to GitHub, got the latest policy file, and is now distributed to all the policy decision points.
All my, all my, my entire app portfolio now is up to date, all synchronized, and I don't really have to do anything and it'll even run it through a CI c CD pipeline for me. So if, if I have any tests in there, the test fail, it'll make sure that that's not going to distribute it. Right. So very safe and very convenient.
Alright, so that's all on the back end now. One really enough thing with serverless help is that we can do the exact same on the client as well. I think that's really cool and I wanna share that as well. So here if I go back here, so here we have an example of an expanse. And here we have some, some issue, right?
So only UI, you often also have to deal with these permissions because especially in these work type of apps, you wanna render buttons depending on their permissions. That's very common. So if the user is, for example, a basic user. They should be able to edit it, right? So that's what we define there. If they, if they are a basic user, they can view and edit.
So it makes sense that we then also render an edit button, right? And that's what we have Now, what we also want. Is that managers, so people that have users that have the manager role they can approve. They can approve expenses, right? So if it's, if I'm logged in as a manager, I'm not, we should also have a, an approve button.
Right now we don't have that, right? Let me actually refresh here. So right now we don't have that. So let's actually fix that and see what's going on here. So on the back end to use Cerbos, let me also show you how to to connect to that. So you can see that my app is connecting to Cerbos with gRPC that's a little bit more efficient than plain HTTP, but works very similarly.
And on the client, I can download that WebAssembly module. Right. So Alex talks about that assembly module, and you can get that from the dashboard here as well. So here you can see the surface. This is for your backend, but then also embedded. So here is a URL for the bundle. I can download this in the browser and I can run all of the, the same checks on the clients, which is one URL.
Even if you change the policy file, you don't have to change the URL. So here in the browser I can just download that and your client essentially becomes also a policy decision point, right? So, um, we, we will have it on the back end, but the policy, decision point can then also become the, the client can also become one, but the web assembly.
So that's a really powerful thing. So this is how you would fetch that on the clients. Okay. So let's take a look on the page and see if we can show an approve button. If the user is a manager, let's say. So let's go to the. So this is a client side. This is the client side part of the Next.js app.
You can see I'm using used client here at the top. It's Next.js. Typically, you don't wanna make your whole page client components, but this is just for demo purposes. You can imagine that this is also a React Feed app, right? React feed is all client side. So this would be similar to that and you would, you would instantiate sermons, right?
So you can also do it in file. And the logic will be the exact same, right? So first you have your standard authentication check, so you get the user information. Typically, these identity providers, they have some kind of hook, right? So with Next auth you have to use session hook. But they all, they all have their hook and they'll give you the user information.
Second step, right? Same as before, we're gonna get the expense info, right? This is just getting the, the resource information. We're gonna fetch that from the server and the use effect here. We can, we can refactor this into a custom hook. veRy straightforward. And then the third step is your authorization check.
So this is important because we want to change the UI depending on the permissions that the user has. If the user has editing permissions, we wanna render editing button. If they have a an approved permission, we wanna render an approve button. Okay? So if we look in here, we can see what we're doing here is we're making the exact same API call.
So we use await Cerbos check resource. We pass the principle right on user information. We pass the resource and the action that we wanna do. Okay. You can see it's the exact same as on the backend. And well, let's actually you see, so set can edit. Is allowed to edit. Is allowed to approve. That's what we put in states.
Right. So that's what we, what we put in states and based on what we put in states we can render an edit button or an approve button, right? So let me actually see and see if I can render that approve button here on the client as well. So we have some example data that I was working with here. So Lisa is an engineering manager.
The amount of the expense is a hundred. And according to our rules, if you take a look, Lisa is a manager. A manager should be able to approve up to 5K. So I would have to check why we don't see an approve button. But at least we see the editing button. So let's see. For a basic user, we should be able to uh, okay, so. The amount here is not correct, so I'm probably making a mistake here.
Okay, so I'm not getting the right data here on the page. So what we want is getting that expense of course. And for some reason it's not getting that from the server. That's okay. So here, expense here should be a hundred. And unfortunately, I, I made a small mistake here, but the point is that we can also update this on the client.
So if I go one more time back to the overall view here it's not a Cerbos issue. I just made a small mistake with the API there. But the point here is I can embed the same rules on the client as I can have on the. So now if there is a business requirement change, I can go into one file, my one policy file.
I can update this. I can push this to GitHub Cerbos. Hub is connected to that. So Cerbos Hub can pick up on that. There's a new policy file. It will run the policy file through their managed CICD pipeline. If it fails, if there are tests and it fails, it'll not distribute it. Let's say for us, if it succeeds, it'll automatically let.
All these Cerbos points now that there is a new policy available and they're gonna download the latest one. So now with Cerbos, I can synchronize all of my authorization logic with just one policy file. And yeah, I think this is really game-changing. I cannot really imagine building a modern SaaS app without au to be honest.
So next time I'm gonna build a SaaS, I'm definitely gonna use Cerbos with Cerbos Hub. So if you wanna see, by the way, a complete tutorial, we're gonna start from absolute scratch. Also setting up everything. We're gonna, I'm gonna have a tutorial on YouTube very soon, so make sure you subscribe. It's YouTube.com at Byte Grant.com at Byte Grants, and we'll, we'll walk through the entire example step-by-step, also setting up Docker and things like that.
So if you wanna see how and how that works and make it work on your own computer, make sure you subscribe. You'll see the video pop up in about a week or so. All right, so I talked a little bit too much I think. I'll hand it over back to Alex and he will finish the, the webinar.
Alex Olivier: Excellent. Thank you very much, Wesley.
That was great and a great overview of really how service can fit into both the backend and the front end side of things. We've got a few questions that I think we, we, we could tackle between us. First off probably one for you, Wesley, as you've done the, did the implementation could you maybe just explain why you have to fetch the expense before you do the authorization check in, in kind of a typical setup.
Wesley: Yeah. So Cerbos needs three things, right? So Cerbos needs to know who is trying to perform a particular action on which resource, right? So you need, those are the three things you need to pass at a minimum to Cerbos. That's why I'm fetching the expense first, right? Because I first need to get the expense from the database and then I'm passing that to Cerbos.
And this is what you would have to do even without Cerbos, right? So if you would have your own authorization business project, you would have, you would essentially do the same. But Cerbos just makes it much easier. Yeah.
Alex Olivier: The, the kind of, the, the reason for this is what you don't wanna have to do is kind of copy all your data around to, like your application database, your authorization system, having them as storing the data in one place is obviously better, so you don't have duplicates everywhere and you don't have to worry about.
Copying data around and those sort of things. And so fetch the latest data from the database pass into servers always means your authorization decisions are working on the latest, most up-to-date version of the information without having any overhead of like scaling and caching and those sort of things.
A few other questions coming in. Please keep asking away. Quick question around like, how do I integrate serverless using something like along with something like feature flags like LaunchDarkly for example. Great question. Sort of authorization and feature flags have kind of a crossover.
In terms of working out what a user's allowed to do, the one we kind of recommend here is you can pass along the feature flag that that user has enabled for them as attributes about that user in the request to service. And then inside of your service policy, you can make authorization decisions based upon the attributes about the user, the attributes about the resource, or which feature flags they have enabled or disabled.
So actually works quite nicely. You just pass those along. Next up, we've got a question here around. Scaling and nesting rules and like complexity like Wesley, you shared an example of a policy where you have these conditions and they're kind of deeply nested. Are there any kind of concerns or things you ran into in terms of like conflicts or like hierarchies of rules and, and that sort of thing?
Wesley: Yeah, you do. You do very quickly start to think about how to structure the policy file. So it is a little bit complex, but it's really nice that you have the playground in Cerbos Hub. So if you, if you use Cerbos Hub to author the policy files, Cerbos Hub will also show you mistakes. So if you made any mistake, it will pop up a little error message.
And you can fix it. And also you can have tests, right? So in the real world scenario, you would have a test. So if you use the playground again, you can also embed those tests in there and it'll automatically run those tests whenever you make a change. So I would definitely run, I would, I would definitely author these policy files in the, in the dashboards.
Alex Olivier: Yeah, absolutely. That's kind of our, our recommended an approach. And there's a kind of a follow-on question as well in, in the chat around sort of how defining different policies for different modules. So if you're an, you have an application that's maybe broken up into sub-applications or different sub-modules, the way we kind of recommend, as in your policy repository, so using like a GitHub repo, you can structure your files and your policy files and whatever makes sense for you.
So you can have a folder per application and sort of. But you can also have shared policies. So for example, this like owner role is a shared rule, which is always defined once, which is if the owner ID attribute is equal to the other person making the request. Then that is, that user is thus the owner of that resource.
That is a shared rule that you can then use across the multiple different modules and you can import variables, you can define variables as well, and kind of include them in different parts of your policy. So it's a very kind of scalable way of approaching things. Another question coming in around how Cerbos is the same to Caspian or Castle, all of those, those sort of tools.
So Caspian is a great library, which allows you to define authorization logic. The difference between Cerbos and these kind of more library solutions is Cerbos is a, a service, it is a, a microservice that runs in your stack or a web assembly module that you, you call from your application and it's agnostic to any particular language or framework.
So if you are using, you know, Castle, Caspian, you're tied to like Ruby or JavaScript Can-can-can. If you go down Ruby and Rails route, you know, you can write your policies, but you can only ever call it from Ruby or JavaScript or what, whatever's relevant for, or essentially is like another API that's running in your environment.
You can call it from any language only framework, any part of your architecture, front end, back end, some job queue somewhere. So it's very agnostic and far more pluggable. And really a question there about can service run in my own cloud environment? Absolutely. So the way service is architected, is it another service you'd run and deploy alongside your application in your environment?
The last thing you wanna do for authorization is to like make a request over the internet to hit some API to get an authorization decision back. Authorization by its nature is in the blocking path of every single API call. You can't return a result back to the browser until you've check the user's permissions.
So that call needs to be as fast as possible. So the way Cerbos is architected is Cerbos decision points run right alongside your application on the same server. If you're running on VMs or sidecars, if Kubernetes, for example. And the Cerbos Hub is a management control plane, but it's not involved in the actual decision-making Cerbos Hub manages your policies and pushing them out, but Cerbos Hub isn't involved in the actual authorization checks that has all been done locally.
Hence, it's super fast and you get the kind of performance character. It's fixed. You need.
Wesley: That's a good question from Leon in the, in the chat actually. Actually I was also wondering about this myself, but what if you want to change the policy file essentially during runtime? So is there like dynamic permissions or roles, and I think you guys have the admin API to update a policy.
I'm not sure if that's Yeah. Solution
Alex Olivier: for, yeah. Great, great question there. We, we get this one a lot. We build servers coming from background of building SaaS platforms. So we, we've been in your shoes. Really there's kind of two ways to look at it. Generally what you would have is you would have an application, a user would belong to a team or a project, and they might have a different role.
The actual policies don't, are, are, are enforced based on what role a user has at that moment in time or what, or attributes that user has at moment in time. So really the dynamicism in terms of. Changing user's role or changing the logic comes from the attributes that you're passing into the request time at Cerbos.
So you can imagine in your UI, you wanna have a nice UI where a user can assign roles to different members of their teams or give a tag that say or put 'em in a group. This is all dynamic data that you store in your user database. You can then pass that along with attributes in the request to Cerbos.
And then in the service policies is interrogating those roles or interrogating those attributes to come up with a decision. What that really means is the input data is dynamic, but the policy and the enforcement is actually static, which then allows you to actually write full on test suites around your authorization logic to make sure it is doing exactly what you want to do.
And that is with static and version controlled and such. And the dynamicism comes from, from the inputs. The Admin. API is, is there. So if you truly want to create brand new policies on the fly at runtime, there's the Admin API where you can send in, literally you can define a new policy file and push it into service via the Admin API, and the instance will update and start serving upon that.
But really vast majority of use cases that we've seen, you can actually model everything by these dynamic attributes and static policies. Few questions around like governance and separating encrypting YAML files and these sort of things. As, as you saw from from the demo it did, the policies are sitting in your Git repo, so that's not something Cerbos Hub holds.
That is your Git repo that is inside of your GitHub organization, you own control, et cetera. It's only the GitHub app, Cerbos Hub app that you authorize to it, that Cerbos gets access. So you only control the policy files. As part of the the CI pipeline. When you create your Cerbos Hub account, we generate a unique encryption key for you.
We give it to you. When you create your account, you then need to save it. That's your secret. We don't hold that. And then every bundle that Cerbos Hub generates and pushes out your policy for your policy instances. Policy decision points is encrypted with that key, and it's only deployed policy decision points that have the key that only your, you know, or your infrastructure.
Are able to decrypt those policy bundles and start serving decisions upon it, at no point to serve us or serve us Hub, hold a copy of your policies or anything like that. And, and what is running on side of the actual decision points is all kind of optimized and binary format encrypted, and you can't really see into it at all.
So best practices, you know, have a repo, lock it down to just the team members that need it, and then let Cerbos Hub manage the distribution of it for you.
Couple more questions. Make sure data governance is implemented, multiple files. Graphic view of map of Cerbos. So from the government's point of view, hopefully that previous answer helps you, you own and control. You are fully owning your policy files, so your existing governance procedures and, and tracking emerging control and auditing, etc.
Still apply. And, and it kind of fit into your existing, existing workflow. So doesn't, doesn't change that for you. And in terms of like understanding how the policies work, we really recommend getting, making sure you have the test coverage test coverage in place so you can really understand what's going on.
So keep firing your questions off. Just a few more things we wanna touch upon before we wrap this up. But we can hang on for the end. So just to kind of conclude. And so going back to this kind of spaghetti, if-else code that you saw at the start of was your demo and evolved it, and this is generally the generally is kind of how your logic would look before.
In the world of service, in your application code, at least everything's reduced down to that sort of single list statement. You, you send over the resource, the principle, and the action, you get that that binary allow or deny decision. And then whenever those policies change or such that logic gets updated.
But you don't ever have to touch your application code again. That's a set up once and you don't have to worry about it, which is great.
We um, one, the big advantages of extracting your authorization logic, standalone service or a standalone component of your stack is around Auditbox. With authorization, making decision is one thing, but being able to actually track what decisions were made and how and why is, is just as important. If you were to get outta the route, implementing authorization yourself in lots of different services in lots of different languages, it's kind of down to you to then also decide and design how you capture the decisions and how you capture the audit log and send it off into whatever log collections that you may have, for example.
But with the service model, because all your authorization logic is coming from a single place and all your decisions that are coming from a single place, every decision, regardless of where it's being asked from the front end, from the back end, from making some async work, EQ somewhere, every decision goes through a service instance.
That service instance then can produce an audit log in the exact same format and the exact same start, the exact same output. Dating at this time. This principle will try to do this action on this resource. It was either allowed or denied by this particular policy, and that is. That is what happened and that's been captured for you, and that will always be generated regardless of where and how you've implemented your authorization checks on application.
As the wider ecosystem. So authentication we touched upon already as being a big one. Sturbles is agnostic to any authentication provider. So you can use Nextdoor. You can use Clurg, you can use Okta, you can use, you can use Super, Tokens, whatever you're using today, your home-grown solution. It works with Cerbos because your authentication happens, you get the identity and then you pass it on to Cerbos for the authorization piece and, and it will plug into your existing stack very simply without you having to change any of your authentication mechanism.
And then from the framework side of things we have example repos and projects. And thanks to Wesley, we'll have this bulletproof, amazing MXJS one out. But we have demos of how your settles will work with your existing tools. So if you're in the JavaScript world, next Nest, Nuxt, Remix, Spelt, we've got a plethora of projects out there.
But it's not just JavaScript. You know, we have things with Python and Go PHP. We have more like data API, so like GraphQL, server integrations, these kind of things. And so settles will work. I'm pretty certain in whatever tech stack you have we have a wide range of users out there. And then finally on the deployment side of things.
In Cerbos, what we distribute is a container. So it's a docket container. You can run that anywhere be it in your existing cloud provider. You can run it on your local instance. You run it on-Prem. We even have a user, who ship physical ATM machines out in the world and they run Cerbos on those ATM machines, which is pretty wild.
Cerbos is designed to run anywhere. It has no extra external dependencies or anything like that. It's completely portable, it's completely self-standalone and, and, and can be self-hosted wherever your application runs. And then the WebAssembly piece, the Embedded policy decision point opens up the whole new world.
For example, if you're running in Vercel or Netlify or one of these type environments where you can't necessarily run a container, the Embedded policy decision point, that WebAssembly module version of Surboss fits in really nicely with that, where you can't necessarily run in the infrastructure. So we kind of got your deployment environments set up.
Cool. Any more questions coming in?
Wesley: question by Noel? Whether you should have one central policy decision point for multiple apps? Well, you would have one that would serve multiple services. Yeah.
Alex Olivier: Yeah, absolutely. It's again, kind of down to your architecture. By having this kind of centralized service every part of every app and every application can all talk to a single point.
You can have replicas of that. But if you're also in a Kubernetes-style world where you can have containers and sidecars, you can actually run one service instance per instance, or the application and use Cerbos Hub to keep all those instances coordinated. So on service instances isn't handling all your traffic.
You can spread it out over multiple instances. Great. Does it work with Microsoft Entra? Yes, it does. We will very shortly be releasing some content along with Microsoft Azure team around how you can use Cerbos with the Microsoft Identity Systems which I think has recently just been renamed from Azure, BTC to Entra.
But yes, Cerbos works with any kind of authentication provider. Cool question in the chat from Aaron around. Policies and what can they be written in? So we've shown you YAML today. You know, servers can work in YAML files also JSON definition files. You can pick the one which works best for you.
In terms of your developer experience, we've also published the schemas for those, so you can plug it into your BS code where we'll use it for editing or use the online playground so you get full antenna sends, autocomplete, those kind of things. And you can trans tra translate between the two back and forth without any issue.
gReat. Question around, like, why do we have to out the GitHub? For, for repos for Cerbos Hub. Cerbos Hub works with GitHub for getting the, the notification and the, the message that basically a new commit, a new change. GitHub gives the nice version control, etc. You're used to your existing portal request workflows.
So that's why the, the primary way of using Cerbos is going by GitHub. If you don't wanna do that, you can run your policies locally. So you can configure the policy decision point to pull from a folder. You can point it to a cloud bucket, or you put it to database, even. It's a pluggable storage backend.
You can find more about that on the website Cerbos.dev, but the storage mechanism is kind of agnostic. But Cerbos Hub works integrates nicely with GitHub via GitHub app. Cool. I think we've got everything and we have blown through our time. So I'm just gonna finally say we big thank you Wesley for joining us and building that great demo.
And as you said that your video will be out on the channel as well. Where should people go and find you online?
Wesley: So I highly recommend if you wanna build this app from scratch with me, step by step that you go to my YouTube channel, YouTube.com at ByteDraft. Make sure you subscribe and you'll see the video pop up in about a week ag or so, and we will build that project together.
Also, I'll also show you how to set up things like Docker and how to properly connect to the policy decision points. So it'll, it won't have all the details included, including making sure the front end actually works. So definitely check me out over there if you wanna see that.
Alex Olivier: Nothing like a live demo.
And from server side, you can find out more about Cerbos Hub at Cerbos.dev, we also offer free workshops. So if you wanna speak to one of our engineers here you can just book it servers.dev slash workshop, pick a time that works for you and you'll get myself or one of the team on a call and we can actually run through in anything in more detail.
We can even help you write your very first policies. You find that at Cerbos.dev and we'll send a follow up email with this recording as well as all these links and everything else. So yeah. Thank you very much. And again, Wesley, thank you very much for your time and, and joining us and thank you all for tuning in and look forward to speak to you all later.
Yep. Thank you everyone. I had a great time as well. Thank you for having me and have a nice day. Bye.
Alex Olivier: Take care. Thanks.
Book a free Policy Workshop to discuss your requirements and get your first policy written by the Cerbos team
Join thousands of developers | Features and updates | 1x per month | No spam, just goodies.