[Openstack] Policy enforcement in Glance (Ocata Release)

Markus Hentsch markus.hentsch at cloudandheat.com
Thu Jun 8 14:04:49 UTC 2017


Dear Brian,

thanks for your answer to my previous question!

I've tried changing the definition of "admin_role" in the configuration
of the Glance API component but it did not change the behavior in the
way I was expecting it.

This role is evaluated and sets the "self.is_admin" property, see:

    https://github.com/openstack/glance/blob/0a2074ecef67beb7a3b3531534c9d97b1c3ea828/glance/api/middleware/context.py#L195

However before that check, the policy check possibly alters the same
"self.is_admin" property in the RequestContext constructor, see:

    https://github.com/openstack/glance/blob/0a2074ecef67beb7a3b3531534c9d97b1c3ea828/glance/context.py#L36

The "check_is_admin()" in turn evaluates the policy rule for
"context_is_admin".

If I interpret this correctly, the value of the "self.is_admin" property
determines who is what you describe as the "glance admin". However, due
to the code cited above, the assignment of who is the "glance admin"
seems to be influenced by /both/ the "admin_role" config entry /as well
as/ the "context_is_admin" policy rule.

This leads to the problem that is affecting my setup. Every project
member that has the "admin" role within their project, seems to be
automatically treated as a glance admin (self.is_admin). This explains
why admins from specific projects can still see _private_ images of
other projects they are not even a member of, just because their role
happens to be called "admin". In my case this is a serious security
issue and I'd like to prevent this.
I want to prevent users from seeing or accessing private images of
projects they are not assigned to!

Normally, I would solve this by changing

    "context_is_admin":  "role:admin"

to

    "context_is_admin":  "is_admin:True"


which actually does restrict the set of images that is returned from the
"image list" call for every user to the desired project context. However
the "is_admin:True" bit which is intended to identify the global admin
only, does not work. Even the global (project-independent) admin is not
able to see all images anymore. The "is_admin:True" usually did the
trick in other components though.

Is there currently no way in Glance to make private images actually
private (i.e. only members of the same project can see/access them)
while retaining access to them for the global admin?



Kind regards,

Markus Hentsch
Cloud&Heat Technologies

> Hi Markus,
>
> Quick comment before some details: this is a complicated issue, and
> we're working on some Glance docs that will give a coherent statement.
> The working draft is here if you want to keep an eye on it:
> https://etherpad.openstack.org/p/glance-authN-authZ-model
>
> On Tue, May 30, 2017 at 9:44 AM, Markus Hentsch
> <markus.hentsch at cloudandheat.com> wrote:
>> Hello,
>>
>> I've run into an issue regarding policies with Glance on the Ocata release.
>> Essentially, I'd like to restrict the actions of listing images and
>> viewing/editing their details to either members of the same project or the
>> global admin.
> What images are included in the glance image-list call, and what
> images a user can do an image-show on, is determined in code.  Roughly
> (because this is affected by the owner_is_tenant setting, which is
> True by default), each user can "see":
> - all public images
> - all community images
> - all images owned by the user's tenant (project)
> - all images the user is a member of
> (whether these images appear in a user's image-list response depend on
> some other factors that are outlined in the glance api-ref)
>
> A glance admin can "see" all images.
>
> As far as setting policies, the "get_images" and "get_image" policies,
> for example, apply to the API call itself.  You can use the policies
> to control what users can make the call, but you can't use the
> policies to determine what will be included in the response to someone
> who's allowed to make the call.
>
> So if I understand what you what to accomplish correctly, it's already
> done by the default policy settings, there is no need to change them
> for your use case.
>
> As far as the other weirdnesses you noticed ... we'll try to come up
> with a coherent explanation to publish with the glance documentation.
>
>> Since all policies are empty strings by default, I tried the
>> following edit:
>>
>> {
>>     "context_is_admin":  "role:admin",
>>     "default": "role:admin",
>>     "admin_or_owner":  "is_admin:True or project_id:%(project_id)s",
>>
>>     "add_image": "",
>>     "delete_image": "",
>>     "get_image": "admin_or_owner",
>>     "get_images": "admin_or_owner",
>>     "modify_image": "admin_or_owner",
>>     "publicize_image": "role:admin",
>>     "communitize_image": "",
>>     ...
>>
>> The result was that nobody (including the global admin!) could list images
>> anymore. An "openstack image list" command would always result in a "403
>> Forbidden" error.
>> Also, retrieving a single image's info via a user from the same project was
>> also impossible. An "openstack image show <image_id>" would simply output
>> "403 Forbidden You are not authorized to compelte get_images action".
>>
>> From the policies as quoted above I would have expected the global admin as
>> well as any project member being able to list and show images without
>> problems.
>>
>> Editing 2 lines in above policy definition:
>>
>>     ...
>>     "get_images": "",
>>     "modify_image": "",
>>     ...
>>
>> resulted in another weird behavior. With those adjustments, an "openstack
>> image list" or "openstack image show <image_id>" on the command line
>> executed as the global admin succeeded. On the dashboard (Horizon) on the
>> other hand, only listing them was possible. Trying to display their details
>> resulted in an error.
>>
>>
>>
>> Digging through the logs and code, I stumbled on an image target object that
>> is inspected for the policy enforcement, see here:
>> https://github.com/openstack/glance/blob/57c4d7d78f37e840660719b944ebabe91cbf231b/glance/api/policy.py#L109
>>
>> Hacking the code to put some more debugging output into the logs, I peeked
>> into this "ImageTarget(image)" object, which also contains a
>> ".target.context" attribute wrapped into it. Although this "context"
>> attribute does contain seemingly relevant user data, its contents do
>> actually differ depending on the logged in user.
>>
>> My interpretation was that the context of the image target should be static
>> (representing the owner/project it actually belongs to) and that this is in
>> turn matched against the dynamic "self.context" dict (representing currently
>> logged in user) according to the policies defined, something along the lines
>> of:
>>
>> self.context (e.g. project_id)   ---[policy check against]--->
>> ImageTarget(image) (e.g. project_id)
>>
>> However "ImageTarget(image)" seems to contain context that is not actually
>> related to the image but differs per logged in user.
>>
>>
>> Did I misinterpret the policy definitions and/or the code related to it?
>> How are policies like these actually supposed to be defined in Glance?
>>
>>
>>
>> Kind regards,
>>
>> Markus Hentsch
>> Cloud&Heat Technologies
>>
>> _______________________________________________
>> Mailing list: http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack
>> Post to     : openstack at lists.openstack.org
>> Unsubscribe : http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack
>>
>>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.openstack.org/pipermail/openstack/attachments/20170608/3026b9f1/attachment.html>


More information about the Openstack mailing list