This is the specification for the blueprint https://blueprints.launchpad.net/glance/+spec/api-v2-property-protection
We're going to take a Minimal Viable Product approach here and see where that gets us.
What are "property protections"?
There are currently two types of properties in Glance:
- properties (or "core properties") ... these are the ones defined in the image schema
- additional properties ... these are arbitrary key/value pairs that can be put on an image
Under this proposal, any of the above could become "protected properties" by defining protections for them. When you put protections on a property, it limits what specific categories of users can do CRUD on that property. Properties that don't have protections defined for them will act as they do now, i.e., admin CRUD on core properties, owner CRUD on additional properties.
How do you specify property protections?
The simplest thing is to use a config file. It could look something like this:
[mypropertyname] create: <role-list> read: <role-list> update: <role-list> delete: <role-list>
where role list is based on policy.json
[mypropertyname] <role-name>: <crud-list> <role-name>: <crud-list> <role-name>: <crud-list>
Rather than simple property names, we may have to allow regex specifications in order to prevent property spoofing (see below).
How do you display properties that are protected?
They'd look exactly as they do now in the Image response except that you might not see them at all depending on your permissions, i.e., if a user doesn't have Read permission on a property, the property will not appear in that user's image detail response.
Namespacing and property protections
There will be no explicit namespacing, informal "namespacing" would continue as it does now, e.g., "system" properties would be prefaced with something like "org.openstack__1__" or "com.cloudprovider__1__". The downside is that since protections are name-based, if an image owner has an existing property name that matches a protected name, the image owner may not be able to edit his own property. On the other hand, the whole point of the javaesque informal namespacing in the first place was to prevent this kind of conflict, so we (well, me, anyway) are not concerned.
Using informal namespacing introduces the possibility of a malicious image owner hijacking the provider's "namespace" and then sharing the image to other users. For example, the image owner puts a property like "com_rackspace_approved: True" on an image to make it look like this image is safe to boot from even though Rackspace has no such image property.
This can be addressed in a few ways . The current consensus is that we can use a regex-based strategy. The basic idea is that providers concerned about this problem can force image owners to use an informal namespace for the additional properties they want to put on images. For example, if the configuration file has a "first-match-wins" policy, it could list the "protected" properties by name with appropriate CRUD restructions on them, followed by /^owner_specified_.*/ with the image owner allowed to do all CRUD on them, followed by /.*/ with all CRUD denied for the image owner. This would effectively force the image owner to use the informal namespace prefix owner_specified_ for all additional properties.
Thus, instead of adding "com_rackspace_approved: True" to an image, a malicious owner would only be able to add "owner_specified_com_rackspace_approved: True", which shouldn't fool anyone. A nice feature of this scheme is that the cloud provider can pick an arbitrary informal namespace for this purpose and educate users appropriately.
Formerly Open Questions
- How should the names of properties with protections on them be communicated to a user?
- The consensus is that this should be done independently of glance. It's up to the cloud provider to communicate this information to users via documentation or other appropriate means.
- Should the protections act like policies, i.e., could be independent for each node, or should we enforce consistency across all nodes?
- The consensus is that property protections should be consistent across all nodes. The key takeaway is that the existence of a config file on each node should not constrain the implementation of property protections, e.g., the protections could be done in the database if it turns out that that's a good implementation strategy.
- What will the config file format be?
- Will this scheme work for the nova snapshotting process? (Nova writes some properties (e.g., 'architecture') from user context.)
- Can this be handled by allowing image owner CR-- on such properties? They are enumerated in the Nova code, so we could specify them by name in the config file.