Storlets/DataSecuritySpec

Requirements
Allow the ability for an account admin to set read access using storlets. That is, allow access to a container only if the GET request has an appropriate X-Run-Storlet header, thus enforcing sensitive data filtering done with that storlet.

At this point we require that the feature will work with Keystone only, and that access will be granted on a single user basis only.

Added API
POST account/container
 * X-Storlet-Container-Read: user_name
 * X-Storlet-Name: storlet_name
 * X-Auth-Token: token

where:
 * The user name, is the name of the user as appearing in the user's Keystone token.
 * The storlet_name is the name as appearing in the X-Run-Storlet header, when invoking the storlet.
 * The token is a token of a user that is authorized to change a container ACL.

Usage
GET account/container
 * X-Run-Storlet: storlet_name
 * X-Auth-Token: token

where:
 * The storlet_name is the name of the storlet to invoke
 * The token is a token of a user that is:
 * Authorized to read from the storlet container - no changes from today
 * Authorized to read from the accessed container or was given explicit access to read using the specified storlet name using the above API.

Implementation
Since we want to allow the account admin to set this without the need to do Keystone updates, we utilize the Swift referrers mechanism: The internals of the above POST request adds to the targeted container read acl a referrer entry of the form: .r:org.openstack.storlet_internal._

To prevent data leaks for users who put the concatenated referrer in their original request, the storlet_middleware blocks any request carrying a referrer that contains the internal prefix: org.openstack.storlet_internal.

Flow
The storlet middleware code will thus work as follows: 1. Make sure the incoming request (GET or HEAD) does not carry a referrer containing the internal prefix "org.openstack.storlet_internal" 2. For GET calls with X-Run-Storlet, try the existing path with no changes. 3. If the calls fails with status HTTPForbidden, we add to the request the internal referrer that is a concatenation of the authenticated user name and the storlet the user tried to execute. Once the referrer is added we retry the request.

This approach makes sure that the original user is an authenticated user with a valid token, and that the user was indeed granted access via the specified storlet.