So, guys, now Mark, we'd present his topic about fine access, fine grain access control.
Hi everyone, hello.
My name is Mark, I'm a software engineer in the Lexsty team at Peronical.
Today I'm going to talk about access management in Lexsty and in microcard as well.
But before we get started, I'll just tell you a little bit about what Lexsty is.
So, Lexsty is a hypervisor for containers and virtual machines.
You can run it, it's quite easily just snap install Lexsty and then you can run your virtual machines.
But it can also be clustered, you can use it for a home lab, for example.
Or you can also deploy it as a very large data center on a server rack.
And microcard is essentially a packaging of Lexsty with some other associated tooling.
So, you can use oven or micro oven for software-defined networks and set for software-defined storage.
And together, that comes together as a kind of multi-tented environment where you can have access control to manage different projects, different instances and so on.
This is where we go through this talk, just trying to keep in mind this image.
So, if you imagine Lexsty as sets of Raspberry Pi, so a small Raspberry Pi cluster, there's not really a lot of space to deploy in the extra services.
So, you know, if you have micro oven, you have Lexsty, micro set, and you're putting your virtual machines on top of that.
You don't really want to have a lot of bandwidth taken up by additional services.
Now, we did have an existing method of authorization for users in next day.
So, open-till before this open-fge work was implemented, authentication of the Lexsty was only with mutual CLS.
And what we were doing was associating each user's certificate, their public certificate, with a particular project in next day.
And as long as they were associated with that project, they could do anything inside that project, except for editing the project configuration itself.
But it calls for that to improve the authorization process and improve the management and make this much more fine-grained.
And so, to make this work, we look to open-fge. Open-fge is provides a framework in a set of modeling concepts, which makes it much more easy to reason about access control.
And so, open-fge is a relationship based access control.
And so, generally, you will model the relationships between different entities in your system in order to make a decision about,
and, you know, this user X is user X able to perform action Y on resource, said.
And so, with open-fge, we can ask the question, does user X have relation can exec with instance C1?
So, in this case, we're asking the question, is someone able to get a shell, for example, inside that instance?
And with open-fge is modeling language, you can have a direct association or a direct relation between the user, the instance, and the relation can exec.
So, in open-fge is modeling system, it kind of looks a bit like this.
They see, you have type identity, that's the user. You have type instance, and you have a set of relations, and then in the square brackets here, you have the identity.
So, an identity can be directly related.
That's good to an extent, but it's also going to be a bit of a headache to manage.
For example, if you want to have some users where you want to give them access to all instances in a project, then you want to have some level of computer relations,
and open-fge provides that as well. It's very nice. So, what you can do is define a relation between a project and an instance,
and then you can inherit these relations down the chain. So, you can say, I have a project, that's related.
I'm an instance, sorry, that's related to the project that sits for them, and then I might have can exec because I have can operate instances on the related project and so on.
An open-fge server will compute all the different paths from which you're able to get these different relations.
And that's great, but it's very complex.
So, in order to be able to compute these different relations, you have to tell open-fge how these different entities in your system are related to each other.
So, for example, you might say there's a project and that's has relation project to instance C1, and this is how open-fge is able to actually do these computer relations.
But the problem that we had was that actually synchronizing all these relationships with the external open-fge server can actually get quite complicated,
various situations where you might, for example, you go to create a network, you tell open-fge and create a network, or creating that network fails,
and then you miss removing that talk or back from the open-fge database, and you can leave things hanging around.
So, if essentially you've got an external cache of all the resources in your system, and that can get quite tricky to keep in the sink.
Another thing was that open-fge requires a HHA Postgres to be, you know, for redundancy, and that's not something that we can really,
feasibly deploy in our system of three or as repised.
So, we need something that we can use in kind of airgaped environments or on a small system that would work for us, and we ended up using open-fge in quite an unconventional way.
Open-fge itself is written in GoLand, and so is LexD, and so we were able to instantiate an open-fge server within LexD,
and implement our own version of their Open-fge database store interface.
And then data store interface is essentially just an interface that says, when I call this method,
this is what these are the kinds of things that I want to return from the database.
And so, ours just reads directly from decolite, decolite is our backing database for LexD.
It's just SQLite, but distributed using the RAPD algorithm.
So, just a couple of things about this Open-fge data store interface.
There are two kind of primary methods that needed to be implemented.
They really are called in different scenarios, or different methods that are called against the RAPD Open-fge server.
One of them is called uncheck requests, where I'm checking does this identity specifically have this relation to this object.
We have a method called Re-Use Set Supples, which basically says list all the Supples, where the user is a given type.
And, yeah, related to a given object with a given relation.
And, yeah, the next one, read starting from user, list all the Supples that are related to a given user.
So, given a group, for example, what permissions does that group have.
And so, to implement this, we had to add a couple of tables to LexD.
One of them being the identity stable.
So, every authenticated user in like Steve will go into the identity stable.
For each identity, we have a list of groups.
And for each group, we have a list of permissions.
And, yeah, demo sign.
So, I should have put my screen on duplicate, rather than present.
Okay.
Just give me one second.
That's right.
Okay.
So, this is the LexD's user interface.
Now, here, I'm able to view projects.
I can create projects, for example.
I can see whatever I like.
And the reason for that is my identity here, me, is a certificate.
And the groups that I'm a member of here, this one group and the group is admins.
So, I go into groups.
You can see that.
In permissions, I have this server admin permission.
So, I've just given myself full access to, actually, over the HTTPS API,
but as if I was connecting over the unique socket.
What I can do is now log in as.
And now I just see user, so I'll just open a guest profile here.
And we'll cancel that.
And so, if I log in with SSO,
let's give us.
So, the first thing we can see, it just says project not found.
And that's because when you first log in as an IDC user,
you don't have any permissions in the system at all,
because you're not related to any groups, so you're not a member of any groups.
So, if we go back to our window where we're an administrator,
and now going to identities, we can see that the IDC user is now present,
so they've been saved in the database as a result of their login.
And they're not a member of any groups.
So, what I'll do is I'll create a group.
I'm going to call it my group.
I'm going to add my IDC identity to that group.
And then I'll give it some permissions.
So, the permissions I'm going to add to it are.
So, I'm going to view on project default, so they'll be able to see the default project,
but they won't be able to actually view any of the results that they're inside it.
This is a very fine-grained entitlement, but it just means you can view the project and that's it.
And then the next thing I'm going to do is,
if the user role on instance normal.
So, the user role is a built-in role that we created,
and we've become and built-in roles because they're essentially defined by our OpenFGA model.
Save.
Okay, so the IDC user that's in the other window,
is now a member of the group, my group, with those permissions.
So, now should be able to see instance normal, great stuff.
And then, if we go to configuration, name is normal, the description, let's try and edit the description.
And I'm unable to update it as expected.
However, I am able to get a thermal session.
And so, that's the gist of how it works.
Let's go back to our slides.
So, just to recap why we did this.
It was really the absolute requirement that we were able to deploy LXD on a set of Raspberry Pi's.
I wouldn't necessarily recommend that you do this if you have a cloud deployment.
You can use any variables of this to deploy Postgres.
Find just use OpenFGA as necessary.
But the pros are, where's out the box?
No Postgres deployment necessary.
Another great thing is, we don't really have to worry at all about synchronizing all the two pools for the system.
And also, easier model migrations.
So, model migrations in OpenFGA can get quite complicated.
Generally, you will have to create a new store with a new model.
And then you would, my great deal of it.
There's it over.
Or in the same store, you can add a new model.
And you'd have to have a kind of intermediary model,
while you migrate all these changes.
But in our case, all we need to do is, essentially, just use the existing system of database migrations that we already have.
Or patches.
The cons are complexity, implementing the OpenFGA data store, and all the various different SQL queries.
In order to query the deeper like that, this was quite complex.
Additionally, you know, storing user information.
Like, in order to be able to manage users in this way, we do have to store the email address,
which is an additional place for, for example,
GDR, GDR compliance for where to delete it.
Yes, the OpenFGA data store in the first tends to get updated fairly regularly by the OpenFGA address.
And that's nothing on them.
They didn't intend for this to be used as a public API.
Although they did expose it.
And they're cool with it.
We've had a meeting with them.
Their communities is really lovely.
And then also, just generally, this is much slower than the existing authorization mechanism that we had,
because that one was fully cached.
This one does have to call out to the database.
And generally, OpenFGA is, they've optimized the database scheme or in such a way
where these calls are at terrific, like tremendously fast,
whereas we don't have the luxury of being able to do that.
And so we have a few things to do to speed this up.
It's already quite fast actually, we've done some work on caching to improve the speed.
But, yeah, thank you very much.
Thank you.
Any questions?
Nope.