[Openstack] Restricting volume attachment using policies

Markus Hentsch markus.hentsch at cloudandheat.com
Mon Feb 20 08:20:39 UTC 2017


Hello,

I'm running a Newton setup where I'm trying to restrict the volume
attachment actions using Nova's policy file.

I want to check for both the VM ownership as well as the volume
ownership, so that users should be unable to attach volumes if they
aren't the owner of both the VM and the volume.

I came up with the following policy.json content:

    {
        "admin_or_user": "is_admin:True or user_id:%(user_id)s",

        "os_compute_api:servers:delete": "rule:admin_or_user",

        "os_compute_api:os-volumes-attachments:create":
"rule:admin_or_user",
        "os_compute_api:os-volumes-attachments:delete": "rule:admin_or_user"
    }

Unfortunately neither of my intended restrictions for volume attachment
seem to be working. This means, a user is still able to attach volumes
that they not own as well as attach volumes to VMs that aren't their VM.
In contrast, the policy restriction for "os_compute_api:servers:delete"
is working just fine: users can now only delete their own VMs, not other
belonging to the same project anymore.

I did some digging into the code and found an interesting difference:

https://github.com/openstack/nova/blob/af44ff97dcef83e3fbae02ab23b1f47d7192e298/nova/api/openstack/compute/servers.py#L757

    def _delete(self, context, req, instance_uuid):
        instance = self._get_server(context, req, instance_uuid)
        context.can(server_policies.SERVERS % 'delete',
                    target={'user_id': instance.user_id,
                            'project_id': instance.project_id})
        ...

For the VM delete action, the "user_id" is retrieved from the VM
instance and thrown into the policy check. However, the same does not
apply for the volume attachment:

https://github.com/openstack/nova/blob/af44ff97dcef83e3fbae02ab23b1f47d7192e298/nova/api/openstack/compute/volumes.py#L310

    def create(self, req, server_id, body):
        """Attach a volume to an instance."""
        context = req.environ['nova.context']
        context.can(vol_policies.BASE_POLICY_NAME)
        context.can(va_policies.POLICY_ROOT % 'create')
        ...

In this case neither the VM instance's "user_id" nor the volume's
"user_id" are retrieved and added as "target" to the policy check.

I modified the code to a log output for the context dict object. It
seems that in the case for the volume attachment the "user_id" value
defaults to the logged in user's for both policy checks, essentially
circumventing my planned restrictions because the "user_id" values will
always match.

Is this some limitation within the code or general design of the volume
attachment policies or is there some other approach that has to be taken
here?


Kind regards,

Markus Hentsch
Cloud&Heat Technologies




More information about the Openstack mailing list