Storage Volumes As Root Disks


Im working on limiting users to a project,

LXD appears to support limiting volumes to projects, but from my attempts storage volumes cant be used as root disks, whats the strategy here?

I don’t understand what you mean.

Instances are always backed by a volume in one of the storage pools.
Custom storage volumes can be created manually and attached to instances at specific paths.

So lets say, I logon as user XYZ - a non admin;

I want to create a new instance

Im assigned to any project - anything other than default (assume user restricted to a project)

First I see what storage is available to me

lxc storage list

This returns everything - which seems odd, even on with a project with restricted storage

Now I need a root disk to create instances on, which from tests can’t be a storage pool volume

So the restricted user needs access to /1.0/storage-pools/ to be able to find a root disk to create instances on? (which reveals a lot about other projects)

Yes, the list of storage pools is the same for everyone, so you’ll use /1.0/storage-pools to know what storage pool you can create instances or custom volumes on.

The volumes themselves are tied to particular projects so you won’t see other project’s volumes in /1.0/storage-pools/NAME/volumes.

But I guess what im saying is /1.0/storage-pools reveals info about other projects in the used_by so the only option is to restrict /1.0/storage-pools to admin & force admin to set a root disk in the default profile for each project

Nah, that one is just an oversight, the UsedBy just needs to be filtered to only show the projects that you are allowed to see.

Right now you get to see that record but if you tried to hit one of those URLs, it would fail with Unauthorized.

Ah okay - I assumed volumes would be base for instances something like;

Screenshot from 2020-11-28 00-53-10

The way things work is you have a shared list of storage pools (currently always available to everyone), then in your project you can create instances or images both of which automatically get volumes on the relevant pool and are marked with their project and then the user can also manually create additional custom storage volumes.

They all sit together on the same storage pool and we just have a DB column that tells us what project they belong to and some OS tricks so that the same name can be used just fine in multiple projects.

This pushes the burden of maintaining the filtering logic onto the client application which is ofc insecure, surely? or is this where RBAC comes in?

Because lets say I make my application generate a certificate per user for a server (so they let their users use lxc CLI but my app cant act as a CA authoirty and revoke peoples certs as required) - then they can just download a cert and do lxc storage info default and extract all the info they want about other peoples projects?

It’s handled by the server but currently only usable with RBAC.

With the upcoming work to allow giving effectively the equivalent of an operator role against a particular set of projects to regular TLS clients, this will apply in this case too.

So if you create a project called foo, then add a TLS key to the trust store configuring it to only have access to foo, that user will only see foo in /1.0/projects, they will only see volumes for foo in /1.0/storage-pools, … similar to what RBAC does today.

That’s an example of what I get on a cluster using RBAC where I only have access to two projects out of the dozen or so it’s got:

stgraber@castiana:~/data/code/lxc/lxd (stgraber/master)$ lxc query /1.0/projects

In this case you’ll notice I don’t even see the default project.

Im traversing the projects tree - but if /1.0/storage-pools is general access your always leaking info to the client about other projects

The list of storage pools is the same for everyone, so there is no leaking, that’s fine.
What’s not the same for everyone is the list of volumes, which is why I’m fixing the UsedBy field now :slight_smile:


Im just trying to keep up and i get a bit lost! should do the trick and can be reused elsewhere if we find it’s needed too. In theory we may need that for projects that don’t use isolated networks/profiles/images to hide some of the others, though I’m not clear on whether we’ve done the filtering there some other way already.

You are the man aren’t you :heart_eyes: