Servoy 2019.06 Servoy Development Series – Part 3 – Security and Wrap Up!
Servoy 2019.06 Servoy Development Series – Part 3 – Security and Wrap Up!
We are on addition number 61 and part three of this week’s mini series focused on the launch of 20, 1906, which is the Q2 build. We do quarterly releases of Servoy’s platform. And today I want to do an update on the topic of security. The reason I wanted to do this update is there were some feature enhancements to the platform in this build as well as some stack hardening. So and I’m not really going to demo anything about the second topic. But one of the things you get with a platform like Servoy is continuous maintenance of the stack. That means keeping components up to date, keeping libraries up to date. As you know, security vulnerabilities emerge in older libraries. So just the mere maintenance of the stack is providing an additional security enhancement that you would have to take care of on your own if you kind of do your own frameworks. The other thing is that we are now starting to scan the platform for vulnerabilities, including types of things like cross-site scripting attacks and those types of vulnerabilities. And we’re going to keep going to keep on doing that every single build. So we’ll be enhancing the stack. And we kind of do this in background. There’s not much to show or say about it. If you look at the release notes, you can see specifically what we’ve done. More importantly, on the topic of security, we added some enhancements around permissions control. And I was thinking about how to explain this in a webinar. And I was looking at the last time we covered this topic. And it was back in Q3 of 2017 when we launched an extension to help with security. And since then, we have been pretty quiet on this topic for the webinars. So this is going to start sort of as a review, kind of soup to nuts of security in Servoy and securing applications. And so what I have planned today is a few demos. First of all, we’ll just go through basic security. I’m starting with an application which has no security applied. And I’m going to go through like the minimal steps to apply security to it and then talk a bit about how the permissions engines work, how multi-tenancy works. And then we’ll get into extending security with an extension that we offer as well. So we’ll kind of hit all the topics. We’re not going too deep into any one of them. The idea is to give you an overview. For those of you that are experienced Servoy developers, I will point out the small enhancement that is new in this version which makes managing security, I think, easier. So let’s jump into the demo. I’m going to switch over to my IDE and I’m going to launch the example solution. Just ignore that error. I was changing something at the very last minute as I always do. Okay, so this is just a basic order form with some data on it coming from an example database. And what I want to do is I haven’t applied any security at all to this. And what I’d like to do is show you step one what you could do out of the box to apply security. So I’m going to come into the developer. I’m going to click on my application or my my active solution and I’m going to check this box must authenticate. And I can see that is set to true. And the next time I launch this application, I am greeted with a Servoy branded login screen. Now I haven’t set up any users or anything like that. But now I cannot access this application without first authenticating. Going back to the IDE, I’m going to double click my security node and my solution explorer. And you can see that I have created a new user called admin. So the way you do that is you just type in here and click new user and and create that user. You can set the password and associate them with permission groups, which we’ll get to in a minute. But just straight away, I’m going to log in with the username and password. And now I can access the application. So at a bare minimum, if you want to create security on your application, you would check that box and add a user or add your users through the developer. You can also do it through the application server manager and your application will be secured and your users will be forced to authenticate. Now that is a very basic approach. The database that actually stores the security model is built into the platform. But this is really all you need if you’re building in house applications. If you’re not hosting applications for multiple companies, for example, then this can actually provide you with enough. And it’s pretty easy to set up. Now, for the next example, what I want to do is show you if you wanted to build your own custom login form. And I think most people do. there are some that probably use the Servoybranded login form because they don’t really care. Their users are all in house employees and they’re fine with that. But if you’re a software vendor, you’re shipping a branded application. Of course, you don’t want that. You want your own login screen. So what I’m going to do is I’m going to add a module that I’ve pre-created. And it’s called Example Login. I’m going to add that as a module to my example solution. Now, when you have a, excuse me, a login module. And if I show you my properties, now you’ll see that the login solution name is Example Login. When you have a login module, that it’s like a mini application will open first. And you can do anything you want inside that application, but it will never pass control to the main application until, until you call it a login API. So now it’s up to you to build your own form and write the code to call the login API. But it’s pretty easy to do. So for the first example, and I’m going to launch the client again to get this. And I’ve created a few custom login screens you can see here with the different examples we’re going to show. So the first example, I’m not even going to validate user credentials. In fact, I’m going to put in anything here. I’ll put in my name. And login. So it’s not checking against a user database. It’s not checking my password or anything. It’s just simply saying I want to log this user in. And you can see up here in the corner, it captures my name in the little welcome icon there. And the application was logged into now. The reason I’m showing you that, and I want to show you the form in the example login module. I go to login form one. And I’m most interested in what’s happening in the code. So I’m going to look at the code for this form. You can see I have a variable to capture the input there for the username. And then pretty much all you have to do to pass control from the login solution to the to the actual application is called a security API.log in. And then what you pass in is up to you in terms of username and user ID. That’s what these first two arguments are. Finally, you have to pass in an array of permissions. And that gets us into the next topic. But before I get to that, it’s just as simple as calling security.log in, and then your users authenticated to the application. You don’t have to check a password if you don’t want to. But this is sort of like the starting point, well, let’s say you brought your own database or you have an active directory or some LDAP server somewhere, or you have your software vendor with multiple sites that you deploy to and they have their own LDAP server or something like that. So your security data could be coming from somewhere else. And you want you’ve already authenticated. And now you want to log into the solution. You just what it do, whatever you do up until that line 17 there and call log in. And then and then it will pass control. But it will serve, well, never pass control to the actual application unless you call this. So let’s with that, let’s go into the next example. And I’m going to just click over here to log out. And when I bring the application up here, I’ll go to my second example, which is apply permissions. And this is a different login form and you can see I have some permissions that I’d like to apply upon logging in. So by default, I’m going to log in again. It doesn’t matter what I put for the username here. But I am going to apply these permissions when I log in and I’ve set a few up in advance. One of them is can see orders. One is basic access. The others can edit orders. So upon log again, now you can see that the fields here that I would normally have editable are visible, but they’re disabled and grayed out. So as a user, I’m allowed to, I’m allowed to view this, these elements and view this data, but I’m not allowed to, I’m not allowed to edit it. And that’s what I’ve set up in the permissions. I’m going to log out and log in again with the addition of the can or edit orders permission. And now you can see that I am able to, to click into a field and change the the data. Suppose that we had a level of restriction that was really, I’m just wrong one, this one, was really saying that, yeah, basic access, you’re not even going to get to, get to that screen and to that data. And so immediately upon logging in, I’m presenting an error message that says you don’t have access to the data and the same for the form. And you can see that it’s not even going to show the form. So Servoy, Servoy security engine will, will actually enforce the rules that you configure. And it’s not like I’m writing some code to check for that and evaluate it at runtime. It just does it for me. So let’s again look under the hood and see how that works. I’m going to my security node here in the solution explorer. And this is really the core of Servoy security engine. So if you kind of glean nothing else from this webinar, know that this is where you can set up and configure your permissions for your applications. And that’s kind of irrespective of where your security data is coming from, what kind of multi-tenancy model you have etc. If you want to enforce application permissions, you can set that up here. You don’t have to necessarily have users that are coming from the built-in Servoy security they could come from an external source. So we have these things called groups or you could think of them as permission groups. And if you want to make a group, you just kind of type in the name of the group here and click new group. I set these up this morning. And elsewhere in my application, I will reference these groups to say what permissions apply to which elements. So I’m going to go to my orders form. I’m going to double click it here in the solution explorer. And this will bring up the form in the form editor. But today what I’m mostly interested in is this tab down here, security. When I click that tab, what it shows me is the list of the permissions groups on the side. And then over on this side, it shows me a list of the elements. And actually the first element is the form itself. Now, this is where I would like to point out what was updated in 2019-06. What we found out is that some folks, good many folks that are using Servoy’s permissions engine, found it cumbersome to administer this because by default, the permissions engine or really the setup was it’s geared to default to a more permissive model. So for example, if you create a new form and you add it to your application, then by default, there’s no security on that form. You have to go in and kind of revoke stuff. You have to take a group and say, okay, well, these groups don’t have permissions to that. And what we were realizing is that some people prefer that way because they do very little in the way of security. And maybe there’s one or revoke a few important or sensitive things. However, others have a more complex security model. And what they want is nothing is enabled by default. You actually have to go and grant it. And so we created this mode called explicit mode. And you can see there’s a checkbox up here in the editor for the form. And I have enabled that. And what that says is that no rights will be given to this entity. In this case, it’s the form and the elements therein. Unless the permissions object has been granted to it or it has been granted to the permissions object. So what that means is if I were to go and add an element to this form, then by default, that’s not going to show up in my solution until I go and enable it. And I can demo that. But first, I want to go through and just show you how we had the basic access where nothing was turned on. And then we had can see orders where everything, all the elements were visible and can edit orders where all the elements were viewable and accessible. Accessible means they’re enabled. And so you can see that when I log in with the two different permissions, those were enforced automatically. It’s not like somewhere in the code. I was checking the user rights and enabling them or disabling them. The platform does that for you. And you can imagine that that’s of a great benefit, especially for large, complex applications with complicated security models. You’re going to have 500 screens. They all have different permissions. Maybe you have 50 different permission types and you’re able to assign those and combine those with different users in different ways. It gets pretty complicated. And it’s nice that that runtime, you don’t really have to do anything. You just have to log in and you can log in any way you want. But if you set what the permissions will be, then it will just work. And that’s what’s nice. So again, it’s what’s new is this explicit mode. And I can show you a bit about how that works. Suppose I go to the design of my form and I want to put a button, oops, a button on the form here. And I’m going to name my button very creatively, button one. So now that I’ve added that to the form, if I would go and I launch the application, or if I would have logged out and logged in because the application stays running, and I will do the permissions even with the can edit orders permission. When I log in, the button is not there. And this is really nice for folks again that have complicated applications where they want by default things to be secure unless they’re enabled or granted. And so the button does not show up. So if by accident a developer forgets to set up the permissions, it’s not like you inadvertently expose a certain part of your application. The same is true if I were to come into my permissions control here and create a new group or add a new user. They don’t automatically get access to that unless that group gets granted those permissions and then the users in that, you know, has logged in in that group. So if I could come back to the form here and you can see now, under can edit orders, I could make this viewable and accessible and save. And now if I log out and back in with the can edit permission, I didn’t anchor my button properly with positioning, but you can see there it is hovering right there. So again, that’s how we can sort of differentiate the permissions and the explicit mode is the new feature in 2019-06. It’s a small checkbox on the form, but I think it can save a lot of people a lot of work. Something else I want to point out here is the permissions engine is applied to the UI on the forms and the elements in the forms and also to the data model. So let’s have a look at the orders table. And what I’ll do is I’ll click the data source part of the form. So if I look at the form properties, see it’s example data dot orders and if I click this little link button, it will open the table editor for the form. Now this is where I can normally look at the database table. There’s lots of metadata and extra functions on that. But if I come over here to security, you can see again, same sort of setup, the list of permissions over on the left, and then what the settings are on the right, and you can see again, I’ve employed this explicit mode. So that means that by default any new groups that I’ve had won’t have access to the table at all, they won’t even be able to read the data unless it gets granted. And you can see that for basic access, there was no grants for CanC, I have read access, and for Can edit, I have full access. You might also notice these two tracking check boxes down here. So, Roy provides in built-in auditing out of the box with no code required. We did a whole other webinar on that subject, so I don’t want to go into that. But it is managed or configured again in permission. So you can enable auditing on a permission by permission basis. You could say that certain user groups don’t get audited while others do, and it’s also on a table-by-table basis as well. So maybe you’re only interested in auditing certain parts of a system of record and other parts are not really to be audited. So again, that’s easy to set up and configure in the designer. It doesn’t matter what your security database looks like when you log in, this will be enforced, and that’s why I got that error message. Now, the message itself was just, I had applied the on-error handler for the whole solution. Right here, and I just, I just, oops, down here, and I had just printed out what the error was. Now, that could also happen in background where the data just doesn’t show up, and nothing is reported. The user, or you can trap that error and do what you want with it. In my case, I trapped it, and I just showed it. It’s up to you. Okay, let’s take a look at one other example. We’re going to move on to the topic of multi-tenancy. So I’m going to log out. Actually, I want to log in real quick and just point something out. You’ll notice that I put a column over here on the left-hand side of my list of orders, and this is showing the tenant to whom this record belongs to. So this set up, right now, I have a multi-tenant database. So often is a case with a multi-tenant architecture that the database itself is also multi-tenant and is segmented by a tenant ID of some kind. And so what I’ve done here is done that here with the example data, and what I’d like to point out when I log back in is a way to enforce a multi-tenant database. So I’m going to go to the multi-tenant filtering log in screen. Again, I’m just going to log in with any user that I want. And here I am prompted to pick a tenant. I’m going to pick demo. And now when I log in, you see there’s only records here for the customer demo. So let’s take a look at how that was done. What I’d like to do is bring up the log in form, which is in the log in module four, I think it is three. And if we look at the code for that, there’s very little code. I added one form variable to capture the input. It defaults to the tenant named Servoy. And there was a value list applied to that so that I could choose. But really the only code to know about here is the set tenant value, and you pass in the value of the tenant. And then after that, you don’t have to write any more code. So it’s one line of code to apply the tenant filtering. However, there is some configuration that you’ll want to do to set it up. Let’s take a look again at the orders table. This time at the actual columns. You can see that I’ve added this column called tenant ID. And if I look at the details for this, there is a flag on it that sort of indicates that this is a tenant column. This is an identifier of the tenant. Now you could have more than one column on a table. And then it would just be the combination here, but I’ve just done one. And it’s like a tenant ID. The most common set up we see is that the tables that will not be shared between tenants typically have a field of a type, you know, like a tenant ID, and that the whole database gets filtered on that. In this case, I only did one table, but this could be applied to many tables. And only those tables, which have that flag will be filtered when I call that set tenant at the very start of after logging in. There’s another way that you can do that. I haven’t done this in a while, but I believe if you go to the server itself, there it is. And you right click flag tenant columns, and it’ll pop up a dialogue. And this is really useful because a lot of applications are set up where the name of the column that is the tenant indicator is the same on every table. And so if you just type that in here, it’ll go through and find all the columns that have a column name with that name, and it’ll set the flag for you. So you can do like a one click to configure your whole database. And then it will just work after that if you call that set tenant value. The other thing worth pointing out is that in servo, you get data broadcasting for free in your applications. You don’t have to write any code. And what that means is that you may have many hundreds of clients that are logged in at the same time. They’re all modifying data. And we always push broadcast real time between clients so that they’re always looking at an accurate view of what’s in the database. But we understand that if the application is really filtered on the database is really filtered on tenant, that it doesn’t make any sense to push that because they should never be looking at the same data anyway. And it also therefore it would be a waste of performance to do that. So when you call that set tenant, it will also filter the broadcasting so that you only broadcast within your own tenant. And that’s a nice performance feature as well that we added in ServoyA2. Again, when I’m calling set tenant and I’m logging in in this case, I was just kind of arbitrarily saying what the tenant is. The actual security database could be totally external. It could be coming from anywhere. So finally, what I’d like to do is show you how this could work with an extension that we offer that we’ve offered since ServoyA8.2 in 2017. And what we found is that a lot of particularly software vendors have similar requirements in their security model, meaning they have a database of tenants of users that belong to those tenants and they have fairly common set of requirements for how they apply permissions to applications. And so what we did is we created a module that created that brought with it like a standardized security database plus a complete API to allow you to manage your security and multi-tenancy data in a single consistent way. So you don’t have to create a design that yourself and it has all of the features built in, all of the validations, etc. that you would expect. This last login form is extending from something in that framework which we’re shipping. So you can see that we’ve added the SFI security module and this form is using form inheritance extends it. So when we look at this in designer, all of this stuff is bound to objects in that framework including the login code itself. The only thing I did is write the what happens on error so that it can show an error dialogue when it logs in but essentially it’s now using a database and an API and what I would like to do is switch solutions to another kind of sample solution that we ship with that module which shows you how you could configure it because at the end of the day a lot of people do this differently. Some will expose different options to their users so what can your users do in terms of creating other users and assigning permissions to them etc. and that’s all has a lot to do with specific workflows and also user experience that you want. So we created a kind of managing console for someone who’s building applications to control this and also to get an idea of how that could look. So I’m going to launch this and this was something we also demoed back in 2017 when that module was released and here you can see that it’s kind of an overview dashboard of what’s going on in my security database and this is the one that is shipped with the database that ships with that module and you can see that I have six tenants, here’s the top two tenants, my list of tenants, here’s the one I was logging in with a Servoy tenant. You can see that it’s showing activity, recent activity and these were the sessions that I had just had so something you get with this database that you don’t have is it keeps an archive of who’s logged in and you know when they logged in and how long they were logged in for and you can actually tie that back to the audit log trail and you can really do some some nice analytics if you want to find out exactly what say a user changed in a particular session or when something was changed go back and find the session it was changed in there’s some good tools there for that I can even drill into the individual sessions and say you know yeah I don’t know if we got an IP address on that one or a geo location but if I go back to one of the other tenants say this one and look at one of one of these sessions probably could geo locate yeah the IP address like that and look at all the details of the user agent string etc so some of that gets mined and stored and we’re doing more and more now with the analytics from from the sessions and we’ll be hopefully announcing some stuff later this year on that if you want to just look at how the permissions is configured we could drill into one tenant let’s go into the Servoy tenant here and view the security setup here so we have in this case one roll admin and we put one one permission granted to that roll what we could do is grant another permission and find say that you know can edit orders which it gets exposed automatically from what you did in the IDE those application permissions get exposed and you can associate them together and say okay well if you have the admin roll you get these two permissions right or all say all three but we could create a new roll and say basic roll and grant a permission just basic access okay and then of course you can associate users to that I only have one user right now this admin user but now that users associated in both of these rolls and she or he will get all of the permissions aggregated together from all the rolls that that they are in so that’s the that’s the most common way we see people setting up permissions however if you think about it now it’s like well what do I want to expose to my users this is fine for me but I’m not going to be the one creating users they’re going to be creating users so maybe you want to yourself pre configure the rolls for your tenants and what permissions they are and then you don’t expose that you just let them create users and add users to rolls or maybe we do see with some like ERP type applications where no there’s a power user that really gets to say you know this is how I want to aggregate permissions together and assign them and this user doesn’t get them and everyone else does and then well then they might build a screen that looks more like this in some way or another we’re working on a sort of a template reference implementation that has a prescribed UX that you could actually plug into your application so for those of you that don’t want a father to design your own UX or workflow for this we’re working on something so that you could you could just take what we offer and plug it in you could take this console to an administer your customers or your tenants as well if I back up a bit you could see that I can also create users here and what I hope to show is creating a new user with different permissions and then logging in through that login screen that for some reason hasn’t bug on it but I think you get the idea basically this is the extension to the security engine that we ship which this includes a database and a complete API and lots of sort of validation and rules and things that happen non-functional behind the scenes transaction control and we’re we’re extending this periodically so as we see more and more requirements we’re adding things to it one of the things we’re working on right now is a navigation sort of metadata module like this that you can link navigation to security so you can sort of set up like menus and things that are linked to security and permissions so look for that in the next quarterly release we’re hoping to have something ready for that I’m going to just do a quick overview of what we saw so the approaches that we saw were the very sort of lowest hurdle to secure an application was to click the Mustoth indicate button and to create a user in the IDE and then you can log in so that’s using the completely built-in approach a lot of people use this it’s not that it’s it’s less robust than other ways of doing it it’s just that if you already if you’re just configuring an in-house application then and all of your security data can live inside Servoy itself then it’s perfect because it’s really easy to administer and it takes really no code at all the next approach we saw was sort of the customer approach where you could bring your own security database but still reuse your permission control and reuse the the permissions engine of Servoy but you yourself are probably going to store your users authenticate your users on you know on your own terms and then from there launch into the application with permissions we saw an approach for using multi-tenancy with a single database I didn’t show this but we have also the capability to do multi-database so we typically see one or the other in a hosted application i was multi-denial application where either you share a database or you don’t but in the case that you don’t then you have a database clones of sort of a reference data model and in Servoy there’s one line of code to do that and I wanted to show it to you database manager switch server if you don’t know this one you basically give it a the reference name so in our case it would be say example data and I was going to show this but I thought why would I do that because you won’t even be able to tell the difference but and then if you create another clone of that database then it will just switch you don’t have to do anything else everything you design against one database will forward to the other connection or connection pool and so you can have you know multiple databases one for each client hosted in your data center or whatever or in the cloud and it will just do the right thing we even offer for that approach if you’re updating your data model through Servoy’s automatic update process when you do deployments we have the ability to update clones so if you add one column to one table in your reference database but you have a hundred customer databases in the cloud and you go and you launch a deployment it’ll automatically add that column to all those other databases for you if that’s what you want so that’s that’s another approach that we see finally what I was showing was the the sfy security module which is for folks who kind of want the most standard approach for security database and permissions control and they don’t want to have to build it themselves then you can just take ours it’s a predefined security schema it has lots of goodies built into it and it’s I’ll tell you a bit more about it in the few slides here it solves a problem of multi-user multi-tenant applications it provides a complete authentication workflow so that includes an API for doing the login so that you saw that one login form it literally has no code in it the only code you put in it would be custom UX stuff it will control everything from there password verification and etc you can also do token-based authentication so if you want to do things like I don’t know send an email that has a link in it to deep link into an application to verify some step and some workflow and you just kind of go in and out of that application but you want to pass a deep link with a token in it that completely authenticates that user for one one time to do one thing we have a facility to do that an API and it’s really quite simple again you saw how we we capture session data who used the application when for how long and you can do some analytics and mining on that the way the permission sets up is that you have an application you have multiple tenants tenants themselves get their own roles so and they could be copies from one tenant to another if you want it set it up for them we even have a mechanism for replicating sort of the security model from one tenant to the other so if you want to set up sort of a master tenant and say sub tenants will sort of clone from that and be updated from that you want to propagate those changes there’s an API for that as well so suppose you you say yeah well I’m going to create a new group with different with new permissions because I added some screens in my latest version then you don’t want to to tell your users that hey you want to go and and probably create security for this you might want to say oh and I created an out of the box sort of permission set up for this new module or something and all you have to do is say that it’s going to clone across all the all tenants and then it will and then they can go and customize it if they want to so we see you know we see a lot of really complex applications we’re managing this stuff becomes really difficult and that’s why we’re trying to solve this problem for you know for as many people as we can yeah well I think we know what tenants are and the users are within a single tenant so we’re not getting into situations where people say yeah well I have one user that can see across you know three companies or something like that you can still do that in Servoyquite easily with the filtering APIs that we have but we didn’t want to get into making decisions about different ways that you could model this because it gets kind of out of control and trying to guess what people are going to do bottom line is that that there will be tenant silos and within those silos you could still do different different filter schemas if you want to rolls our ways to aggregate permissions together so typically you don’t want to expose your users just to have to know about like you know fields on a form or something what you want to do is sort of aggregate those together and something called a roll and say yeah this roll you can edit orders right and then can edit orders might have you know a bunch of stuff in it about the UI and about the database etc but you want to just sort of put that in one place and expose it to them again the permissions are enforced across the user interface and across the database so you have CRUD control and tracking plus UI stuff you can also add a runtime query whether or not they have access to elements or to the database in a certain capacity and finally we track and archive all the authenticated sessions you can combine this with the audit logging which you can do on a table by table basis to really create a powerful traceability and there’s a complete API and a wiki on the project page I’m going to show you the project page and I’ll put the link up for it as well but there’s good examples in documentation there if you go to scyqy security slash wiki oh I was close I need to get rid of this stuff my browser history there we go this is where you you can get started you can look at the API documentation and there’s a complete you know object-oriented documentation there for the whole API so a lot of people are using this and it’s well supported this is an example of the way you might program it say you wanted to create your own roles programmatically it’s got a nice JavaScript sort of chaining style as well so you can you can chain calls together but it’s really quite intuitive going backwards sorry I think that’s it that’s all we want to show I encourage you guys to we’ll post the example solutions here I’ll fix that one login form as well but there’s already a sample solution for the S3I security on the on the project page I’ll leave up the the links here for you guys to stare at well we take some more questions all right yeah the so the first so the first question is answered if one Carlos is asking about where to get the example solutions and modules S3I security is just part of the standard modules watch where you can just get it in the package manager am I right yeah let me show you that because there’s two things you can do one if you’re creating a new solution you can see that security is something you can just check and it will download and import that that module for you the other thing you can do is launch the web application manager here download install with Servoy package manager it will open this up in your IDE you select Servoy solutions and S3I security the module is there there’s also the console that I was showing you which is kind of like a reference controller solution so you can install either of those it will just import it right into your workspace and you can start using it there is an example solution to that’s that’s also on the on the project homepage as well that you can install so then there’s a question from Luis regarding broadcasting and clients running the same solution that are connected to different database servers using switch server does sort of a broadcast defense only to the other clients connected to the same database if it’s if it’s different databases then then there would be no broadcasting to to like you wouldn’t receive the broadcast event even if you’re running off a clone or something because it is it is already really separate the example I was talking about is when you have a multi-tenant database where where by default it would broadcast every change so if I were to edit an order on the one example I had and then I was logged in as another tenant not even looking at that order it would it would still broadcast it into the tenant and then you know I wouldn’t use the broadcast because there would be nothing to update because that record wasn’t cached but the point is there’s some overhead and in in getting the broadcast so we filter it now within the tenant if you’re in a different database then it won’t even try to try to do it all right last question is we’re going pretty much in overtime now from able what what will be the best approach to manage user permissions and record entitlement for example some users can only see records related to a particular area the allowed records can be defined in a query right okay so that goes back to the other point I was making where we filter really the database on tenant as the most simple and sort of strict silo however we understand that there are other models with how you want to filter data and serve voice since the earliest version has supported being able to filter even an entire database based on some criteria so if you if you were to filter a table say on what a user has access to and it’s not just like a strict tenant ID and that was coming from a query we actually added support for that fairly recently a couple versions ago if you go to the database manager node you’ll see some methods here called add table filter per amp and those have been in there since the beginning of server way in fact that’s how we started off being able to do multi-tenant databases because we can in filter an entire database say on a tenant ID but what we added support for was a query builder object so now you could actually pass in the the query builder object and it could be some complex derivation of how you get those you know access to those records and maybe it’s an in you know clause or something like that whatever you could do in SQL you could do here and put it as the filter and then you can forget about it because no matter where you go in your application that filter will apply it will apply to of course forms and found sets but also valueless and relations and and calling queries with the query builder itself and you know everywhere unless you do raw SQL which is a plugin to go around everything in surf way then then you will be able to trust that filter