 All right. So my name is Gorky Marjan. I work for Red Hat on the developer tools for Red Hat. Before we start, with the show of hands, how many of you have ever implemented a plugin for Backstage or planning to implement one? All right. So this talk is actually for you. I'm going to try to woo you into using Permissions API. So this is the mandatory what is your Backstage slide, right? It's like, what is Backstage? It's a platform for building developer portals. And it does have a centralized software catalog. And it does provide software templates and other 18, 20 other things that you can think of. But then there is one thing that is going to jump up to you and grab you is growing ecosystem of plugins. What does that mean for you if you're a large enterprise trying to use Backstage for your development? What that means is you're going to start to depend more and more into this ecosystem. And as the ecosystem grows, this is actually a good thing for you. But then the problem becomes, how do you get the good quality plugins that satisfies your enterprise needs, especially authorization? So when we are talking about authorization, we need to talk about Permissions API on Backstage. As you can see in this call graph, which is very roughly done, this is how the authorization on Backstage and the Permissions API works. A user makes a request to a plugin. The plugin, in turn, makes a request to the Permissions API and says, hey, does this person have the permission? Does a permission check? And the Permissions API, in turn, makes a delegation to the permission policy. Permission policy, and we're going to talk about that in a few slides later, does its thing and says yes, no, or maybe. And we're going to talk about that. And the policy decision comes in. And according to the policy decision, plugin decides what to say to the user. So as you can see from this call graph that there is a lot of work that is left to the plugin. Because the plugin first needs to decide that they are going to use the Permissions API. If they don't, we don't have authorization for that plugin. Then the plugin needs to decide what to do with the decision. Because the Permissions API can say no, but then plugin can still return the result to the user. So there is a lot of responsibility that is actually given to the plugin developer, all of you, who has, I know who you are, that are given to you. So what do you need to do on your plugin? It's actually very simple. Since I'm trying to voodoo you, I'm going to hide all the ugly parts and show you all the good code here. But there is like three things you need to do. Create a permission. There is no standard permission out there. Every plugin needs to create a permission. Or you can try to reuse one of the existing six ones that has been created by the core plugins, but that doesn't really make sense. So you need to create a permission. The second thing that you need to do is to check that permission. And the third thing, because you're a good developer, you need to write tests that checks that permission is working. Before we go on how to do those steps for your plugin, let's talk about the three types of permissions that exist on Backstage. You have the basic permissions. I like to call them action-based, although Backstage documentation does not refer to them as action-based. Then you have the resource-based permissions where you're trying to make permissions available for a specific resource, like a catalog item, a policy file, or anything that you can think of, a Kubernetes cluster. And then you have the conditional permissions, which is the maybe part of the permissions where the permission framework kind of says, well, this is a conditional permission. Run a condition rule and decide whether you can do it or not. Creating a permission is actually very easy. There is a very handy function called create permission. And when you're creating a basic permission or a resource permission, or even a conditional permission, the code is, as you see, you just make a call. And if you are doing a resource permission, you just add the resource type there and that's your permission. It's ready. See, I promised it would be easy. And how do you use that permission on your plugin? Typically, you take the authorization header and then you get a reference to the permission framework and make a call to the authorize function or method on that permissions framework, permissions API, and it gives you a decision. If it's a deny, you should send a 403, saying that you're not allowed to do this. If it's an allow, you do whatever your plugin's functionality is. And if it's a conditional, well, we'll come to that. So how do we do conditional permissions? We create a permission rule. So this is taken from the, the earlier one was from a Red Hat plugin. This is taken from the standard to-do list tutorial. By the way, there is a wonderful tutorial as part of the documentation on backstage. You should read it if you are willing to use the permissions framework. This is, the code is taken from the example code. As you can see, it's actually creating a rule again. And as part of the rule, the important bit here is these two methods implementations called apply and to query. And you will see that eventually when the permission, when you're applying this permission to see if this conditional hold, condition holds or not, you will be ending up in these two functions that you have implemented. You, typically you use your conditional, conditional permissions for to figure out things like, oh, is this the ownership or certain annotations are part of the entity and so on and so forth. But since you're actually executing a bunch of code as part of the conditional, you can do anything. It's like, oh, if the person executing this sitting in Chicago, you can actually do that. But don't. There is a possibility to do it, but please don't. But typically you're basically checking, oh, if this catalog entity is owned by this team or not. Or if this entity has an annotation that says red team and so on and so forth. And then when you are using this condition, there are two things that you're doing. You can see the transform conditions call up there. There's a condition transformer API that you can use so that you get a transformation. Remember the two query method that we had earlier. And then the other change is, instead of calling the permissions authorized, we're calling permissions authorized conditional. With that, you can actually get a deny or a conditional. And if it is a conditional, you basically say transform conditions which which ends up calling the two methods that you have implemented and at the end, in this example, they are a little bit lucky because the return filter is actually something that they can send back to the user, but in other cases, you may just get something. It just depends on how your plugin is actually implementing it. So you're implementing the actual permission rule and also what you're doing with that permission rule so you have some flexibility on the implementation of the conditional permissions. And the other question may come, oh, can we actually secure the frontend with the permissions API? And yes, the answer is yes. There's two wonderful APIs that are provided. One is a React hook. So I've been told, which is the user permission. And the second one, which you're not able to see, is the require permission tag, which you can use with your application. Once the require permission tag fails, none of the button is not rendered, for instance, which is very handy to hide the UI in that case. And this is really handy if you wanna do a disabled button, for instance. Okay, so far we looked at how we can implement what the permissions are, how we can implement those permissions. We'll look at a little bit of code, but you can find a very good tutorial online as part of backstage documentation. And now we're gonna look at a little bit on the other side of things, when you are doing a plugin and you're trying to decide, do you need to worry about this permission API or not? Do you, does your plugin actually need authorization or not? Because one thing I'm gonna say, as far as I know, in the backstage code base that I looked at, there's like six plugins that actually use the permissions API. Or seven, if I'm missing. And that's not, I'm not saying that this is just because your plugin doesn't need to, it's just the way it is. And the reason for that is permissions API is not, when you get a vanilla backstage instance, permissions API is not enabled by default. And in order to enable permissions API, you actually need to enable mission to machine authentication, identity to provider authorization as well. So all of that kind of makes it a little bit hard for the plugin developers when they are setting up their development environment. So my guess, again, it's a guess with no solid data behind it is because the permissions API is not enabled by default on development environments, none of the plugin developers pay attention to it. But if you do need to pay attention to it, there are a few factors that you can look into whether your plugin actually needs it or not. One of them is user roles. If you have multiple roles accessing your plugin's data, there is a good chance that you wanna give authorization to your plugins. Another thing is another factor is sensitivity of the data. If you are giving away, I don't know, financial data in your plugin or even addresses of your developers or phone numbers of your developers, which may actually be a regulatory compliance issue as well, you may wanna use the permissions API. And then the third one, the last one is interesting because the principle of least privilege, that's when you are trying to give the least privilege to do the work, right? And this becomes a lot of a problem because a lot of the plugins actually use what we call a service account to access other systems. So when you are doing that, that means that the backstage instance that the person is using has access to everything. It has access to my data, it has access to the next person's data and so on and so forth. So if you wanna kind of limit that a little bit, make that a little bit easier for the administrators and integrators to work with your plugin, you can, for instance, create a permission rule saying that, hey, you know what, if this user is part of Kubernetes cluster X, then they can access the Kubernetes cluster X. And once you decided to do permissions, which is exactly what happened to my team at Red Hat, once you decide to do permissions, you need to decide on the granularity. Like all of a sudden you have this, zero plugins that had zero permissions so far and then you have 10. It becomes a management nightmare because you have to manage 10 permissions, you need to be able to assign them to correct teams and people and so on and so forth. So when you are deciding on the granularity of the permissions or how many permissions you are going to have, you should think about complexity and manageability. Another factor is performance. The more permissions that you have, especially with the conditional permissions, things can actually go bad. And scalability, and scalability not in the sense that, oh, you can run multiple instances of backstage or larger instances of backstage, but you have your plugin contributes 10 permissions, the next one contributes 20, the next one contributes 10, the next one, one, four permissions, 50 permissions, four plugins, 50 permissions to manage. That's not actually scalable for anyone to actually manage. So the second thing you need to think about when defining permissions is the granularity. And what are some of the best practices that we have discovered so far is, of course, user interface. Even if you're securing your backstage, it's always a backend, it's always a good idea to expose your user interface to the permissions as well. You need to separate the concerns. A good example or a basic example of this is if your permission is both giving access for read and update, that just doesn't work. And you need to separate that, separate permission for read and a separate permission for update is always a good idea. Testability is an important factor here because at the end of the day, there's a lot of emphasis that has been given to the plugin developer in regards to authorization and therefore the permissions that you put if they are testable by you and also by integrators and administrators that it would be the ideal. And talking about integrators and administrators, documentation and naming is basically what they only have to go with when they are using your plugin and the permissions for your plugin. Another factor is monitoring and auditing depending on how the integrator is doing the monitoring and auditing on the backstage instance, they may also need a little bit more help from your plugin with regards to monitoring and auditing. And lastly, there are security implications, especially with conditional permissions because there is code executed as part of the authorization process. You need to make sure that you are doing safe coding. Nobody is injecting anything in that. I hate when this happens, sorry about that. Nobody is able to inject any code as part of your authorization process. And with that, we're gonna go full cycle and now we are back to making friends with integrators and administrators. So remember we talked about permission policy, right? When someone is trying to authorize their call to a plugin, you end up with the permission policy and permission policy is what your integrator actually creates, which looks into your request and decides whether you have the rights to do that permission, do that action, do that, what that permission entitles. So as you have seen on the best practices, the naming and the documentation helps a lot there, but also you can give utility methods to policy developers, which they can use to figure out your conditional permissions and other permissions, which they can use as part of their permission policy. Another thing is the permission policy is usually about roles, groups, users. For instance, my team provides one permission policy implementation, which is very generic that does users groups and then we just map them to permissions. But for us to be able to do that successfully, we actually need to get the documentation and naming correctly from the plugins so that the administrators can make a decision whether the user team A should have access to catalog updates or not. I think I'm on time. Right on time, Gorkin. Thank you so much, that was great.